상세 컨텐츠

본문 제목

실용주의 단위 테스트. 4장. 테스트 조직.

TIL/실용주의 단위 테스트

by box-jeon 2019. 11. 6. 06:03

본문

테스트 코드를 잘 조직하고 구조화할 수 있는 JUnit 기능을 소개합니다.

AAA로 테스트 일관성 유지

AAA를 사용하여 테스트를 가시적이고 일관성 있게 작성합니다.

 

  • 준비(Arrange): 테스트 코드를 실행하기 전에 시스템이 적절한 상태에 있는지 확인합니다.
  • 실행(Act): 테스트 코드를 실행합니다.
  • 단언(Assert): 실행한 코드가 기대대로 동작하는지 확인합니다.

동작 테스트 vs 메서드 테스트

테스트를 작성할 때는 클래스 동작에 집중해야지 개별 메서드를 테스트한다고 생각하면 안 됩니다. 테스트의 대상이 될만한 흥미로운 동작을 찾아야한다고 말합니다.

 

* 사실 그 부분이 가장 어려운 부분...

테스트와 프로덕션 코드의 관계

테스트 코드는 프로덕션 시스템 코드에 의존하지만, 그 반대는 해당하지 않습니다. 프로덕션 코드는 테스트 코드의 존재를 모릅니다. 다만 단위 테스트 작성이 용이해질 수 있도록, 프로덕션 코드를 테스트 친화적으로 설계하는 것은 가능합니다.

프로젝트 내에서 실제로 파일들을 어떻게 관리할 것인지에 대해서는 몇 가지 선택지가 있습니다. 하지만 요즘은 IDE가 대부분 알아서 2번 방식으로 설정해 줍니다.

 

  1. 테스트를 프로덕션 코드와 같은 디렉터리 및 패키지에 넣기: 소오름
  2. 테스트를 별도 디렉터리로 분리하지만 프로덕션 코드와 같은 패키지에 넣기: 테스트 코드가 패키지 수준의 접근 권한을 갖습니다.
  3. 테스트를 별도의 디렉터리와 유사한 패키지에 유지하기: 공개 인터페이스만 활용하여 테스트 코드를 작성하게 됩니다.

어떤 개발자들은 테스트를 작성할 때 프로덕션 코드의 공개 인터페이스만 사용해야한다고 믿습니다. 테스트가 비공개 인터페이스를 호출할 수록, 테스트는 구현 세부 사항과 결속하게 됩니다. 그러한 세부 사항이 변경되면, 공개 인터페이스에 변경이 없다 하더라도 테스트가 깨질 수 있습니다. 테스트가 프로덕션 코드와 같은 패키지에 있으면 그 클래스에 대해 패키지 수준의 접근이 가능해집니다. 하지만 내부 행위를 테스트하려는 충동이 든다면 설계에 문제가 있는 것입니다. 테스트하고자 했던 내부 행위를 클래스로 추출하여 공개 인터페이스로 전환하는 것이 좋습니다.

 

* 패키지 수준의 접근도 하지 않는 것이 좋다는 건 좀 지나치다는 생각이 듭니다만... Xcode로 단위테스트를 작성하는 경우 @testable import를 통해 패키지 수준의 접근을 허용하게 되는데, 가능한한 @testable 없이 테스트를 작성할 수 있도록 노력해봐야겠습니다.

집중적인 단일 목적 테스트의 가치

테스트 하나가 하나의 검증 목적을 가질 수 있도록 분리해야합니다. 테스트 결과를 확인했을 때, 빠르게 상황을 파악할 수 있게 해줍니다.

문서로서의 테스트

테스트 이름을 멋지고 설명적으로 지어야 합니다. 어느 형식을 따르든 일관성이 중요합니다.

 

  • doingSomeOperationGeneratesSomeResult
  • someResultOccursUnderSomeCondition
  • givenSomeContextWhenDoingSomeBehaviorThenSomeResultOccurs
  • whenDoingSomeBehaviorThenSomeResultOccurs

@Before와 @After 더 알기

각각의 테스트 실행 전/후에 수행해야하는 공통적인 동작이 있다면 @Before와 @After 애너테이션을 사용할 수 있습니다. JUnit은 각각의 테스트 케이스마다 객체를 생성하며, 테스트 실행 순서를 보장하지 않는 다는 것을 염두에 두어야 합니다.

녹색이 좋다: 테스트를 의미 있게 유지

테스트를 항상 빠르게 유지하는 것이 좋습니다. 필요에 따라 일부만 테스트할 수도 있지만, 가능한한 많은 테스트를 실행해야 합니다.

 

관련글 더보기

댓글 영역