개발 관련 일지/TDD

좋은 단위 테스트의 4대 요소

worldi 2024. 2. 12. 03:38

페어프로그래밍을 하면서 거짓 양성, 블랙 박스, 화이트 박스… 같은 용어들이 생소했다.

그래서 단위 테스트 책을 읽으면서 해당 관련 지식을 보충하게 되었다! 단위 테스트 책 4단원에 해당 지식이 나온다.

좋은 단위 테스트의 4가지 특성

  • 회귀 방지
  • 리팩터링 내성
  • 빠른 피드백
  • 유지 보수성

회귀 방지

회귀 = 소프트웨어 버그로, 코드 수정 후 기능이 의도한 대로 동작하지 않는 경우이다.

회귀 방지는 테스트가 얼마나 버그의 존재를 잘 나타낼 수 있는지 척도를 말한다.

회귀에는 다음과 같은 요소들이 영향을 미친다.

  • 테스트 중에 실행되는 코드의 양
    • 실행되는 코드가 많을 수록 회귀가 나타날 가능성 많다.
  • 코드 복잡도,코드 도메인 유의성
    • 복잡한 비즈니스 로직이 보일러 플레이트 코드보다 중요하다.

리팩터링 내성

테스트를 빨간색으로 바꾸지 않고, 기본 애플리케이션 코드를 리팩터링 할 수 있는지에 대한 척도이다.

거짓 양성

기능은 의도한 대로 작동하지만, 테스트는 실패를 나타낸다. 구현을 수정하지만, 식별할 수 있는 동작을 유지할 때 거짓 양성이 나타난다고 한다. 이는, 전체 테스트 스위트에 치명적인 영향을 줄 수 있다.

  • 거짓 양성의 원인?

테스트와 sut의 구현 세부 사항이 많이 결합할 수록 허위 경보가 많이 생긴다. 즉 sut의 특정 구현 (결과 전달을 위해 sut가 수행해야 할 특정 단계)를 예상하므로 깨지기 쉽다. → sut의 구현을 리팩터링하면, 모두 테스트 실패로 이어진다.

즉, 테스트를 깨지지 않고, 리팩터링 내성을 높이는 방법은 SUT 의 구현 세부 사항과 테스트 간의 결합도를 낮추는 것이다. 즉, sut를 블랙박스 취급하고, sut가 만든 최종 결과를 검증해야 한다.

 

두가지 특성(회귀 방지, 리팩터링 내성)의 본질적 관계

프로젝트가 시작된 직후에는 회귀 방지를 지키는 것이 중요하지만, 리팩터링 내성은 바로 필요하지 않다.

  • 기능 작동→ 테스트 통과, 기능 실패 → 테스트 실패는 자연스러운 추론이다.
  • 하지만, 기능이 고장났는데 테스트를 통과하면 문제가 된다. → 거짓음성이다. → 회귀 방지가 훌륭하면, 거짓 음성을 최소화 할 수 있다.
  • 기능이 올바른데, 테스트가 실패하면 → 거짓 양성이다. → 리팩터링 내성이 높으면, 도움이 된다.

테스트의 정확도는 다음과 같이 정의 내릴 수 있다.

 

테스트 정확도 = 신호 (발견된 버그 수)/ 소음 (허위 경보 발생 수)

 

가능한 소음이 적고, 버그를 잘 찾아 내면 테스트가 명확해 진다.

초기에는 리팩터링이 중요하지 않고, 시간이 지나면서 점차 중요해진다. 따라서 코드 정리를 많이 할 필요가 없다.

하지만 시간이 흐를 수록 코드베이스가 나빠진다. 리팩터링이 점점 더 필요해짐에 따라 테스트에서 리팩터링 내성도 점점 더 중요해진다. 따라서, 프로젝트가 커질 수록 거짓 음성(알려지지 않은 버그)와 거짓 양성 (허위 경보)에 똑같이 주의를 기울여야 한다.

빠른 피드백과 유지보수성

테스트 속도가 빠를 수록, 더 많은 테스트를 수행할 수 있고, 실행할 수 있다.

유지 보수성은 다음과 같이 두 가지 요소로 구성된다.

  • 테스트가 얼마나 이해하기 어려운가 : 테스트 코드 라인과 품질
  • 테스트가 얼마나 실행하기 어려운가 : 의존성 문제

좋은 단위 테스트

좋은 단위 테스트 = 회귀 방지 * 리팩터링 내성 * 빠른 피드백 * 유지보수성

블랙 박스 테스트와 화이트 박스 테스트 간의 선택

  • 블랙 박스 테스트
    • 시스템 내부 구조를 몰라도 시스템의 기능을 검사할 수 있는 소프트웨어 테스트 방법. 무엇을 해야 하는 지를 중심으로 구축된다.
    • 회귀 방지에는 나쁘지만, 리팩터링 내성에는 좋다.
  • 화이트 박스 테스트
    • 내부 작업을 검증하는 테스트 방식이며, 테스트의 요구사항이나 명세가 아닌 소스코드에서 파생된다.
    • 리팩터링 내성에는 나쁘지만, 회귀 방지에는 좋다. (외부 명세에만 의존할 때 놓칠 수 있는 오류를 발견할 수 있다. 특정 구현과 결합 되어 있어 깨지기 쉽다.)

하지만, 리팩터링 내성은 타협할 수 없으므로, 블랙 박스 테스트를 기본으로 선택해라.

시스템을 블랙박스로 보고, 의미 있는 동작을 확인해라.
그리고 테스트를 분석할 때 화이트 박스 방법을 사용해라!

 

'개발 관련 일지 > TDD' 카테고리의 다른 글

테스트 더블이란 무엇인가  (1) 2024.02.12