프로그래밍 공부

[TDD] 테스트 코드 작성 순서와 종류

레벨 2가 되고 Spring을 사용하다 보니 TDD에 대한 부분이 다소 무너지는 것 같아서 테스트 주도 개발 시작하기 (최범균 저)의 내용을 간단하게 정리하여 이야기해보고자 한다.

 

테스트 코드 작성 순서

  • 쉬운 경우에서 어려운 경우로 진행
  • 예외적인 경우에서 정상인 경우로 진행

초반에 복잡한 테스트부터 시작하면 안 되는 이유

초반부터 다양한 조합을 검사해야 하는 코드를 만들게 되면, 해당 테스트를 통과시키기 위한 코드가 많아진다. 한 번에 완벽한 코드를 짤 수는 없기 때문에 작성하기 쉬운 코드를 작성하는 것이 개발 속도에 많은 도움이 된다고 한다. 

한 번에 구현하는 시간이 짧아지면 디버깅할 때 유리하고, 원인을 찾기도 더 빠르다. 

 

예외상황을 먼저 테스트해야 되는 이유

예외상황은 복잡한 if 블록을 동반할 때가 많다. 예외 상황을 전혀 고려하지 않은 코드에 예외상황을 반영한다면 중간에 코드를 뒤집는 등의 문제가 발생할 수 있다. 이는 코드를 복잡하게 만들 가능 성이 있다.

 

하지만, 초반에 예외 상황을 테스트하게 되면 먼저 예외상황에 대한 처리를 할 수 있어서 코드 구조의 변화가 크지 않도록 도와줄 수 있다.

 

또한, 예외상황을 발견한 이후에 테스트에 반영한다면 프로그램 실행 중에 심각한 오류가 발생할 가능성이 있으나, 미리 예외상황을 정의하고 그에 따라서 테스트 코드를 작성하면 많은 도움이 될 수 있다. 

 

 

테스트 범위와 종류

테스트 범위

일반적인 웹 어플리케이션은 아래와 같은 구조를 갖는다. 

웹 어플리케이션의 구조

이러한 구조를 기반으로 테스트 범위에 따른 테스트의 종류를 정리해보면 다음과 같은 이미지가 된다.

이렇게 적힌 테스트의 용어는 종종 다르게 적혀있기도 한데, 테스트 관련 용어가 문맥이나 사용자에 따라 다양하게 사용되기 때문이다. 개발 완료 후에 진행되는 최종 테스트를 '통합 테스트'라고 부르기도 하고, 고객의 입장에서 요구한 기능을 올바르게 수행했는지 수행하는 테스트를 '인수 테스트'라고 부르나, 요건을 완료했는지 정의하기 위한 테스트를 '인수 테스트'라고 부르기도 한다. 용어 하나하나의 글자에 집중하기보다는 관련된 개념을 정확히 아는 것이 더 중요할 것 같다.

 

테스트 종류

기능테스트와 E2E 테스트

사용자 입장에서 시스템이 제공하는 기능이 올바르게 동작하는지 확인. (= 인수 테스트)
  • 비즈니스 쪽에 초점을 둔다 → 누가, 어떤 목적으로, 무엇을 하는가
  • 모든 구성요소를 하나로 엮어서 사용자의 관점에서 테스트한다.
    • 소프트웨어 내부 코드에 관심을 갖지 않는 블랙박스 테스트이다.
    • 끝에서 끝(End to End, E2E)까지 모든 구성요소가 올바른지 검사한다.
  • Java에서는 RestAssured, MockMvc 같은 도구를 활용하여 인수 테스트를 작성할 수 있다.
  • ex - 회원가입 기능이 올바르게 작동하는지 확인

통합 테스트

시스템의 각 구성요소가 올바르게 연동되는지 확인
  • 개발자가 변경할 수 없는 부분(ex. 외부 라이브러리)까지 묶어서 검증
  • DB 접근 등 전체 코드와 다양한 환경이 제대로 작동하는지 확인하는데 필요한 모든 작업 수행
  • 통합 테스트 수행 ≠ 응용 프로그램의 완전한 작동
    • 실제 환경에서 발생하는 버그까지는 확인할 수 없음
  • 스프링 부트에서는 클래스 상단에 @SpringBootTest 어노테이션을 붙여 통합 테스트를 수행할 수 있다.
  • ex - 서버의 회원가입 코드를 직접 테스트

단위 테스트

개별 코드나 컴포넌트가 기대한 대로 동작하는지 확인
  • 클래스 or 메서드 수준으로 대상 단위를 작게 설정해 테스트를 생성
  • 내부 코드에 대한 지식을 반드시 알고 있어야 하는 화이트박스 테스트
  • Java는 주로 JUnit으로 테스트한다.

테스트 범위에 따른 테스트 코드 개수와 시간

  • 테스트의 제약 수준 : 기능 테스트 > 통합 테스트 > 단위 테스트
  • 테스트 실행 시간 : 기능 테스트 > 통합 테스트 > 단위 테스트

더 작은 단위를 대상으로 테스트 코드를 만들고 다양한 상황을 다루기에 통합 테스트보다 단위 테스트 코드를 많이 작성하게 된다.

 

물론 이러한 코드를 기능 테스트나 통합 테스트에서 진행할 수 있으나, 테스트 속도는 통합 테스트보다 단위 테스트가 더 빠르기에 단위 테스트에서 다양한 상황을 다루고, 통합 테스트나 기능 테스트는 주요 상황에 초점을 맞춰야 한다. 테스트가 느려진다는 것은 결국 피드백이 느려지고, 개발 속도를 늦어지게 하는 원인이 될 수 있기 때문이다.

 

 

'프로그래밍 공부' 카테고리의 다른 글

무중단 배포란?  (0) 2022.09.27
VPC란 무엇인가?  (2) 2022.09.20
도메인이란 무엇인가?  (1) 2022.05.15
[TDD] Test-Driven-Development란 무엇인가  (0) 2022.02.24
[React / Spring] CORS 이슈 해결하기  (0) 2021.07.27