회고 & 생각

유닛 테스트에 대해

안모 2023. 9. 26. 21:29

개요

jest를 이용해서 테스트를 구축하고 있다. e2e테스트는 어떻게든 만들고 더 발전시킬 여지가 보이는데 단위 테스트는 갈피 잡기가 애매하다.

단위 테스트는 간단하고 가볍고 즉각적이여야 한다. 처음에는 커버리지 100을 목표로 하면 좋은 테스트 코드를 작성할 수 있지 않을까? 하는 기대가 있었다. 하지만 테스트 코드에 대해 계속 알아보고 좋은 테스트 방식을 찾다 보니 무작정 커버리지 100을 목표로 하는 것은 올바른 방향이 아닌듯 하다.

어떤 방식으로 단위 테스트를 작성해야 할까?

일단 함수의 결과값 반환에 초점을 맞춰서 작성하려 한다. 내게 있어 단위 테스트는 함수가 제대로 작동했는지 검증한다는 인식이 있다.

단위 테스트에 대해 찾아보면 '테스트 가능한 가장 작은 소프트웨어를 실행하여 예상대로 동작하는지 확인하는 테스트'라는 말이 있으니 아주 틀린 말은 아니겠지만, 제대로 개념을 잡고 제대로된 방법론을 가지고 테스트를 만들고 싶다.

stub은 뭐고, mock은 뭐고, spy는 뭔가?

  • Stub
    • 가짜 객체를 이용해 실제로 동작하는 것처럼 보이게 하는 객체
    • 해당 인터페이스나 클래스를 최소한으로 구현하여 요청에 대해 미리 준비해둔 답변을 응답
    • 협력 객체의 특정 부분이 테스트하기 어려운 경우 stub을 사용하여 테스트 할 수 있다
    • 상태 검증 진행
  • Mock: 사전에 정의된 명세서대로의 결과를 돌려주도록 미리 프로그래밍 되어 있다.
    • 호출에 대한 기대를 명세하고, 내용에 따라 동작하도록 프로그래밍 된 객체
    • 테스트 작성을 위한 환경 구축이 어려울 때, 테스트하고자 하는 코드와 엮인 객체들을 대신하기 위해 만들어진 객체
    • 행위 검증 진행
  • Spy: 어떻게 호출되었는지 일부 정보를 기록하는 스텁이다.

상태검증과 행위검증

  • 상태검증: 메서드가 수행된 후, 객체의 상태를 확인하여 올바르게 동작했는지 확인한다
  • 행위검증: 메서드의 리턴 값으로 판단할 수 없는 경우, 특정 동작을 수행하는지 확인한다

정리자면 stub은 상태를 검증하여 최종 결과가 올바른지 테스트하고, mock은 행동을 검증하여 올바른 호출을 하는가 테스트한다.
둘 중 어떤 방식으로 테스트 할지는 context를 고려해야 한다.
spy는 실제로 작동하는 코드를 '보는' 것이다. 실제 코드를 확인하여 몇 번 호출되었고, 어떤 인자를 받았는지 검증할 수 있다. 스파이를 사용하면 메서드가 스텁되지 않은 경우 실제 메서드가 호출되기 때문에 신중하게 사용되어야 한다.

그래서 무엇을 이용할 것인가?

일반적으로 상태검증이 더 좋은 경우가 많다고 한다. stub방식을 이용하여 함수를 격리시켜서 테스트하는 방법을 쓰려고 한다. 테스트에 관한 이미지 중 함수를 여러개의 스텁이 둘러싸 함수를 격리하여 테스트하는 그림이 종종 보이는 만큼 이 방법이 접근하며 감을 잡기 좋을 것 같다.