https://s3-us-west-2.amazonaws.com/secure.notion-static.com/cc9e93a3-c8c0-4ecb-900b-a1653bdf09fa/Frame_16.png

프로젝트의 핵심적인 기능 개발을 마친 후 그다음으로 진행한 작업은 바로 테스트 코드 작성! 그 과정을 소개해드립니다 😊

바쁘신 분들을 위한 3줄 요약!

테스트 코드를 작성한 이유는 뭔가요?

추가적인 기능을 구현하거나 특정 부분을 리팩토링하면 서비스의 여러 부분이 영향을 받게 됩니다. 이때 발생하는 버그를 더 빠르게 찾고 이전에 구현한 기능들이 제대로 잘 동작하는지 확인하는 데 걸리는 시간을 줄이고자 테스트 코드를 작성했습니다.

무엇을 이용해서 테스트 하나요?

백엔드의 통합 테스트를 위해서 Jest를 사용하고 E2E 테스트를 위해서는 Cypress를 사용했습니다. 또한 저희는 Jest 를 단위 테스트가 아닌 통합테스트 에 사용했습니다. 저희 프로젝트에서 API 요청은 복잡한 데이터를 처리하는 비즈니스 로직 대신 단순히 db에서 값을 조회하고 수정해 클라이언트에게 전달하는 코드가 많았으므로 단위 테스트 대신 API가 잘 동작하는지 확인하는 통합 테스트를 진행했습니다.

백엔드 통합 테스트를 위한 준비 과정은 무엇이 있나요?

저희는 테스트를 위한 데이터베이스를 따로 두었습니다. 통합 테스트로 진행되다 보니 API 호출 시 실제 데이터에 변화가 생기게 되었습니다. 테스트로 인해서 배포된 서버가 직접적인 영향을 받으면 안 된다고 판단해서 별도의 데이터베이스를 두었습니다.

또한, seed를 직접 구현해서 데이터베이스를 매번 초기화시켰습니다. 테스트는 프로젝트에 기능이 추가되거나 수정될 때마다 돌리게 됩니다. 하지만 회원가입과 같이 고유한 정보로 데이터를 생성해야 하는 API들은 에러를 반환하게 되고 이를 해결하기 위해 데이터를 초기화했습니다.

Jest로 테스트 코드는 어떻게 작성하나요?

API 단위로 테스트 코드를 작성하고 올바른 결괏값이 반환되었는지, 변경 사항이 잘 적용되었는지를 확인했습니다. 예시로 설명하겠습니다.

실시간으로 뜨는 택시 호출 요청을 드라이버가 수락했을 때 실행되는 운행 시작 API를 아래와 같이 테스트했습니다. 오더의 아이디와 함께 해당 API를 실행합니다. 로직이 성공적으로 실행되었을 경우 success를 결괏값으로 반환하기 때문에 해당 값이 들어왔는지 확인합니다. 추가로 해당 오더를 직접 불러와서 상태가 올바르게 바뀌었는지 확인했습니다.

자세한 코드가 궁금하시다면 **여기❗️**를 클릭해주세요 😊

test('approvalOrder API 테스트', async () => {
    const {
      data: { approvalOrder },
    } = await mutate({
      mutation: APPROVAL_ORDER,
      variables: { orderId: waitingOrderId },
    });

    const {
      data: { getOrderById },
    } = await query({
      query: GET_ORDER_BY_ID,
      variables: { orderId: waitingOrderId },
    });

    expect(approvalOrder.result).toBe('success');

    expect(getOrderById.result).toBe('success');

    expect(getOrderById.order.status).toBe('approval');
  });

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/de9df617-e749-4150-9e03-a30cb107c88c/Untitled.png

Cypress로 테스트 코드는 어떻게 작성하나요?