테스트(Test)
소프트웨어 테스트는 다양한 테스트 들이 있다.
화이트박스 테스트, 블랙박스 테스트, 단위테스트, 통합테스트, 시스템 테스트, 인수 테스트 등
TDD(Test Driven Development) 를 공부하기 전, 단위테스트, 통합테스트, 인수테스트에 대해 개념을 정리하려 한다.
단위테스트(Unit Test)
단위테스트는 응용 프로그램에서 하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트이다.
테스트가 가능한 가장 작은 소프트웨어나 기능을 실행하여 예상대로 동작하는지 확인하는 테스트이다.
- 단위 테스트에서 테스트 대상 단위의 크기는 엄격하게 정해져 있지 않다.
- 하지만 일반적으로 클래스 또는 메서드 수준으로 정해진다.
- 단위의 크기가 작을수록 단위의 복잡성이 낮아진다.
- 여기서 모듈은 애플리케이션에서 작동하는 하나의 기능 또는 하나의 메서드로 이해할 수 있다.
- 즉, 단위 테스트는 애플리케이션을 구성하는 하나의 기능이 올바르게 동작하는지를
독립적으로
테스트하는 것으다. - 만약 테스트에 네트워크나 데이터베이스 같은 외부 리소스가 포함된다면 그것은 유닛 테스트가 아니다.
즉 작성한 가능한 모든 메서드들에 대해서 테스트 케이스를 작성하는것이다.
일반적으로 private 메서드는 테스트 하지 않는다.
public 메서드 내에서 private 메서드가 작동하기 때문이다.
단위 테스트를 작성할때는,
- 테스트 대상 단위의 크기를 작게 설정해서 단위 테스트를 최대한 간단하고 디버깅하기 쉽게 작성해야 한다.
- "어떤 기능이 실행되면 어떤 결과가 나온다" 정도로 테스트를 진행한다.
단위 테스트 작성의 필요성
일반적으로 통합 테스트는 실제 여러 컴포넌트들 간에 상호작용을 테스트 하기 때문에 모든 컴포넌트들이 구동된 상태에서 테스트 하게 된다.
- 여기서 컴포넌트들은 캐시, 데이터베이스, 다른 서버들을 의미
이 시스템을 구성하는 컴포넌트들이 많아질수록 테스트를 위한 비용(시간이) 상당히 커지는 단점이 있따.
반면에, 단위 테스트는 해당 부분만 독립적으로 테스트가 가능하기 때문에, 기능의 변경이나 코드의 변경에 있어 문제가 생겨도 빠르게 문제 여부를 확인할 수 있다.
요즘 많이 사용되는 TDD(Test Drive Development, 테스트 주도 개발)에서 얘기하는 테스트도 단위 테스트를 의미하며,
TDD에서 단위테스트는 꼭 작성해야 한다.
단위 테스트의 장점
단위 테스트를 진행하게 된다면 하나의 기능을 독립적으로 테스트하기 때문에,
코드의 변경으로 인해 문제가 발생하여도 테스트 케이스를 통과하지 못했을 경우 짧은 시간 안에 해당 문제를 파악할 수 있다.
- 새로운 기능 추가 시 수시로 빠르게 테스트 할 수 있다.
- 일반적으로 단위테스트는 실행이 빠르다.
- 리팩토링 시에 안정성을 확보할 수 있다.
- 어떠한 부분에 문제가 있고 고칠 부분이 어디인지 명확하게 알 수 있기 때문에.
- 코드에 대한 문서가 될 수 있다.
- 메서드 명이나, 다른 표시(ex @DisplayName)로 인해 어떤 기능이고 어떤것에 대한 내용인지 알 수 있기 때문에.
단위 테스트의 단점
일반적인 애플리케이션에서는 1개의 기능을 처리하기 위해 다른 객체들과 메세지를 주고받는다.
하지만 단위 테스트는 해당 모듈에 대한 독립적인 테스트 이기 때문에 다른 객체를 사용하여 메세지를 주고 받기가 힘들다.
그러면 어떻게 해결할까?
Stub, 스텁
단위 테스트는 독립적인 모듈에 대한 테스트이다.
만약 기능이 다른 객체를 필요로 한다면, 모듈은 독립적이기 때문에 사용하지 못한다
이 문제를 해결하기 위해서 다른 객체 대신에 가짜 객체(Mock Object)
를 주입하여 어떤 결과를 반환하라고 정해진 답변을 준비시킨다.
이를 Stub 이라고 한다.
- Mock : Unit Test를 할 모듈과 메시지를 주고받는 객체를 대신할 가짜 객체
- Stub: 실제 코드나 아직 준비되지 못한 코드를 호출하여 수행할 때 이용할 미리 준비해둔 결과를 제공하는 메커니즘
좋은 단위 테스트의 특징
일반적으로 요구사항을 계속 변하고, 그에 맞춰 우리의 코드 역시 변경되어야 한다.
하지만 실제 코드를 변경한다는 것은 코드의 변경에 따른 잠재적인 버그
가 발생할 수 있음을 내포한다.
하지만 좋은 테스트 코드
가 있다면 변경된 코드를 검증함으로써 이를 해결할 수 있다.
또한 실제 요구사항에 따른 코드가 변경되면서 테스트 코드 역시 변경이 필요할 수 있다.
이런 이유로 테스트 코드도 가독성 있게 작성할 필요가 있다.
그렇기에 테스트 코드를 작성하는 경우에 다음을 준수하는 것이 좋다.
- 1개의 테스트 함수에 대해서는 assert를 최소화 하라
- 1개의 테스트 함수는 1가지 개념만을 테스트 하라
좋고 깨끗한 코드는 F I R S T 라는 5가지 규칙을 따라야 한다
- Fast : 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다
- Independent: 각각의 테스트는 독립적이며, 서로
의존
해서는 안된다. - Repeatable : 테스트는 어느 환경에서도 반복적으로 실행할 수 있어야 한다
- Self-Validating : 테스트는 성공 또는 실패를 boolean 값으로 결과를 내어 자체적으로 검증 되어야 한다.
- Timly : 테스트는 적시에, 즉 테스트 하려는 실제 코드(기능)를 구현하기 직전에 구현해야 한다
자바에서는 JUnit을 이용하여 단위테스트를 할 수 있다.
통합 테스트 (Integration Test)
통합테스트는 단위 테스트보다 더 큰 동작을 달성하기 위해 여러 모듈들을 모아 이들이 의도대로 협력하는지 확인하는 테스트이다.
단위 테스트가 끝난 모듈을 통합하는 과정에서 발생할 수 있는 오류들을 찾는 테스트이다.
통합 테스트는 단위 테스트와 달리 개발자가 변경할 수 없는 부분들(ex) 외부 라이브러리) 까지 묶어 검증할 때 사용한다.
이는 DB에 접근하거나 전체 코드와, 다양한 환경이 제대로 작동하는지 확인하는데 필요한 모든 작업을 수행할 수 있다.
그러나 통합 테스트가 응용 프로그램이 완전하고 완벽하게 작동하는걸 무조건 증명하지는 않는다.
통합테스트의 장점
- 단위 테스트에서 발견하지 어려운 버그를 찾을 수 있다.
- 예를 들어, 환경 버그(멀티쓰레드, 싱글코어 CPU, 멀티코어 CPU 에서는 잘 실행되지 않는 버그들)가 발생할 수가 있다.
- 추상화된 인터페이스와 관련된 오류를 감지할 수 있다.
통합테스트의 단점
- 단위 테스트보다 더 많은 코드를 테스트 하기 때문에 신뢰성이 떨어질 수 있다.
- 어디서 에러가 발생했는지 확인하기가 쉽지 않다
- 단위 테스트는 통과했는데 통합 테스트에서는 버그가 생기면 하나하나 다시 찾아봐야 한다.
통합 테스트 방법
1. 하향식 테스트 (Top-Down)
- 가장 상부의 모듈부터 통합하며 테스트를 순차적으로 아래 방향으로 진행한다
- 하향식 테스트를 위해 테스트 스텁(Test Stub)을 이용하여 진행한다.
- 설계상의 결함을 빨리 발견할 수 있으며 수정이 어려운 중요한 결함을 하부 구조에서 발견할 수 있다.
2. 상향식 테스트 (Bottom-Up)
- 최 하위 모듈을 통합 후 상부의 모듈을 순차적으로 위 방향으로 진행한다
- 상향식 테스트를 위해 테스트 드라이버(Test Driver)로 진행한다.
- 하위 모듈을 충분히 테스트 후에 수행할 수 있고, 수정이 어려운 중요한 결함을 상부 구조에서 발견할 수 있다.
인수 테스트(Acceptance Test)
인수 테스트는 사용자 스토리(시나리오)에 맞춰서 수행하는 테스트이다.
요구사항이 충족되는지 확인하기 위해 비즈니스
측면에 초점을 둔 테스트이다.
요구사항이 만족하는지 확인하는 과정에서 스토리(시나리오)에 맞춰 테스트가 수행된다.
인수 테스트는 애자일 개발 방법론에서 파생했다
익스트림 프로그래밍(XP)에서 사용하는 용어이다.
요구사항(인수 조건)이 만족하는지 확인하는 과정에서 시나리오에 맞춰 테스트가 수행된다.
시나리오에서 요구하는 중점은 누가
, 어떤 목적으로
, 무엇을 하는가
이다.
이런 기능들은 API를 통해 드러나며, 인수 테스트 주로 이 API를 확인하는 방식으로 이뤄진다.
인수 테스트는 소프트웨어의 코드, 내부 구조, 구현 방법을 고려하기보다는 실제 사용자 관점에서 테스트하는 경우가 많다.
따라서 인수 테스트는 소프트웨어 내부 코드에 관심을 가지지 않는 블랙박스 테스트 라고 할 수 있다.
결국 요구사항이 잘 작동하는지 실제 사용자 관점에서 수행하는 테스트이다.
자바에서는 RestAssured, MockMvc 같은 도구를 사용하여 인수 테스트를 작성한다.
참조
'테스트' 카테고리의 다른 글
코드 커버리지(Code coverage) (0) | 2023.01.05 |
---|---|
Java Mockito Void method 테스트 (0) | 2022.11.18 |
Java Static Method Mocking Test - 자바 스태틱 메소드 테스트 (0) | 2022.11.18 |
Hamcrest (In Java JUnit5) (0) | 2022.11.13 |
무엇을 테스트 할것인가? 어떻게 테스트 할것인가 - 권용근님 (0) | 2022.11.10 |