
이 글은 2026년 04월 14일 작성된 글입니다.
오늘은 CLI 기반 명언 앱을 TDD 방식으로 구현하면서 테스트 환경 구성과 단계별 기능 흐름을 정리했다. 특히 TestUtil을 활용한 입출력 테스트와 단계별 요구사항을 중심으로 학습했다.
명언 앱은 CLI 환경에서 동작하며, 단계적으로 기능을 확장하는 구조로 설계된다.
등록, 목록, 삭제, 수정 기능을 기반으로 이후 파일 저장, 검색, 페이징까지 확장된다.
기존 Scanner(System.in) 방식은 테스트 자동화에 부적합하다.
따라서 문자열 기반 입력과 출력 캡처 방식으로 변경했다.
Scanner scanner = new Scanner("""
등록
현재를 사랑하라.
작자미상
""");
ByteArrayOutputStream out = TestUtil.setOutToByteArray();
System.out.println("출력 테스트");
String result = out.toString();
테스트를 위해 공통 유틸 클래스를 직접 구현했다.
public class TestUtil {
private static final PrintStream ORIGINAL_OUT = System.out;
public static Scanner genScanner(String input) {
return new Scanner(input);
}
public static ByteArrayOutputStream setOutToByteArray() {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
System.setOut(new PrintStream(byteArrayOutputStream));
return byteArrayOutputStream;
}
public static void clearSetOutToByteArray() {
System.setOut(ORIGINAL_OUT);
}
}
테스트 코드에서 반복되는 실행 로직을 줄이기 위해 AppTestRunner를 사용한다.
String out = AppTestRunner.run("""
등록
현재를 사랑하라.
작자미상
""");
기능 구현은 항상 다음 흐름을 따른다.
assertThat(out)
.contains("명언 :")
.contains("작가 :")
.contains("1번 명언이 등록되었습니다.");
이번 학습에서 진행한 주요 단계는 다음과 같다.
테스트는 명령어 단위로 작성한다.
@Test
@DisplayName("등록")
void t1() {
String out = AppTestRunner.run("""
등록
현재를 사랑하라.
작자미상
""");
assertThat(out).contains("1번 명언이 등록되었습니다.");
}