ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TDD를 해보자
    프론트엔드 2023. 2. 7. 09:00
    728x90
    반응형
    SMALL

    이번 포스팅은 필자가 생각하는 TDD를 하는 과정에 대해서 포스팅해보려고 합니다.

    부족한 점이 많을 수 있다는 점 양해 부탁드립니다....

     

    TDD를 위해서 필요한 것

    1. 관심사의 분리

    관심사의 분리란?

    관심사의 분리란 간략하게 설명하자면 한 파일이 하나의 역할만 하도록 해주는 것입니다.

    React를 예시로 들자면, View역할을 하는 .tsx파일은 View의 역할만 하도록 하고, View 파일에서 사용하는 동기, 비동기 로직은 util파일이나 logic.ts파일로 나누어서 View에서는 선언만 해서 사용하도록 해줍니다.

    관심사의 분리가 필요한 이유

    개발을 하게 될 경우 View파일 내부에 필요한 로직까지 모두 선언 및 사용하는 경우가 많습니다.

    이럴 경우 한 파일의 코드안에 view, 동기 비동기 로직이 합쳐져 대량으로 불어날 수 있습니다.

    다음은 view와 logic 관련 코드가 같이 있을 경우의 문제점입니다.

    • 코드 가독성이 나빠집니다.
    • 리팩토링이 어렵게 됩니다. (한 파일 내부에 모든 것을 포함하고 있으니, 의존성이 있는 컴포넌트를 옮긴다거나 할 경우, 문제가 될 수 있습니다.)
    • TDD를 할 경우, 무엇을 테스트해야 될지 잘 모르게 됩니다. (모든 컴포넌트가 한 뭉텅이가 되므로, 이 컴포넌트를 테스트하는 방법 밖에 없게 됩니다.)

    2. MSW

    MSW란?

    Mock Service Worker의 약자로, 비동기 데이터 패칭이 필요할 경우 네트워크 단에서 실제 백엔드 API와 통신하는 것처럼 데이터를 제공해주는 API 모킹 라이브러리입니다.

    MSW가 필요한 이유

    단위 테스트에 대한 코드 작성을 할 경우 비동기 코드와 같은 경우 목업 함수로 대체한 다음 패칭된 데이터의 결과값을 미리 선언해두고 테스트코드를 작성할 수 있습니다.

    const axios = require("axios");
    const userService = require("./userService");
    
    jest.mock('axios');
    
    test('axios get 테스트',()=>{
    	axios.get.mockResolvedValue({
    		data: {
    			id:1,
    			name:'beomseok'
    		}
    	});
    
    	const user = await userService.findOne(1);
    
    	expect(user).toHaveProperty('id',1);
    	expect(user).toHaveProperty('name','beomseok');
    
    	expect(axios.get).toBeCalledTimes(1);
    	expect(axios.get).toBeCalledWith('<https://beomseok.dev.api/user>');
    });
    

    하지만, 위와 같은 방식으로는 여러 api 요청이 동시에 일어날 수 있는 통합 테스트나 E2E 테스트에서 패칭된 데이터에 따른 UI의 변경이 옳바르게 되고 있는지 확인할 수 없습니다.

     

    그러므로, MSW를 도입해 실제 유저 이벤트를 동반한 api 요청이 있을 경우에 대한 코드를 미리 작성해두면 개발 단계에서 이미 backend api가 실제 있는 것처럼 개발을 진행할 수 있습니다.

    또한, MSW가 없이 백엔드의 api를 그대로 이용할 경우 네트워크가 지원되지 않은 곳에서 개발을 하거나 백엔드 서버가 켜져있지 않다면, api를 이용한 테스트는 모두 실패하게 될 것입니다.

    이를 방지하기 위해서도, MSW를 사용해보는 것이 좋습니다.

     

    개발 순서

    1. 테스트 시나리오를 작성합니다.
    2. 테스트 시나리오를 기반으로 테스트 코드를 작성합니다. (실제 테스트 코드, MSW)
    3. 우선적으로 테스트가 성공하도록 코드를 구현합니다.
    4. 테스트가 성공하는 선에서 리팩토링 과정을 거칩니다.

    위의 과정은 여러 다른 TDD 방법론에서 소개 된 것과 동일합니다(Red, Green, Refactor)

     

    결과

    1. 우선, 무엇을 테스트할지 선정하고 시나리오를 작성해봅니다.

     

    2. 테스트할 대상에 대한 테스트 코드를 작성해줍니다. 테스트 대상에 비동기 요청이 있다면, MSW를 이용해 api 요청 관련 코드를 미리 작성해줍니다.

    테스트 코드 작성 시 테스트의 대상이 되는 util 함수나 컴포넌트를 미리 선언만 하고 테스트 코드에 넣어 사용합니다. (이럴 경우 내부 실제 코드는 아직 구현되지 않은 껍데기 상태이므로 당연히 테스트는 실패합니다).

     

    3. 가장 간단한 방법으로 테스트를 통과하도록 한 뒤, 리팩토링 과정을 통해 유연하고 가독성 좋은 코드로 바꿔주면 됩니다!

    (관심사의 분리를 어떻게 하느냐에 따라 테스트의 용이성이 바뀌게 될 것이므로, 최대한 하나의 책임만 질 수 있도록 코드를 잘 분리해줍니다.)

    반응형
    LIST

    댓글

Designed by Tistory.