1. 프론트엔드 테스트란?
소프트웨어 테스트: 소프트웨어 개발에서 사용자 인터페이스(UI) 및 사용자 경험(UX)를 검증하는 과정- 전반적으로 소프트웨어가 기대된 대로 작동하는지 확인하고, 잠재적인 버그를 찾아내어 개선하는 프로세스
소프트웨어 테스트의 중요성:- 사용자에게 안정적이고 오류가 적은 제품을 제공
- 개발 주기 초기에 버그를 찾아내어 수정함으로써 프로젝트 비용을 절감하고 개발 속도를 향상
테스트 종류: 유닛 테스트(unit testing), 통합 테스트(integration testing), E2E(End-to-End) 테스트 등- 왜 테스트를 해야할까?
- 버그와 에러의 조기 발견, 코드 변경의 안전성, 사용자 경험 향상, 유지보수의 편의성, 자동화를 통한 효율성 증대 등
- 적절한 테스트 전략과 도구를 활용하여 안정적이고 신뢰성 있는 소프트웨어를 개발하는 것이 중요
1.1 프론트엔드 테스트의 필요성
신뢰성 확보: 테스트를 통해 코드의 예상치 못한 버그를 사전에 찾아내어 소프트웨어의 신뢰성을 높일 수 있음- e.g. 통합 테스트를 통해 컴포넌트 간의 상호 작용에서 발생할 수 있는 문제를 사전에 식별
유지보수성 향상: 변경된 코드가 기존의 기능에 영향을 미치지 않음을 확인하여 유지보수성을 향상- e.g. 유닛 테스트로 기능의 핵심 로직이 정확하게 동작하는지 검증하고, 통합 테스트로 여러 모듈 간의 호환성 을 확인할 수 있음
개발 생산성 향상: 테스트를 통해 안전하게 리팩토링을 수행하거나 새로운 기능을 추가할 수 있음버전 관리 및 협업의 용이성: 협업 시 버그의 원인을 더 쉽게 파악할 수 있도록 도와주며, 버전 간의 변경 사항을 추 적하는 데 도움사용자 경험 향상: 성능 및 E2E(End-to-End) 테스트를 통해 사용자 경험을 향상시키고, 안정적인 애플리케이션 을 제공
1.2 프론트엔드 테스트 종류
유닛 테스트(Unit Testing): 개별 컴포넌트, 함수, 또는 모듈과 같은 코드 단위를 격리하여 테스트통합 테스트(Integration Testing): 여러 컴포넌트나 모듈 간의 상호작용을 테스트하여 전체 시스템이 예상대로 통합되는지 확인하는 것e2e 테스트(End-to-End Testing): 사용자의 관점에서 애플리케이션의 전체적인 동작을 테스트하는 것Snapshot 테스트: 렌더링된 컴포넌트의 스냅샷(이전에 캡처된 렌더 결과)을 저장하고, 변경 여부를 검사성능 테스트: 애플리케이션의 성능을 측정하고, 특히 로딩 시간, 응답 시간, 자원 사용량 등을 테스트
1.2.1 Unit 테스트
1// main.js2function add(a, b) {3return a + b4}56// math.test.js7const math = require('./math')89test('adds 1 + 2 to equal 3', () => {10expect(math.add(1, 2)).toBe(3)11})
유닛 테스트: 유닛 테스트란 소프트웨어의 가장 작은 단위인 “유닛”에 대한 테스트.- 이때, 유닛은 주로 함수, 메서 드, 또는 모듈과 같은 개별적인 코드 조각을 의미
유닛 테스트 수행 도구: Jest, Mocha 등테스트 작성 방법: 라이브러리 설치 → 테스트 슈트 작성 → 테스트 케이스 작성 → 테스트 실행유닛 테스트은 언제 사용할까: 대규모 프로젝트, CI/CD, 새로운 기능 추가 및 리팩토링
유닛 테스트를 작성할 때는 아래와같은 FIRST 원칙을 따른다:
Fast: 테스트는 빠르게 실행되어야 합니다. 느린 테스트는 개발자의 피드백을 늦추고 생산성을 저하Isolated/Independent: 각 테스트는 독립적이어야 하며, 다른 테스트의 실행 결과에 영향을 받지 않아야 함Repeatable: 테스트는 어떤 환경에서도 반복 가능해야 함Self-validating: 테스트는 자체적으로 검증 가능하며, 성공 또는 실패 여부를 명확히 알려줘야 함Timely: 테스트는 적절한 시점에 작성되어야 하며, 개발 초기부터 지속적으로 유지보수되어야 함
1.2.2 Integration 테스트
1// src/components/ExampleComponent.test.tsx2import { render, screen } from '@testing-library/react'3import ExampleComponent from './ExampleComponent'45test('ExampleComponent renders properly', () => {6render(<ExampleComponent />)78// 검증9expect(screen.getByText('Hello, World')).toBeInTheDocument()10})
통합 테스트: 여러 컴포넌트가 상호 작용하는 상황에서 전체 애플리케이션이 예상대로 작동하는지 확인하는 테스트.- 주로 컴포넌트 간의 통합이 원활하게 이뤄지는지, 데이터 플로우가 제대로 동작하는지를 검증
통합 테스트 툴: React Testing Library 프론트엔드 테스트 종류 및 필요성 알아보기통합 테스트 방법: 라이브러리 설치 → 테스트 환경 설정 -> 테스트 코드 작성- 언제 통합 테스트를 사용해야할까?
- 컴포넌트 간의 통합이 중요한 프로젝트, 비즈니스 로직이 복잡한 프로젝트, 데이터 플로우가 중요한 프로젝트
1.2.3 E2E 테스트
1// cypress/integration/example_spec.ts2describe('E2E Example Test', () => {3it('Visits the app root url', () => {4cy.visit('https://your-app-url')56// 예제 : 로그인 테스트7cy.get('#username').type('your-username')8cy.get('#password').type('your-password')9cy.get('#login-button').click()1011// 검증12cy.url().should('include', '/dashboard')13cy.get('.welcom-message').should('contain', 'Hello World!')14})15})
E2E 테스트 (End-to-End Testing): 사용자 시점에서 애플리케이션의 전체적인 흐름을 시뮬레이션하여,- 애플리케이션이 예상대로 동작하는지 확인하는 테스트
E2E 테스트 툴 Cypress: 강력한 E2E 테스트 도구 중 하나로, 사용이 간편하면서도 다양한 기능 제공.- 시각적으로 풍부한 테스트 결과를 제공하여 디버깅을 용이
- 언제 E2E 테스트를 사용해야할까?
- 사용자 경험이 중요한 웹 애플리케이션, 복잡한 비즈니스 프로세스를 갖는 애플리케이션, 다양한 통합 시스템을 가진 애플리케이션
1.2.4 Snapshot 테스트
1// Component.test.js2import React from 'react'3import { render } from '@testing-library/react'4import '@testing-library/jest-dom'5import MyComponent from './Component'67test('renders correctly', () => {8const (asFragment) = render(<MyComponent />)9expect(asFragment()).toMatchSnapshot()10})
-
스냅샷 테스트: 컴포넌트 렌더링 결과물이 예상대로 유지되고 있는지 확인하기 위한 테스트 방법.- 테스트시점에서 컴포넌트의 렌더링 결과를 캡처하고, 이후 테스트에서 캡처한 결과와 비교하여 변경사항을 감지
-
스냅샷 툴 예시: Jest, React Testing Library -
언제 스냅샷 테스트를 사용해야할까?
- 컴포넌트 렌더링이 자주 변경되는 프로젝트, 디자인 시스템을 사용하는 프로젝트, 다양한 환경에서 사용되는 프로젝트
1.2.5 성능 테스트
성능 테스트: 소프트웨어 시스템이나 컴포넌트의 성능을 측정하고, 특정 부분에서 혹은 전체 시스템에서 발생할 수 있는 성능 이슈를 식별하는 프로세스- 성능 테스트는 주로 응답 시간, 처리량, 확장성, 안정성 등을 평가하여 사용자 경험을 향상시키고 소프트웨어의 안정성을 보장
성능 테스트 툴 예시: Lighthouse, 크롬 개발자 도구의 네트워크 탭성능 테스트의 장점: 성능 최적화, 사용자 경험 향상, 비용 절감- 성능 테스트가 필요한 프로젝트?
- 대규모 트래픽을 처리하는 서비스, 이미지나 동영상을 다루는 플랫폼, SPA(Single Page Application)등의
- 현대적인 웹 애플리케이션등 모든 종류의 웹 애플리케이션에 적용될 수 있음
1.3 소프트웨어 테스트 7가지 원칙
ISTQB (International Software Testing Qualifications Board)의 기본 원칙들을 반영:
- 결함 존재를 보여주는 테스팅 (Testing shows presence of defects)
- 철저한 테스팅은 불가능 (Exhaustive testing is impossible)
- 조기 테스팅 (Early testing)
- 결함 클러스터링 (Defect clustering)
- 살충제 역설 (Pesticide paradox)
- 테스팅은 맥락에 따라 다름 (Testing is context dependent)
- 결함 부재의 오류 논리 (Absence-of-errors fallacy)
2. 테스트 주도 개발(TDD)
Test Driven Development(TDD)
- 실제 코드를 작성하기 전에 테스트 코드를 먼저 작성
- 테스트 코드를 작성한 후 그 테스트 코드를 Pass 할 수 있는 실제 코드를 작성
2.1 TDD 장점
- TDD를 하면, 코드에 안정감이 부여
- 개발하는데 많은 시간이 소요되는 부분은 디버깅 부분이라서, TDD를 사용하면 디버깅 시간이 줄어들고 개발 시간도 줄어듬
- 소스 코드 하나하나를 더욱 신중하게 짤 수 있기 때문에 깨끗한 코드가 나올 확률이 높음