Intro
디프만 15기에 합류하게 되면서 스터디에도 욕심을 내봤다. 솔직히 프로젝트를 위해서 글을 쓰는 오늘 시점부터 배울 것이 너무나 많아져서 내가 너무 황새 따라가려다 다리가 찢어지는 거 아닐까 약간! 아주 약간! 🥲 걱정이 되긴 하지만, 간단하게라도 혼자가 아니라 사람들과 공유하면서 배워가는 경험을 얻고 싶었다.
그러나 좀처럼 프론트엔드 직무에 적합한 스터디 공고가 올라오지 않고 있었는데, 다행히 같은 팀인 HM님이 테스트 코드 관련 강의 스터디 공고를 올리셔서 이번 스터디는 프론트엔드의 테스트 코드를 간단하게 알아보는 것으로 진행하게 되었다. 아주 예전에 React 강의에 묶음으로 있었던 Jest로 테스트 코드가 무엇이고 왜 쓰는 것인지는 한 번 찍먹을 해봤지만, 당시에는 React를 사용하는 법만으로도 벅찼기 때문에 우선순위가 높은 기술이 아니어서 기억 저 너머에 쳐박아 두었었다...
여러 프로젝트를 진행하면서, 또 최근 취업 공고를 뒤적여보면서 어느 정도 규모가 있는 프로젝트에서는 테스트 코드가 거의 필수라는 걸 체감하게 됐고, 지금 당장 너무나 필요한 기술은 아니더라도 확실히 도움이 될 거라고 생각된다.
이 강의는 37개임에도 불구하고 2시간이 안되는 짧고 간단한 강의다. 중간 점검 이후 매우 바빠질 일정을 고려하면 짧아도 알찬 강의라고 생각된다. (게다가 인프런이 디프만을 지원해주기 때문에 30% 저렴한 가격으로 강의를 겟했다.) 🫶🏻
테스트 코드란?
테스트 코드는 말 그대로 개발자가 작성한 코드에 문제가 없는지 테스트를 하기 위해 작성하는 코드를 말한다.
'개발하고 제대로 동작하면 그만 아니야? 왜 테스트까지 해야 해?'라고 나도 생각한 적이 있었는데, 단순히 지금 잘 동작하는지의 여부보다 미래의 안정성에 더 중점을 둔 게 테스트 코드라고 생각한다.
- 정확성과 신뢰성 (다양한 조건/입력에서도 예상한대로 정확하게 동작하는지)
- 이후에 진행될 수월한 리팩토링을 위해 🥹
이 2가지가 가장 큰 목적이지만 이외에도 테스트를 명확하게 한다는 것은 곧 잘 작성된 문서화로 보여지고, 개발자는 물론 기획자와도 소통할 수 있다는 장점이 있다.
무엇을 테스트 하는가?
테스트 코드의 목적은 위에서 말했다시피 정상적으로, 예상한대로 코드가 동작하는지 확인하는 것이다.
이것을 하는 이유는 유저가 우리 서비스를 이용할 때 어떤 상황에서도 문제가 없다는 것을 확인하기 위해서다.
즉 단순히 보여지는 UI보다는, 어떤 버튼을 클릭하거나 어떤 인풋에 값을 입력했을 때 제대로 굴러가는지를 확인해야 한다.
테스트의 유형
강의에서 다루는 테스트의 유형은 유닛 테스트, 통합 테스트, E2E 테스트 3가지다.
- 유닛 테스트
- 가장 작은 단위의 테스트
- ex. 버튼을 클릭했을 때 제대로 모달이 나오는지, 인풋에 값을 입력하면 잘 나오는지
- 통합 테스트
- 다양한 컴포넌트, 모듈, 함수들이 잘 연결되어 동작하는지 테스트
- ex. 로그인 실패 시 메인으로 잘 redirect 되는지 등
- E2E 테스트 (End to End)
- 실제 유저가 사용하는 것처럼 시작부터 끝까지 작동 순서를 검증하는 테스트
- ex. 회원가입 페이지에서 생성된 정보로 로그인이 잘 되는지, 잘못 로그인할 경우 에러 메세지가 나오는지 등
강의에서는 프론트엔드의 경우 통합 테스트와 E2E 테스트의 경계가 모호해 굳이 구분 짓지 않아도 된다고 한다.
통합 테스트는 결국 컴포넌트를 렌더링 해서 테스트를 하는 거고, E2E 테스트는 페이지에서 접근해 테스트를 하는 것이기 때문이다.
그래서 그 부분보다 유닛 테스트와 통합 테스트는 jest를, E2E 테스트는 cypress를 사용하는 것으로 접근하는 것이 더 적합하다.
(물론 cypress로 유닛 테스트와 통합 테스트도 진행할 수 있다.)
jest를 사용한 테스트 코드
jest는 페이스북에서 만든 테스팅 라이브러리다.
초기에는 프론트엔드에서 주로 사용되었지만 백엔드에서도 사용되는 기술이라고 한다.
테스트 코드 파일을 생성할 때는 통상적으로 테스트할파일이름.spec.tsx와 같은 형태로 생성한다.
test.tsx로 적는 글들도 봤는데 테스트의 목적이 특정 사양대로 동작하는지(spec)/단순 테스트인지(test)에 따라 다른 것 같다.
jest에서 주로 사용하는 테스트 코드 문법으로는 it(또는 test), describe, beforeEach, beforeAll, afterEach, afterAll 이렇게 6가지가 있다. it, describe까진 써봤던 것 같은데 기억 안남 이슈... 하나씩 자세히 알아보자!
it (또는 test)
실제 테스트 코드를 작성하는 함수로, 하나의 테스트 케이스를 작성한다.
강의에서는 영문으로 테스트 명을 작성할 때는 it을, 한글로 작성할 때는 test로 작성하는 것을 권장한다.
둘은 기능적으로 완전히 똑같고 단지 가독성, 취향에 따라 작성하면 된다.
// it
it('should add a + b to equal 3', () => {
expect(sum(a + b)).toEqual(3);
});
// test
test('a + b는 3이다.', () => {
expect(sum(a + b)).toEqual(3);
});
describe
it이나 test의 묶음으로 관련 있는 테스트들을 하나로 묶는 함수다.
이를 통해 응집도를 높이고 지금 테스트 하려는 내용과 관련된 함수들을 설명한다.
describe("테스트 하려는 컴포넌트", () => {
it("should test component A", () => {});
test("테스트 케이스 1번, 00를 테스트한다.", () => {});
});
beforeEach
describe 블록 안에 있는 각각의 it 또는 test가 동작하기 전에 먼저 동작하는 함수다.
describe("테스트 하려는 컴포넌트", () => {
beforeEach(() => {
console.log("beforeEach");
});
it("should test component A", () => {
console.log("it");
});
test("테스트 케이스 1번, 00를 테스트한다.", () => {
console.log("test");
});
});
이런 식으로 작성된 코드가 있을 때 결과는 아래와 같이 나온다.
beforeEach
it
beforeEach
test
사이에 또 it이나 test가 들어간다면 그것들이 각각 실행되기 전에 또 beforeEach가 실행될 것이다.
beforeAll
beforeEach가 각각의 it 또는 test가 동작하기 전에 먼저 동작하는 함수라면, beforeAll은 각각의 describe 전에 동작하는 함수다. 즉 it 또는 test 전에 딱 한 번만 돈다.
describe("테스트 하려는 컴포넌트", () => {
beforeAll(() => {
console.log("beforeAll");
});
beforeEach(() => {
console.log("beforeEach");
});
it("should test component A", () => {
console.log("it");
});
test("테스트 케이스 1번, 00를 테스트한다.", () => {
console.log("test");
});
});
위의 예제에서 beforeAll만 추가했다.
beforeAll
beforeEach
it
beforeEach
test
이 경우에는 이렇게 동작된다!
beforeAll 먼저 한 번 돌고, 그 다음에 각각의 beforeEach들이 돌게 된다.
afterEach
beforeEach와 반대로 describe 블록 안에 있는 각각의 it 또는 test의 동작 후에 동작하는 함수다.
configuration을 초기화 하거나 mock data를 클린 업 할 때 사용한다.
afterAll
beforeAll과 반대로 각각의 describe가 동작한 후에 동작하는 함수다.
여러 개의 describe에 공통적으로 사용되는 것들을 초기화 할 때 사용한다.
describe("테스트 하려는 컴포넌트", () => {
beforeAll(() => {
console.log("beforeAll");
});
beforeEach(() => {
console.log("beforeEach");
});
afterEach(() => {
console.log("afterEach");
});
afterAll(() => {
console.log("afterAll");
});
it("should test component A", () => {
console.log("it");
});
test("테스트 케이스 1번, 00를 테스트한다.", () => {
console.log("test");
});
});
이렇게 있을 때는 아래와 같이 동작한다.
beforeAll
beforeEach
it
afterEach
beforeEach
test
afterEach
afterAll
이런 식으로 테스트에서 필요한 메서드를 적절하게 사용할 수 있다.
참고 강의
'⚛️ React > 📜 Test Code' 카테고리의 다른 글
[Test Code] Cypress로 본격적인 테스트 코드 작성하기(fixture, recoil mocking) (0) | 2024.07.02 |
---|---|
[Test Code] Cypress로 테스트 하기 (0) | 2024.07.02 |
[Test Code] react-query 공식 문서를 따라 테스트 코드를 하면 안되는 이유 + nock으로 mocking 하기 (0) | 2024.06.26 |
[Test Code] beforeEach()를 활용한 Jest 성공 케이스 작성 (0) | 2024.06.19 |
[Test Code] Jest를 활용해 테스트 코드 작성하기 (0) | 2024.06.19 |