[ 박우빈 Practical Testing #3 ] 더 나은 테스트를 작성하기 위한 Tip (2)

김수호·2024년 6월 19일
0
post-thumbnail

① 한 문단에 한 주제
② 완벽하게 제어하기
③ 테스트 환경의 독립성을 보장하자.
④ 테스트 간 독립성을 보장하자.

⑤ 한 눈에 들어오는 Test Fixture 구성하기
⑥ Test Fixture 클렌징
⑦ 테스트 수행도 비용이다. 환경 통합하기
⑧ private 메서드의 테스트
⑨ 테스트에서 필요한 메서드가 생겼는데 프로덕션 코드에서는 필요 없는 경우


② 완벽하게 제어하기

  • 테스트를 하기 위한 환경을 조성할 때, 모든 조건을 완벽하게 제어할 수 있어야 한다. 제어할 수 없는 영역은 테스트 가능한 구조로 만드는 게 좋다.
    • given 절에서 데이터를 만들 때, (수행할 때 마다 or 수행되는 환경이 달라질 때 마다) 테스트 결과가 달라질 수 있는 LocalDateTime.now() 와 같은 것은 되도록 사용을 지양하자.
      • 현재시간에 대한 것을 LocalDateTime.now() 와 같이 사용하기 보다는, 고정된 날짜와 고정된 시간, 고정된 값 등으로 넣어주는게 좋다. (제어할 수 없는 값들을 제어할 수 있는 값으로 만들자.)
      • LocalDateTime.now() 으로 아무생각 없이 쓰기 시작하면 모든 사람들 또한 같이 쓰기 시작하면서 프로젝트 내에서 번지게 된다.
      • LocalDateTime.now() 같이 현재시간이라는 제어할 수 없는 변수를 사용했을 때, 나중에 변경사항이 생기는 경우, 문제를 일으킬 수 있다. ( 수행되는 환경에 따라 시간이 달라져서 문제가 발생한다던지 등 )
    • 제어할 수 없는 환경(외부 시스템과 연동하는) 부분같은 경우, Mocking 처리하자.

 

③ 테스트 환경의 독립성을 보장하자.

  • given 절을 조성할 때 최대한 독립성을 보장하도록 구성하자.
    • 1) 논리적 사고를 요구하는 구문을 지양하자.
      • stock1.deductQuantity(3); 에서 내부 로직을 파악하고 맥락을 이해해야만 하는 허들이 생긴다.
      • 추가적으로 만약, deductQuantity() 내부에서 뭔가 로직이 있어서, 예외를 발생시키는 구문이 있다고 가정해보자. 그러면 테스트에서 when/then 절에서 테스트가 실패하는게 아니라, given 절에서 테스트에 실패하게 된다. 즉, 테스트 주제와 맞지않는 부분에서 테스트가 실패하는 것이다. ( 이렇게 되면, 만약 단순한 테스트 케이스가 아닌 복잡한 테스트 상황에서 테스트가 실패한 경우, 이게 왜 실패했는지 유추하기 어렵게 만드는 포인트가 될 수 있다. )
    • 2) 팩토리 메서드를 사용해서 자원을 구성하는 것은 지양하자. ( 테스트 환경을 조성할 때, 생성자나 순수 builder를 기반으로 구성하는 게 좋다. )
      • 팩토리 메서드는 사실 어떤 의도를 가지고 만들어진 메서드라고 볼 수있다. 생성자 등으로 만들어도 되는데 굳이 팩토리 메서드로 만들었다는 얘기는, 팩토리 메서드 내에서 뭔가 해당 용도에 맞는 검증을 하고싶다거나 하는 목적이 들어간 생성인 경우가 많다. 따라서 테스트에서 팩토리 메서드는 지양하는 것이 좋다.
    • 결론) 테스트 환경을 구성할 때는 최대한 독립적으로, 독립성을 보장해서 구성하는 게 좋다.

 

④ 테스트 간 독립성을 보장하자.

  • 이전 테스트의 실행이 다른 테스트에 영향을 주지 않도록 구성하자.
    • 두 가지 이상의 테스트가 하나의 공유 자원을 사용하게 되면, 테스트간 순서가 중요하게 될 수있다. 따라서 공유 자원에 대한 것은 사용을 지양하는게 좋다.
      • 참고) 테스트 실행시 테스트의 실행 순서는 보장되지 않는다.
    • 그런데 만약 하나의 객체가 변화하는 모습을 차례대로 테스트해야하는데, 그게 하나의 테스트 안에서만 작성하기에 너무 많은 경우라면 어떻게 할까? @DynamicTest 를 사용하면 된다.
  • 테스트는 서로 순서에 영향받지 않아야 한다.
    • "A테스트가 수행된 이후에 B테스트가 수행되어야 성공한다." 라는 개념 자체가 없어야 한다.
    • 각각 독립적으로 언제 수행되든 항상 같은 결과를 내야 하는게 올바른 테스트 코드이다.

 

✔️ 참고 - @DynamicTest ( 상태 공유가 필요한 일련의 단계적 시나리오 작성이 필요한 경우 )

  • 어떤 하나의 공유 환경을 구성해두고, 이 환경에 변화를 주면서 사용자 시나리오를 단계별로 테스트하고 싶은 경우에 사용한다.

강의를 듣고 정리한 글입니다. 코드와 그림 등의 출처는 박우빈 강사님께 있습니다.

profile
현실에서 한 발자국

0개의 댓글