Test code?

ijimlnosk·2024년 11월 14일

TestCode

목록 보기
1/1

기존에 진행하던 프로젝트에 테스트 코드를 도입해보기로 하였다.
프로젝트를 진행하며 동시에(?) 진행하는게 좋을 것 같았지만
아직 1차 스코프를 진행하는 도중이기도 하고 프로젝트의 안정성을 높이기 위해 도입하게 되었다.
우선 테스트 코드가 무엇인지 살펴본 다음 jest에 대해 알아본 뒤 실제 어떻게 사용했는지 볼 예정이다.

테스트 코드란?

애플리케이션의 특정 기능을 테스트하는 코드이다.
예를 들어, 특정 함수의 테스트를 하려면, 그 함수에 대한 입력값과 기대되는 출력을 정의하고, 실제 출력과 비교하는 식으로 작성된다.
테스트 코드는 일반적으로 코드와 함께 저장되어 계속해서 수정되고 실행된다.

테스트 코드의 종류

  • 단위 테스트(Unit Test)
    개별 함수나 메서드와 같은 작은 단위를 테스트한다.
  • 통합 테스트(Intergration Test)
    여러 컴포넌트나 모듈을 조합하여 상호작용이 잘 이루어지는지 확인한다.
  • E2E 테스트(End-to-End Test)
    애플리케이션의 전체 흐름을 테스트하여 사용자가 실제로 경험할 작업이 잘 수행되는지 확인한다.
  • UI 테스트
    사용자 인터페이스의 동작을 테스트하여 화면의 요소들이 의도한 대로 동작하는지 확인한다.

테스트 코드를 작성해야하는 이유

테스트 코드를 작성해야하는 주요 이유로는 신뢰성 확보와 품질 유지하기 위해서이다.
코드가 추가되거나 수정될 때 발생할 수 있는 예기치 않은 버그를 사전에 방지하고,
자동화된 검증을 통해 개발 효율성을 높일 수 있다.
또, 유지보수를 용이하게 하여 기능 변경 시 기존 코드가 정상적으로 동작하는지 쉽게 확인이 가능하다.

테스트 코드의 장단점

테스트 코드의 장점으로는 버그를 예방하고, 리팩토링을 안정적으로 지원하며, 개발 속도를 높일 수 있고, 코드 사용 예시를 제공하여 문서 역할을 할 수 있다.
단점으로는 초기 작성 시간이 늘어나고, 기능 변경 시 테스트 코드도 함께 수정해야 하며, 모든 케이스를 완벽하게 커버하지 못할 수 있다.

테스트 코드에서 확인해야 하는 내용

테스트 코드는 정상 동작, 오류 처리, 경계 조건을 검증해야 한다.
함수나 모듈이 주어진 입력에서 예상대로 작동하고, 잘못된 입력에 대해 적절한 예외 처리를 수행하는지를 확인해야한다.
또, 극단적 입력값에서도 문제가 없는지와 여러 모둘이 의도대로 상호작용하는지 테스트한다.

주요 라이브러리

주로 사용하는 프레임워크나 언어에 따라 다르지만 대표적인 라이브러리로는
Jest, React Testing Library, Mocha & Chai, Cypress, Junit, Selenium이 있다.
그 중 jest를 사용하여 프로젝트의 테스트 코드를 작성해보기로 했다.


Jest 설치 및 기본 설정

우선 npm install --save-dev jest를 사용하여 설치를 한 뒤
package.json에 아래와 같이 실행 스크립트를 추가한다.

{
   "scripts":{
      "test": "jest"
   }
}

기본적인 Jest 사용법

  1. describe,it 또는 test블록
  • describe: 테스트를 그룹으로 묶어 구조화할 수 있다.
  • it 또는 test: 개별 테스트 케이스를 정의하는 데 사용된다. 둘은 동일한 역할을 한다.
describe("수학 함수 테스트",() => {
  it("숫자를 올바르게 더하는지 확인", () => {
    expect(1 + 2).toBe(3);
  });
  
  test("숫자를 올바르게 곱하는지 확인",() => {
    expect(2 * 3).toBe(6);
  });
});
  1. expect와 매처
  • expect: 테스트의 예상 결과를 정의. 다양한 매처와 함께 사용되어 값을 검증할 수 있다.

자주 사용되는 매처

  • .toBe(value): 기본적인 값 일치를 확인할 때 사용된다.(기본 데이터 타입)
  • .toEqual(value): 객체나 배열의 속성까지 포함해 동일성을 확인할 때 사용된다.
  • .toBeNull(),toBeUndefined(),toBeDefined(): 특정 값이 null,undefined, 정의된 상태인지 확인한다.
  • .toBeContain(value): 배열이나 문자열에 특정 값이 포함되어 있는지 확인.
test("toEqual 과 toBe 예제",()=> {
  const data = { one: 1 };
  data["two"] = 2;
  expect(data).toEqual({ one: 1, two: 2 });
});
  1. 비동기 코드 테스트
    비동기 함수는 async/await 또는 done을 사용하여 테스트할 수 있다.
test("비동기 함수의 값이 올바른지 확인", async () => {
  const fetchData = async () => "Hello, Jest";
  await expect(fetchData()).resolves.toBe("Hello, Jest")
})
  1. Mock 함수
    Mock 함수는 외부 모듈에 의존하지 않고 함수의 호출 여부와 횟수를 확인할 때 유용하다.
test("mock 함수 호출",()=> {
  const mockFn = jest.fn();
  mockFn();
  expect(mockFn).toHaveBeenCalledTimes(1);
});
  1. 스냅샷 테스트
    컴포넌트의 구조가 이전과 동일한지 검증하는데 사용된다.
    UI가 변경되면 Jest가 경고를 표시하며, 변경사항을 승인할 수 있다.
import render from 'react-test-renderer'
import MyComponent from './MyComponent'

test("MyComponent matches snapshot", () => {
  const tree = renderer.create(<MyComponent />.toJSON());
  expect(tree).toMatchSnapshot();
})

Jest 설정 옵션

Jest는 설정 파일을 통해 다양한 옵션을 조정할 수 있다.
jest.config.js파일에 기본 설정을 추가해 테스트 환경을 조정할 수 있다.

module.exports = {
  testEnvironment: "node",
  verbose: true,
  collectCoverage: true,
  coverageDirectory: "coverage"
};
  • testEnvironment: 테스트 환경을 설정. 기본적으로 jsdom이며, Node.js에서 실행할 경우 "node"로 변경할 수 있다.
  • verbose: 테스트 실행 시 자세한 정보를 출력.
  • collectCoverage: 테스트 커버리지를 수집.
  • coverageDirectory: 커버리지 결과가 저장될 디렉토리를 지정.

실제 사용

실제 이번 프로젝트에서 사용을 해보기 위해 우선 공용 컴포넌트인 Deliver Button 컴포넌트에 적용을 해본 예시이다.

it("버튼 클릭 시 onClick 함수가 호출되는지 확인", () => {
        const handleClick = jest.fn();
        render(
            <DeliverButton
                label="Click"
                onClick={handleClick}
                length="full"
                isModal={false}
            />
        );
        const button = screen.getByRole("button", { name: /click/i });
        fireEvent.click(button);
        expect(handleClick).toHaveBeenCalledTimes(1);
    });

위 예시에서 mockFn()을 사용하여 함수 호출을 추적하였으며,

  • render(...)@testing-library/react 라이브러리의 함수이다.
    테스트할 React 컴포넌트를 가상DOM에 렌더링 한다.
  • const buttonscreen.getByRole@testing-library/react에서 제공하는 쿼리 메서드로, 특정 역할(role)을 가진 요소를 선택한다.
  • getByRole("button", { name: /click/i })는 DOM에서 역할이 "button"이고, 접근성 이름(name)에 "click"이 포함된 요소를 찾는다.
    label"Click"인 버튼이 선택된다.
  • fireEvent.click는 선택한 요소에 클릭 이벤트를 발생시킨다.
  • expect는 Jest의 단언 함수로, 특정 조건이 참인지 확인한다.
  • toHaveBeenCalledTimes(1)handleClick함수가 정확히 한 번 호출되었는지 검증하는 메서드이다.

0개의 댓글