TDD
TDD에 대한 설명은 아래 포스팅을 참고해주세요!
https://annovation.tistory.com/23
TDD (Test-Driven Development) feat. JUNIT
TDD TDD(Test-Driven Development는 테스트 주도 개발이라는 소프트웨어 개발 방법론입니다. 개발을 시작하기 전에 테스트를 먼저 작성하고, 그 테스트를 통과하도록 최소한의 코드를 작성한 뒤 점진
annovation.tistory.com
단위 테스트 (Unit Test)
단위 테스트는 프로그램의 가장 작은 단위(주로 함수나 메서드)를 독립적으로 테스트하여, 해당 단위가 올바르게 동작하는지 확인하는 소프트웨어 테스트 방식입니다.
* 목적
- 코드를 작성한 의도대로 작동하는지 검증
- 코드 변경이 다른 부분에 영향을 미치지 않도록 보장
- 버그를 조기에 발견하여 개발 속도와 코드 품질을 높임
* 특징
- 작은 범위
- 클래스, 메서드, 함수 등 프로그램의 작은 단위를 대상으로 테스트
- 외부 의존성(DB, 네트워크 등)을 최소화
- 독립적
- 각 테스트는 다른 테스트와 독립적으로 수행
- 테스트 간 상호작용이 없도록 설계
- 자동화 가능
- 테스트를 코드로 작성하여 자주 실행할 수 있음
- CI/CD 환경에서 지속적으로 테스트 가능
- 빠른 실행
- 코드의 작은 부분만 테스트하므로 실행 속도가 빠름
JUNIT을 활용한 TDD 개발 방식
1. src package 아래 test package에 있는 초록색 java package에 class를 만들어주면 test class 생성이 가능합니다.
2. Input, Output 자동화가 필요한 경우 (대강 작동 원리만 이해하고 넘어가도 괜찮다!)
public static String run(String input) {
input = input.stripIndent().trim() + "\n종료"; // 입력 문자열 끝에 "종료" 명령 추가
Scanner scanner = TestUtil.getScanner(input); // 문자열을 Scanner로 변환
ByteArrayOutputStream outputStream = TestUtil.setOutToByteArray(); // 출력 캡처 시작
App app = new App(scanner); // 입력 Scanner를 사용하여 App 인스턴스 생성
app.run(); // 프로그램 실행
String output = outputStream.toString(); // 캡처된 출력 내용을 문자열로 변환
TestUtil.clearSetOutToByteArray(outputStream); // System.out을 복구
return output; // 캡처된 출력 내용을 반환
}
3. test package에 구현하고자 하는 코드를 작성하기 전, 테스트 코드를 먼저 작성합니다. (Red)
- 작업 위치 : 테스트 클래스(보통 src/test/java 디렉토리)
- 테스트 코드 위에 @Test 어노테이션을 붙여줍니다.
- 필요에 따라 @DisplayName("코드에 대한 설명")을 덧붙여줍니다.
public class WiseSayingControllerTest {
@Test
@DisplayName("등록을 입력하면 내용과 작가를 입력받는다.")
public void t4() {
String output = AppTest.run("""
등록
현재를 사랑하라.
작자미상
""");
assertThat(output)
.contains("명언 : ")
.contains("작가 : ");
}
}
➡️ 테스트 의도 : "등록" 명령어 입력 후, "명언 : "과 "작가 : "라는 메시지가 출력되어야 한다.
➡️ 결과 : 테스트 실행 시 해당 기능이 구현되지 않았으므로 실패(Red 상태)
"""
등록
현재를 사랑하라.
작자미상
"""
➡️ 이 문자열은 사용자가 콘솔에서 입력하는 명령어를 대신합니다.
➡️ TestUtil.getScanner(input)을 통해 입력 문자열을 Scanner 객체로 변환하여 App 클래스에서 실제 입력처럼 처리할 수 있게 합니다.
4. main package에 테스트를 통과시키기 위해 최소한의 코드를 작성합니다. (Green)
- 작업 위치 : 메인 패키지(보통 src/main/java 디렉토리)
- 이 단계에서는 복잡한 로직을 구현하기보다는 테스트 통과에 집중합니다.
public class WiseSayingController {
public void actionAdd() {
System.out.println("명언 : ");
String content = scanner.nextLine();
System.out.println("작가 : ");
String author = scanner.nextLine();
WiseSaying wiseSaying = wiseSayingService.add(content, author);
System.out.println(wiseSaying.getId() + "번 명언이 등록되었습니다.");
}
}
➡️ 테스트 의도 : "등록" 명령어가 실행되었을 때, 명언과 작가 입력을 처리하는 기능을 구현
➡️ 결과 : 다시 테스트를 실행하면 테스트가 통과(Green 상태)
5. 테스트가 통과한 코드를 리팩터링하여 품질을 개선합니다. (Blue)
- actionAdd 메서드의 중복 코드 제거, 더 명확한 변수명으로 변경, 또는 서비스 로직을 별도의 클래스에 분리 등
public void actionAdd() {
String quoteContent = promptInput("명언 : ");
String quoteAuthor = promptInput("작가 : ");
int registeredId = wiseSayingService.registerQuote(quoteContent, quoteAuthor);
System.out.printf("%d번 명언이 등록되었습니다.%n", registeredId);
}
private String promptInput(String message) {
System.out.print(message);
return scanner.nextLine();
}
JUnit과 TDD를 활용한 워크플로우
- 요구사항 정의
- 문제를 작은 기능 단위로 나눕니다
- 테스트 작성 (Red)
- 아직 구현되지 않은 기능에 대한 테스트를 작성
- 테스트가 실패하는 것을 확인
- 기능 구현 (Green)
- 테스트를 통과하기 위한 최소한의 코드를 작성
- 리팩터링 (Refactor)
- 코드 품질을 개선하고, 테스트가 계속 통과하는지 확인
- 반복
- 새로운 기능에 대해 위 과정을 반복
출처
OpenAI의 ChatGPT (https://openai.com)
'Java > TDD' 카테고리의 다른 글
단언 메서드 (assertion methods) (1) | 2025.02.25 |
---|---|
[JUNIT] REST API feat. Annotation (0) | 2025.02.22 |
[JUNIT] 어노테이션 (Annotation) (1) | 2024.12.08 |