테스트 코드 (and TDD)

goodjam92·2023년 4월 4일
0

서론

지금까지 사이드 프로젝트, 회사 프로젝트를 진행하면서 테스트 코드에 대해서는 작성해본적이 없다. 오로지 직접 동작해보거나 console.log를 통해 버그가 없는지 하나씩 확인하면서 작업했다. 그런데 이 방법은 시간적인 소요가 매우 컸고, 불편하였다. 그래서 이번 기회에 테스트 코드에 대해 학습해보고, 내용을 정리해보려고 한다.

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

  • 작성한 코드가 잘 작동하는 것을 검증하기 위함
  • 사람이 아닌 테스트 자동화를 통해 테스트 시스템이 일정한 동작으로 검증
  • 코드 수정 후 작성한 코드와 연관된 다른 코드들에 대해서도 문제가 없는지 확인할 수 있음
  • 개발 과정에서 실수가 발생할 수 있는 상황에 대해 미리 대비할 수 있다
  • 규모가 큰 기능의 경우 리팩토링 시 이전과 코드가 동일하게 작동하는지 검증하는 것이 매우 쉬워짐

테스트 코드 종류

유닛(Unit) 테스트

아주 작은 단위로 진행되는 테스트
(보통 하나의 파일만 테스트)

  • 유닛 테스트의 예시
    • 컴포넌트 렌더링이 잘 된다.
    • 컴포넌트의 특정 함수를 실행하면 상태가 원하는 형태로 바뀐다.
    • 리덕스의 액션 생성 함수가 액션 객체를 잘 만들어낸다.
    • 리덕스의 리듀서에 상태와 액션 객체를 넣어서 호출하면 새로운 상태를 잘 만들어준다.

통합(Integrated) 테스트

전체적으로 기능들이 잘 작동하는지 확인하기 위한 테스트
(여러 파일들, 한 파일에 여러 기능들의 테스트)

  • 통합테스트 예시
    • 여러 컴포넌트를 렌더링하고 서로 상호 작용에 문제가 없다.
    • DOM 이벤트를 발생시키면 원하는 UI의 변화에 문제가 없다.
    • 리덕스와 연동 된 컨테이너 컴포넌트의 DOM에 특정 이벤트를 발생시키면 원하는 액션이 잘 디스패치 된다.

자바스크립트 테스트 도구

  • Karma (브라우저와 유사한 환경에서 테스트 실행)
  • Jasmine (Jest의 기반이 되는 프레임워크, 오랜기간 사용 되었으며 많은 정보 수집 가능)
  • Jest (간단한 사용법, 병렬 메커니즘으로 대형 프로젝트로 갈수록 빠른 속도)
  • Chai (많은 플러그인과 확장 기능)
  • Mocha (유연하고 확장 가능한 구성)
  • Sinon, Unexpected ... 등등 다양 함.

테스트 코드 작성해보기

먼저 자바스크립트에서의 테스트 코드를 작성해보고, 리액트에서 사용해보기로 한다. 테스트 프레임워크는 설정이 간단하고 시작하기 좋은 Jest로 사용해보도록 하자.

시작

1. Jest 설치

yarn add jest
(or) 
npm install --save jest

2. 파일 생성 및 설정

  • 자바스크립트 파일(.js)을 생성한다.
  • 테스트 코드를 작성 할 파일을 파일명.test.js형식으로 생성한다.
  • packge.json 파일에서 다음과 같은 내용을 추가한다.
"script": {
 "test" : "jest --watchAll --verbose"
}

3. 테스트 코드 작성

sum.js 파일에 두 개의 인자를 받아서 합산한 값을 반환해주는 함수 작성

function sum(a, b) {
	return a + b;
}
modules.export = sum;

sum.test.js 파일에 함수가 잘 작동하는지 테스트 케이스를 작성한다.

const sum = require('./sum');

test("1 + 2 = 3", () => {expect(sum(1, 2)).toBe(3); });
  • test 함수는 새로운 테스트 케이스를 만드는 함수
  • expect는 특정 값이 ~~ 일 것이다 라고 사전에 정의하고, 통과하면 테스트를 성공 시키고 통과 못하면 테스트를 실패처리
  • toBematchers라고 부르는 함수이며 특정 값이 어떤 조건을 만족하는지, 어떤 함수가 실행이 됐는지, 에러가 발생하였는지 등 확인 할 수 있게 해준다.
  • babel을 사용하지 않는다면 ES5 문법으로 작성해야 한다.

4. 테스트 실행

터미널에 다음과 같이 입력한다.

yarn test 
(or)
npm test
  • 통과 되었을 경우

  • 통과 되지 못하였을 경우

    • sum.js 파일을 다음과 같이 변경하고 테스트 결과를 지켜보자
function sum(a, b) {
	return a - b;
}

5. it과 describe

  • it

    • 앞에서 test함수를 사용하여 테스트 케이스를 생성하였는데 이 때, test대신 it이라는 키워드를 사용할 수도 있다.
  • describe

    • 테스트 케이스를 작성할 때 describe라는 키워드를 사용하면 여러 테스트 케이스를 묶을 수 있다.

sum.js

function sum(a, b) {
	return a + b;
}

// 배열의 모든 숫자 더하는 함수 추가
function sumOf(numbers) { 
 let result = 0;
  numbers.forEach(num => result += num);
}
return result;

exports.sum = sum;
exports.sumOf = sumOf;

sum.test.js

const { sum, sumOf } = require('./sum');

describe("sum", () => {
  it("1 + 2 = 3", () => {
  expect(sum(1, 2)).toBe(3); 
  });
  
  it("sum all numbers", () => {
    const array = [1, 2, 3, 4];
    expect(sumOf(array)).toBe(10);
  }
}

describe로 테스트 코드를 감싸주고, 여러 테스트 케이스가 sum 이라는 이름으로 분류된다.

6. 리팩토링

sum.js

function sum(a, b) {
	return a + b;
}

// 배열의 모든 숫자 더하는 함수 추가
function sumOf(numbers) { 
	return numbers.reduce((acc, current) => acc + current, 0);
};

exports.sum = sum;
exports.sumOf = sumOf;

우리가 리팩토링 과정에서 실수 또는 문제들이 있다면 테스트 코드가 실패해서 우리는 직접 테스트를 해보지 않아도 알 수 있을 것이다. 물론 모든 문제에 대해 방지할 수는 없겠지만 테스트 코드를 통해서 많은 부분을 걸러낼 수 있다.


TDD (테스트 주도 개발)

[이미지 참고] - How Test-Driven Development Creates Code That ALWAYS Works

TDD는 테스트가 개발을 이끌어 나가는 형태의 개발론이다. 먼저 테스트 코드를 작성하고 기능을 구현한다고 보면 되는데 총 3가지 절차로 이루어져있다.

Red (실패)

  • 실패하는 테스트 케이스를 먼저 만든다.
  • 지금 구현해야하는 기능을 하나씩 테스트 케이스를 작성한다.
  • 상황에 따라 한 번에 여러 테스트 케이스를 작성하기도 한다.

Green (성공)

  • 실패하는 테스트 케이스를 통과하기 위해 코드를 작성하여 테스트를 통과시키는 것

Refactor (리팩토링)

  • 구현한 코드에 중복되는 코드 또는 더욱 개선시킬 방법이 있다면 리팩토링을 진행
  • 리팩토링 후 테스트 케이스가 통과되는지 확인
  • 절차가 완료되면 다시 Red 단계로 가서 다음 작업을 진행한다.

TDD 장점

  • 작은 단위로 만들기 때문에 코드의 길이가 과하게 방대해지지 않고, 코드의 모듈화가 자연스럽게 이루어진다.
  • 테스트 커버리지가 높아지기에 리팩토링과 유지보수가 쉬워진다.
  • 프로젝트의 퀄리티가 높아지고 협업에 도움이 된다.
  • 버그에 소요되는 시간을 줄일 수 있다.

정리

테스트 코드라는 것을 알고나니 TDD 방법으로 개발을 진행하면 시간이 좀 더 소요되기는 하겠지만 퀄리티가 높고 깔끔한 코드를 써내려가며 개발할 수 있겠다는 생각이 들었다. 지금까지는 직접 하나씩 동작해보며 버그나 잘못된 부분이 있는지 확인하다보니 시간이 많이 소요되었었는데 테스트 코드를 작성해두면 시간도 많이 절약되고, 이점이 많은 것 같아 다음에는 이 방법을 사용하여 개발해봐야겠다.

.
.
.
.
.
.
.
.

참고사이트
베로퍼트와 함께하는 리액트 테스팅

profile
습관을 들이도록 노력하자!

0개의 댓글