테스트코드 입문 주니어의 개념 공부하기

최윤성·2024년 4월 4일
1
post-thumbnail

테~스트 테~스트 테테테텥테텥 테스트~

들어가며..

요즘 채용공고를 보면 항상 우대사항 혹은 필수역량에 언급되는 기술스택이 있습니다.
바로 시니어같은 주니어 가 아니라 테스트 코드 작성 경험 혹은 여부이죠.

사실, 테스트 코드는 채용공고말고도 우리가 심심치않게 항상 말하는 주제이긴 합니다.
우리에게 익숙한 React 라이브러리에서도 컴포넌트 분리의 중요성 측면에서 "테스트 코드의 작성이 쉬워진다" 라는 장점이 있고요.

우리는 이렇듯 평소 테스트코드의 존재는 알았지만 테스트코드에 입문하기 껄끄러웠을수도 있습니다. 그 이유는

  • 실제 구현도 시간이 부족한데 테스트 코드까지 작성하려면 시간이 너무 오래걸려! 😈
  • 어플리케이션 변경 사항을 테스트코드에 까지 업데이트해야해서 테스트코드도 유지보수해야해.. 😵💫

하지만, 테스트코드에는 단점만 있는것이 아닌 장점도 있습니다. 나름 무서운 친구는 아니랍니다~
그럼 이번글에서 테스트코드와 같이 친해지는 시간을 가져보아요~

테스트코드 공부 계기

본인은 사실 테스트 코드말고도 아직 모르는게 많은 주니어 개발자입니다. 따라서 일단 여러가지 기술스택을 공부하며 프로젝트 설계 및 기능구현도 벅찬 상황이였고 이 상황에서

TDD 관점 으로 코딩을 하는것은 매우 어렵다.

라는 이야기와 또한 회사에 아직 테스트코드 기술이 도입되지 않았다는 이유로 테스트 코드 설계에 대한 내용을 배우지 않는것을 정당화 하였습니다.

하지만, 시간이 지나며 나름 회사에서 진행한 프로젝트도 몇 있고 해당 프로젝트를 진행하며 또 진행 후에 유지보수 및 인수인계를 하며 내가 짠 코드가 어떤 아키텍처로 설계되어 있으며 추가로 컴포넌트 하나하나마다 어떤 생각으로 코드를 설계하였는지 기억이 나지않아 하나하나 다시 코드를 봐야하는 상황이 생겼습니다.

전 개발자가 어떤사람이였길래 ㄷㄷ... 난 누군지 정말 모르겠다~

그래서 테스트코드를 사용해 TDD 기법을 이용하면 나의 주니어 시기에 성장에 큰 도움이 될거같아 공부하게 되었습니다.

테스트의 정의 및 테스트코드 사용 이유

설이나 이론이 실제로 들어맞는지를 확인하기 위해 다양한 조건 아래에서 여러 가지 측정을 실시하는 일 ( 위키백과 )

우리 위키백과 선생님 말씀으론 위와 같이 말하십니다.

사실 우리가 평소에 하는 테스트(테스트 코드를 사용하지않고)도 위 사전적 정의를 그대로 따라갑니다.

  • 설이나 이론 : 디자이너가 준 피그마 / 기획자의 기능정의서
  • 다양한 조건 아래서 여러가지를 측정 확인 : 개발자가 개발하면서 진행하는 디버깅 및 QA

즉, 우린 이미 "테스트" 라는 정의에 부합하는 일을 이미 하고있다는겁니다.

나 사실 일 잘하는 개발자일지도??

하지만, 이렇게 우리가 평소에 하는 테스트도 한계점이 있는데

만약에 기능이 매우 많거나 코드를 수정했는데 해당 기능과 관련된 다른 다양한 기능들이 있다고 가정해봅시다. (예를들면 회원가입 기능?)

이 상황에서 리팩토링 조금 한걸로 이 모든것에 대한 테스트 (비지니스 로직의 플로우 모두)를 계속 하게 된다면 매우 비효율적일테고 그렇다고 리팩토링을 안하자니 기술 부채는 증가할 것이고 악순환이 될겁니다.

ㅋㅋㅋㅋㅋㅋ 기술부채 막이래

이 상황에서 구세주 같은 코드가 바로 "대 황 테스트 코드" 되시겠습니다.

대 황 코드를 작성하게 된다면

  • 적극적인 리팩토링이 가능해지며 결함을 예방하고 요구사항을 충족하는지 검사할 수 있다.
  • 테스트 코드가 명세서의 역할을 하여 코드를 파악하는데 도움을 주기 때문에 협업에서도 유용하다.
  • 더 나아가 테스트 자동화로 반복적인 테스트에 대한 비용이 줄어든다.
    (테스트 코드를 작성하는 비용이 있긴하지만..)

이러한 부분들에서 이점을 얻을 수 있습니다.

다만, 모든것이 완벽한 팔방미인도 내성발톱은 있는법..

  • 테스트 코드를 작성하는 비용이 있습니다. 이때문에...
    (모든 부분에서 하는것은 비효율적이기 때문에 프로젝트를 설계해야하는데 테스트 코드만 짤 수는 없습니다.)

따라서, 테스트 코드를 사용하기 위해선 테스트 코드가 테스트하는 기능의 중요도를 잘 체크해야합니다.

프론트엔드 테스트 종류

프론트엔드 테스트의 종류는 크게 4가지로 나눌 수 있습니다.

  • 정적테스트
  • 단위테스트
  • 통합테스트
  • E2E (End to End)

단위테스트

나는 나만 신경쓰고 나만의 길로만 간다 기호 2번 단위테스트~

단위테스트는 말 그대로 어플리케이션을 가장 작은 단위로 분리하여 테스트하는것을 의미합니다.

프로젝트를 설계하면서 util 함수, 커스텀 훅, 컴포넌트 파일 등을 생성하게 된다. 이에 대한 가장 작은 단위의 테스트 코드를 설계하는것이 단위 테스트이다.

컴포넌트를 테스트할 경우 자식 컴포넌트까지 포함하여 렌더링하는 Sociable Test가 있고, 자식 컴포넌트를 Mocking해서 렌더링하는 Solitary Test가 있습니다.

여기서 Mocking 이란 모조품을 만들어 일단 코드가 돌아가게 하는것입니다. 컴포넌트의 자식 컴포넌트가 있을경우 자식 컴포넌트의 모조품을 만들어 가짜로 대체하는 것입니다.

테스트하고 싶은 기능이 다른 기능들과 엮여있을 경우 유용하게 사용할 수 있습니다.
(jest 의 jest.fn() 함수느낌..)

단위 테스트를 함으로써 얻는 이점은 아래와 같습니다.

  • 수행 목적에 따른 행위가 뚜렷한 함수와 컴포넌트등을 설계하기위해 고려하게된다.
    이벤트도 발생시킬 수 있어 기존에 하던 콘솔 디버깅도 할 수 있다.

통합(Intergration) 테스트

나는 모든걸 한번에 하기를 좋아해.. 한번 엮이면 일단 같이 움직여야하는 기호 3번 통합테스트

어플리케이션의 여러 부분들이 통합되어 제대로 상호작용 되는지 테스트합니다. 단위테스트는 단일 모듈에서만 테스트를 진행하여 자신의 단위 내에서만 에러를검증할 수 있었다면, 통합테스트는 모듈 간의 연결에서 발생하는 에러를 검증할수 있고, 단위 테스트보다 넓은 범위에서 테스트하므로 리팩토링할 경우 사이드 이펙트가 적습니다.

의존성 있는 모든 모듈이 연결된 상태로 테스트하는 board test와 연결된 모듈을 모킹 또는 가상의 API로 대체하여 테스트하는 narrow test가 있습니다.

프론트엔드에서의 통합 테스트는 state 변화에 따른 UI변경, UI와 API간의 상호작용에 대한것이 있습니다.

단위테스트와의 차이점 을 살펴보면 아래와 같습니다.

  • 단위 테스트와 달리 개발자가 변경할 수 없는 부분까지 묶어 검증할 때 사용합니다. (Ex. 외부 라이브러리)
  • 단위 테스트에서 발견하기 어려운 버그를 찾을 수 있습니다.
  • 단위 테스트보다 더 많은 코드를 테스트하기 대문에 신뢰성이 떨어질 수 있고 어디에서 문제가 발생했는지 확인하기 어렵습니다.

이게바로 무한동력 자동문??

E2E (End to End)

나는 모두를 수용할 수 있는 능력을 지닌 기호 4번 E2E~

유닛 테스트로 함수를 테스트하고, 통합 테스트로 서로 다른 시스템이 잘 상호작용하는지 테스트합니다. E2E 테스트는 종단(Endpoint)간 테스트로 유저의 입장에서 유저가 애플리케이션을 사용하는 상황을 가정하고 테스트를 수행합니다.


개발자는 결코 유저를 만만하게 봐서는 안돼..(출처 : 청원이 유튜브)

각 목적에 맞는 개발 라이브러리

단위테스트

Jest

jest는 단위 테스트를 위한 프레임워크입니다. JavaScript로 작성된 모든 코드의 테스트를 지원하고 있으며 독립적으로 실행이 가능합니다.

TypeScript에서도 @types/jest와 jest에서 typescript를 실행할 수 있게 도와주는 ts-jest만 있으면 사용할 수 있습니다.


통합테스트

enzyme

Jest가 자바스크립트 테스트 프레임워크라면, enzyme은 React를 테스트하기 위해 airbnb에서 만든 라이브러리이다. enzyme는 독립적으로 사용할 수 없기 때문에 Jest와 함께 사용하여 React의 단위 테스트와 통합 테스트가 가능해진다.

react-testing-library(RTL)

enzyme와 다르게 컴포넌트 구현 세부 사항에 중점을 두지 않고, 실제 브라우저 DOM을 기준으로 테스트를 작성합니다. 그래서 RTL은 컴포넌트의 속성(state, props 등)에 대한 접근을 제공하지 않습니다.


E2E(End to End)

cypress

E2E 테스트(단위 테스트와 통합 테스트도 가능)가 가능한 도구이다. GUI 도구를 지원하고, 스펙관리 및 디버깅이 편리합니다. test runner가 jest가 아닌 mocha라는 특징이 있습니다.


마치며

그동안 미뤄왔던 테스트 코드의 개념을 한번 되돌아보며 정리하는 시간을 가졌습니다.
다가가기 어려웠던 친구이니만큼 잘 활용해서 멋진 프론트엔드 개발자가 되어보겠습니다!

이제 테스트코드 넌 내 단짝이야~

추가로 다음은 TodoList + Jest + ReactTestingLibrary 를 이용한 실제 코드를 가져오겠습니다.

profile
웹과 앱을 사랑하는 남자

0개의 댓글