Jest 도구를 이용해서 여러 가지 테스트를 해보자 기본적인 단위 테스트를 하는 방법과 TDD를 할 수 있도록 테스트를 먼저 써서 진행하는 방법을 알아보자

Jeong·2023년 8월 17일
2

테스트

목록 보기
1/4
post-thumbnail

키워드

  • TDD란
  • Jest
  • Describe - Context - It 패턴
  • 단위테스트란

최종 목표

테스트와 테스트 하는 방법에 대해 알아보자.

학습 목표

Jest 도구를 이용해서 여러 가지 테스트를 해보자. 기본적인 단위 테스트를 하는 방법과 TDD를 할 수 있도록 테스트를 먼저 써서 진행하는 방법을 알아보자.

TDD란? (Test Driven Development)

구현보다 테스트 코드를 먼저 작성하는 방식이다.

즉, 인터페이스스펙 을 먼저 정의하고 개발을 진행한다.

인터페이스와 스팩을 먼저 정의함으로써 막연하게 시작하지 않을 수 있다.

여기에서 말하는 인터페이스는 타입스크립트에서 쓰는 시그니처와 같은 의미이다.
예를 들어서, add(x, y) => number 이렇게 쓸 수 있다.

그리고 스펙을 x, y 를 넣으면 둘이 더해진다. 로 해석할 수 있다.

정확하게는 시그니처를 모아놓은게 인터페이스이다.

테스트 코드만 먼저 작성하면 TDD인가요?

테스트 코드를 작성한다고 해서 TDD 가 아니다.

TDD Cycle 과정을 엄격하게 지켜서 개발을 진행해야 TDD라고 할 수 있다.

TDD Cycle 이란?

TDD Cycle은 테스트 코드를 먼저 작성하고, 구현하고, 리팩터링 하는 과정이다.

목표까지 TDD Cycle을 계속해서 반복해야 한다.

STEP1: Red

실패하는 테스트 코드를 작성한다.

인터페이스와 스펙을 어떻게 하면 잘 쓸지에 (테스트 코드를 어떻게 하면 잘 쓸지에) 집중한다.

STEP2: Green

재빨리 테스트를 통과시킨다.

브루트포스를 써도 상관없으니 재빨리 통과시킨다. 올바른 방법이 아니어도 괜찮다.

TDD 창시자 캔트 백은 빨리 통과시키기 위해 죄악을 저릴러도 괜찮다고 할 정도이다.

STEP3: Refactor

리팩터링을 통해 코드를 올바르게 만든다. 재빨리 만들었던 코드를 고치는 것이다.

Refactoring 간과하지 마세요!

STEP3: Refactor는 TDD에서 가장 중요한 부분이지만, 간과될 때가 많다.

TDD가 목표로 하는 것은 제대로 동작하는 클린코드 이다.
이를 위해서 제대로 작동해야 하고(STEP2), 클린코드로 나아갈 수 있게 리펙터링(STEP3)을 해야 한다.

그러니 처음부터 완벽한 해법을 내려고 하지 말자. 굉장히 어렵다.
일단 통과하는 테스트를 만들고(STEP2) 리펙터링(STEP3)을 통해 조금씩 바꾸자.

Refactoring 이 지향하는 바는?

리펙터링이 지향하는 바는 동작은 바뀌지 않고 설계만 바꾸는 것이다.

즉, 어떻게 작동하는지에 대한 스펙은 바뀌지 않고 내부에 구현되어 있는 코드만 바꾼다.

실제로 마틴 파울러의 책에서 나오는 단위 테스트를 리펙터링 하는 부분을 보면, 테스트가 터지지 않은 선에서 고친다.

하지만 설계를 바꾸다 보면 동작을 바꿀 때가 있다. 괜찮다. 테스트가 깨지니 STEP1으로 돌아간 것이다. 다시 잘 고치면 된다.

TDD Cycle을 잘 돌리는 법

작은 단계를 찾는다. 그리고 계속해서 반복한다.

작은 단계는 1분 이하로 가져올 수 있으면 BEST이다. 적어도 10분 안에 한 사이클이 돌아야 한다.
그래야 작은 단계를 여러 번 진행할 수 있다.

작은 단계를 여러 번 진행하면 좋은 점이 있다. 각 단계 속에서 피드백을 얻기 때문이다.
그래서 큰 단위로 일을 하면 안되는 일이 생겼을 때 일주일 동안 붙잡고 낑낑되게 되는 것이다.

만약 STEP2 가 어렵다면?

STEP2 를 어떻게 해도 통과시키지 못하고 있다면 STEP1 에서 잡은 단위가 큰 것이다.
STEP1 에서 더 작고 더 쉬운 문제로 정의해야 한다.

만약 STEP 3 가 어렵다면?

중복을 제거를 하는 연습을 해야 한다.

코드는 어떤 의도를 가지고 작성하게 된다. 그러면 의도가 이곳저곳에 있게 된다. 그 중에서 중복되는 의도를 찾아서 처리하는 것이다.

클린 코드를 만들기 위해서 필수이다.

작은 단위의 문제를 만드는 것, 중복을 찾아서 제거하는 것. 개발을 잘하려면 당연히 갖춰야 하는 조건이다.

TDD 만의 문제가 아니다.

Jest 란?

Jest 라는 도구를 이용해 TDD를 연습해보자.

Jest는 페이스북에서 만든 테스팅 도구이다. 쓸 만한 것을 모두 모아놓았고 단순하다.

Jest모카 라는 테스팅 도구의 영향을 받았고,
모카 는 루비로 된 알스펙 이라는 테스팅 도구의 영향을 받았다.

그래서 Jest 로 테스트 코드를 작성할 때 알스펙 으로 작성한 코드를 참고해도 도움이 된다.

예를 들어 Describe - Context - It알스펙 에서 쓰는 패턴이다.
Jest 에서는 Context 를 기본적으로 제공하지 않지만 이 패턴을 사용한다.

테스트 케이스를 정의하는 방법

  • test 함수로 개별 테스트를 나열하는 방식
  • BDD 스타일로 주체-행위 중심으로 테스트를 조직화하는 방식

test 함수로 개별 테스트를 나열하는 방식

test('add', () => {
	expect(add(1, 2)).toBe(3);
});

BDD 스타일로 주체-행위 중심으로 테스트를 조직화하는 방식

주체(어떤 것을 테스트할지) 그리고 행위(어떻게 될지) 에 대해 드러낼 수 있다.

describe('add', () => {
	it('add는 ~ 한다', () => {
		expect(add(1, 2)).toBe(3);
	});
});
describe('add', () => {
	it('returns sum of two numbers', () => {
		expect(add(1, 2)).toBe(3);
	});
});

1번은 단순해서 좋다. 그래서 간단한 테스트를 할 때 사용한다.

스펙이 많다면 Describe - Context - It 패턴으로

const context = describe;

describe('add', () => {
	context('with no argument', () => {
		it('returns zero', () => {
			expect(add()).toBe(0);
		});
	});

	context('with only one number', () => {
		it('returns the same number', () => {
			expect(add(1)).toBe(1);
		});
	});

	context('with two numbers', () => {
		it('returns sum of two numbers', () => {
			expect(add(1, 2)).toBe(3);
		});
	});

	context('with three numbers', () => {
		it('returns sum of three numbers', () => {
			expect(add(1, 2, 3)).toBe(6);
		});
	});
});

위에서도 언급했지만 Describe - Context - It알스펙 에서 쓰는 패턴이다. 그래서 context는 지원하지 않는다. describe를 이용해서 만들어줘야 한다.

Jest에서 타입스크립트를 사용하도록 jest.config.js 파일 생성 및 작성

Jest에서 타입스크립트를 사용하도록 jest.config.js 파일 생성하고 작성한다.

module.exports = {
	testEnvironment: 'jsdom',
	setupFilesAfterEnv: [
		'@testing-library/jest-dom/extend-expect',
	],
	transform: {
		'^.+\\.(t|j)sx?$': ['@swc/jest', {
			jsc: {
				parser: {
					syntax: 'typescript',	
					jsx: true,
					decorators: true,
				},
				transform: {	
					react: {
						runtime: 'automatic',
					},
				},
			},
		}],
	},
};

참고로 ^.+\\.(t|j)sx?$ 에서 x? 는 x는 없어도 된다는 뜻이다.
그래서 ts(x) 과 js(x) 파일에 대해서 swc/jest가 변환을 해준다.

swc는 타입스크립트 코드를 자바스크립트로 변환하기 위해서 jest와 함께 쓰고 있다.
jest는 기본적으로 타입스크립트를 지원하지 않는다.

TDD에서 중복을 제거한다는 게 어떤 의미인지 알아내자

https://github.com/ahastudio/til/blob/main/blog/2016/12-03-tdd-faq.md
바닥부터 만들기

https://github.com/ahastudio/til/blob/main/jest/20201204-simple-tdd-example.md
중복을 계속 만든다
그 다음에 패턴(중복)을 찾고 정리한다.

아하! 포인트

  • 테스트 도구 자체에 익숙해지는게 가장 중요하다.
  • 테스트 작성 자체에 가중치를 두자.
    • 처음부터 TDD를 제대로 습득하는 건 대단히 어렵다.
    • 부담 갖지 말고 되도록 테스트를 많이 작성하는 훈련을 해보자.
  • 강의에서 아샬이 보여주는 TDD Cycle 을 적용하는 흐름을 악착같이 따라가자.

알고리즘 문제를 풀 때도 테스트를 작성하면 리펙터링이 쉬울 것 같다.
동작을 바꾸다가 설계도 바꾸는 실수를 줄일 수 있으니까.

다음에는?

React Testing Library 에 대해 알아보자.

profile
성장중입니다 🔥 / 나무위키처럼 끊임없이 글이 수정됩니다!

2개의 댓글

comment-user-thumbnail
2023년 8월 17일

좋은 정보 얻어갑니다, 감사합니다.

1개의 답글