이번 프로젝트를 진행하면서 테스트를 메인으로 해보자는 의견이 나와서 공부를 할 겸 궁금한 점도 있어서 정리해 본다.
테스트 코드를 수시로 작성하고 돌리면서 문제를 파악하는 것이 TDD(테스트 주도 개발)에서 얘기하는 테스트가 단위 테스트를 의미하는 것이었다...
테스트는 크게 단위 테스트(Unit Testing), 통합 테스트(Intergration Testing), 시스템 테스트(Ststem Testing), 인수 테스트(Acceptance Testing)로 나눌 수 있다.
하지만 개발자가 개발 단계에서 수행하는 테스트는 단위 테스트와 통합 테스트에 해당한다.
그럼 각각의 테스트가 어떤 역할을 하는지 간단하게 알아보고 개발자가 하는 테스트에 대해 자세히 알아보자.
- 단위 테스트
개별적인 코드 단위. 즉, 함수, 메서드 또는 모듈을 테스트하는 것이다. 이러한 테스트는 주로 개발자가 작성하며, 코드의 기능을 확인하고 예상치 못한 오류를 찾아내는 데 사용된다. 자동화된 단위 테스트 도구를 사용하여 코드 변경 사항이 기존 코드와 호환되는지 확인할 수 있다. - 통합 테스트
다양한 컴포넌트 또는 모듈이 함께 작동할 때 발생할 수 있는 문제를 식별하는 데 사용된다. 이것은 단위 테스트 이후에 진행되며, 각각 모듈이 상호 작용할 때 예상치 못한 동작을 검사한다. 코드의 통합을 확인하고 문제를 해결하는데 중요하다. - 시스템 테스트
소프트웨어의 전체 시스템 또는 애플리케이션을 테스트하는 단계로, 단위 및 통합 테스트 이후에 진행된다. 이 단계에서는 시스템이 기능적 및 비기능적 요구 사항을 충족시키는지 확인한다. - 인수 테스트
최종 사용자 또는 고객이 소프트웨어가 실제 사용환경에서 작동하는지 검증하는 단계이다. 일반적으로 사용자 또는 고객이 직접 수행하며, 소프트웨어가 승인될지 여부를 결정하는 중요한 단계이다.
단위 테스트와 통합 테스트
소프트웨어 개발은 오류를 최소화하고 코드의 신뢰성을 가지는 것에 중점을 둬야 한다. 따라서 테스트가 필수적이다.
일반적으로 테스트 코드를 작성한다고 하면 거의 단위 테스트를 의미한다.
하나의 모듈을 기준으로 독립적으로 진행되는 가장 작은 단위의 테스트이다.(회원가입, 로그인 등등)
1.1 단위 테스트의 중요성
- 버그 조기 발견: 단위 테스트를 통해 코드의 논리적 오류나 예외 상황을 조기에 발견할 수 있으므로 버그를 최소화할 수 있다.
- 코드 품질 향상: 단위 테스트는 코드의 예상 동작을 문서화하고 코드를 이해하기 쉽게 만든다.
- 빠르게 테스트 가능: 단위 별로 쪼개서 테스트하는 것이기 때문에 새로운 기능이 만들어지면 그에 대한 테스트도 빠르게 할 수 있다.
- 코드 자체가 문서화 가능: 테스트 코드를 작성함으로써 코드 자체가 문서화가 가능하다.
1.2 단위 테스트 작성 방법
- 단위 테스트 프레임 워크 선택(예: JUNIT, TestNG)
- 각함수 또는 메서드에 대한 테스트 케이스 작성
- 테스트 실행 및 결과 확인
- 버그 발견 시 수정하고 다시 테스트를 실행하여 버그 수정
2.1 통합 테스트의 중요성
- 모듈 간 호환성 확인: 다른 모듈이 함께 작동할 때 예상치 못한 문제를 발견하고 해결한다.
- 인터페이스 오류 감지: 모듈 간의 데이터 전달 및 통신 오류를 식별한다.
- 시스템 통합 검증: 전체 시스템이 예상대로 동작하는지 확인한다
2.2 통합 테스트 작성 방법
- 통합 테스트 시나리오 및 테스트 케이스 작성
- 다른 모듈 또는 컴포넌트와의 통합을 시뮬레이션하고 테스트 실행
- 예상한 결과와 실제 결과 비교하여 문제 식별 및 수정
단위 테스트에도 문제점이 있을까?
일반적인 애플리케이션에서는 1개의 기능을 처리하기 위해 다른 객체들과 메시지를 주고 받아야 한다.
하지만 단위 테스트는 해당 모듈에 대한 독립적인 테스트이기 때문에 다른 객체와 메세지를 주고받는 경우에 이에 어긋난다.
그렇기 때문에 다른 객체 대신 가짜 객체(Mock Object)를 주입하여 어떤 결과를 반환하라고 정해진 답변을 준비시켜야 하는데, 이를 stub이라고 한다. 예를 들어 데이터베이스에 새로운 데이터를 추가하는 코드를 테스트한다고 하면, 가짜 테이터(MocK data)를 주입하면 반드시 1을 반환하도록 해주는 것이 stub이다.
좋은 단위 테스트의 특징
일반적으로 요구 사항은 계속해서 변하고, 그에 맞춰 코드 역시 변경되어야 한다. 하지만 코드를 변경하면 버그가 발생할 수 있음을 내포하게 되는데, 좋은 테스트 코드가 있다면 변경된 코드를 검증함으로써 이를 해결할 수 있다.
따라서 실제 코드가 변경되면 테스트 코드 역시 변경되어야 하므로 테스트 코드 역시 가독성 있게 작성하면 좋다.
- 1개의 테스트 함수에 대해 assert를 최소화
- 1개의 테스트 함수는 1가지 개념 만을 테스트
또한 깨끗한 테스트 코드는 FIRST라는 5가지 규칙을 따라야 한다.
- Fast: 테스트는 빠르게 동작하여 자주 돌릴 수 있어야 한다.
- Independent: 각각의 테스트는 독립적이며 서로 의존해서는 안된다.
- Repeatable: 어느 환경에서도 반복 가능해야 한다.
- Self-Validating: 테스트는 성공 또는 실패로 bool 값으로 결과를 내어 자체적으로 검증되어야 한다.
- Timely: 테스트는 적시에 즉, 테스트하려는 실제 코드를 구현하기 직전에 구현해야 한다.
현재 프로젝트를 진행하면서 내가 사용하는 Java, Spring에서는 어떤 식으로 테스트 코드를 하는지, 어떤식으로 작성했는지를 포스팅해야겠다.
참고 블로그:
망나니 개발자
'Spring' 카테고리의 다른 글
[Spring] java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not available via reflection. (0) | 2024.02.06 |
---|---|
[Spring] JUnit을 이용한 단위 테스트, 통합 테스트 (0) | 2023.09.20 |
DDD(Domain Driven Desgin) (0) | 2023.07.25 |
프로젝트 패키지 구조는 어떻게 나누는게 좋을까 (0) | 2023.07.14 |
[Spring] 왜 Service 와 ServiceImpl로 나누는걸까 (0) | 2023.06.28 |