1.테스트 프레임워크 만들기
다음의 프로그램을 작성했다고 가정할 경우,
Calculator.java
public class Calculator {
public double add(double number1, double number2) {
return number1 + number2;
}
}작성한 계산기가 컴파일에도 문제가 없지만, 런타임에도 문제가 없는지 확인이 필요함
이 코드만으로는 해당 기능(덧셈)이 제대로 동작하는지에 대해 증명할 수 없는 상태
→ 즉, 자동화된 테스트가 필요함!
Calculator를 테스트하는 코드 작성
따라서 Calculator를 테스트하는 코드를 작성해보면 다음과 같음
CalculatorTest.java
public class CalculatorTest {
public static void main(String[] args) {
// Calculator 객체 생성
Calculator calculator = new Calculator();
// 덧셈 메서드를 호출하여 테스트
double result = calculator.add(3, 5);
if (result != 8) {
System.out.println("잘못된 결과: " + result);
} else {
System.out.println("테스트 성공: " + result);
}
}
}CalculatorTest 코드 개선
테스트에 용이하게 하기 위해 개선한 코드는 다음과 같음
CalculatorTest.java
public class CalculatorTest {
private int errors = 0;
// 확장성을 고려하여 덧셈 메서드만 모듈화
public void testAdd() {
Calculator calculator = new Calculator();
double result = calculator.add(3, 5);
if (result != 8) {
// 예외를 던지도록 지정
throw new IllegalStateException("잘못된 결과: " + result);
}
}
public static void main(String[] args) {
// Calculator 객체 생성
Calculator calculator = new Calculator();
try {
test.testAdd(); // 덧셈 메서드 호출
} catch (Throwable e) {
test.erros++;
e.printStackTrace();
}
// 테스트 메서드에서 발생한 에러의 개수 확인하기
if (test.errors > 0) {
throw new IllegalStateException(test.errors + "개의 에러가 있습니다.");
}
}
}단위 테스트 프레임워크의 동작 이해하기
보편적인 단위 테스트는 지켜야할 몇 가지 규칙이 있음
1. 단위 테스트는 다른 단위 테스트와 독립적으로 실행되어야 함
테스트하고자하는 대상을 다른 테스트와 분리하여 외부 변인을 통제하기 위해 다른 테스트와 독립적으로 실행되어야 함
CalculatorTest.java
// 덧셈 기능만 별도의 메서드로 분리
public void testAdd() {
Calculator calculator = new Calculator();
double result = calculator.add(3, 5);
if (result != 8) {
// 예외를 던지도록 지정
throw new IllegalStateException("잘못된 결과: " + result);
}
}
// 뺄셈 기능 메서드
// public void testSub() { ... }
// main(String[] args) ..2. 프레임워크는 각 단위 테스트의 오류를 파악하여 개발자에게 알려주어야 함
프레임워크는 개발자가 테스트의 오류를 빠르게 파악할 수 있도록 통지가 필요
CalculatorTest.java
// void testAdd() { ... }
public static void main(String[] args) {
Calculator calculator = new Calculator();
try {
test.testAdd(); // 덧셈 메서드 호출
} catch (Throwable e) {
test.erros++;
e.printStackTrace();
}
// 테스트 메서드에서 발생한 에러의 개수를 파악하여 개발자에게 알려주기
if (test.errors > 0) {
throw new IllegalStateException(test.errors + "개의 에러가 있습니다.");
}
}3. 개발자가 어떤 테스트를 실행할지 쉽게 정의하고 작성할 수 있어야 함
실행하고 싶은 테스트를 편리하게 지정할 수 있으면 더 좋음
CalculatorTest.java
// void testAdd() { ... }
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 실행할 테스트를 try 블럭 내에 작성하여 테스트를 실행함
try {
test.testAdd(); // 덧셈 테스트 메서드 호출
} catch (Throwable e) {
test.erros++;
e.printStackTrace();
}
// 테스트 메서드에서 발생한 에러의 개수를 파악하여 개발자에게 알려주기
if (test.errors > 0) {
throw new IllegalStateException(test.errors + "개의 에러가 있습니다.");
}
}3. 간이 테스트 프레임워크의 단점
그럼에도 불구하고 간이로 구현해본 테스트 프레임워크는 몇 가지 단점이 있음
1. try 블럭에 추가되는 테스트 메서드
만약 뺄셈, 곱셈 등 다른 기능들이 추가되면 try 블럭 내 코드가 늘어나고 유지보수가 어려워짐
→ 덧셈 기능만 테스트하고 싶을 경우, 다른 클래스들에 주석 처리 필요
CalculatorTest.java
// void testAdd() { ... }
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 실행할 테스트를 try 블럭 내에 작성하여 테스트를 실행함
try {
test.testAdd(); // 덧셈 테스트 메서드 호출
} catch (Throwable e) {
test.erros++;
e.printStackTrace();
}
// 테스트 메서드에서 발생한 에러의 개수를 파악하여 개발자에게 알려주기
if (test.errors > 0) {
throw new IllegalStateException(test.errors + "개의 에러가 있습니다.");
}
}2. 테스트 대상이 되는 메서드만 찾으려면?
프로그램을 구현하다보면 현실적으로 테스트 필요성이 떨어지는 메서드가 있을 수 있음
프로그램에게 테스트 대상이 되는 메서드만 찾게 하려면 어떻게 해야할까?
런타임에 코드를 조작할 수 있는 Java의 reflection API을 활용하여 test~로 시작하는 메서드만 테스트 대상의 메서드만 되도록 처리
CalculatorTest.java
void calculatorUtil() { ... }
// test~로 시작하는 메서드만 테스트 대상의 메서드가 되도록 등록
void testAdd() { ... }
void testSub() { ... }
void testMul() { ... }3. 보일러 플레이트 코드 준비
단위 테스트를 수행하기 위해서는 지금까지 확인한 테스트를 위한 템플릿 코드를 준비해야 함
Last updated on