자동화한 테스트를 작성해서 자바 애플리케이션이 제대로 작동하는지 반복적으로 검증하기
JUnit과 TestNG는 자바 플랫폼에서 가장 유명한 테스트 프레임워크
두 프레임워크 모두 테스트할 메서드에 @Test를 붙여 public 메서드를 테스트 케이스로 실행하는 건 동일
은행 시스템 개발
이자 계산기 인터페이스
public interface InterestCalculator {
void setRate(double rate);
double calculate(double amount, double year);
}
public class SimpleInterestCalculator implements InterestCalculator {
private double rate;
public void setRate(double rate) {
this.rate = rate;
}
public double calculate(double amount, double year) {
if (amount < 0 || year < 0) {
throw new IllegalArgumentException("Amount or year must be positive");
}
return amount * year * rate;
}
}
테스트 케이스test case는 여느 public 메서드에 @Test를 붙인 메서드
테스트 데이터는 @Before 메서드에 설정하고 테스트가 끝나면 @After 메서드에서 리소스를 해제
모든 테스트 케이스 전후에 꼭 한번만 실행할 로직은 @BeforeClass/@AfterClass를 붙인 public static 메서드에 구현
org.junit.Assert 클래스에 선언된 정적 어설션assertion(단언) 메서드는 직접 호출할 수 있으나 보통 static import문으로 모든 assert 메서드를 한 번에 임포트해 사용
public class SimpleInterestCalculatorJUnit4Tests {
private InterestCalculator interestCalculator;
@Before
public void init() {
interestCalculator = new SimpleInterestCalculator();
interestCalculator.setRate(0.05);
}
@Test
public void calculate() {
double interest = interestCalculator.calculate(10000, 2);
assertEquals(interest, 1000.0, 0);
}
@Test(expected = IllegalArgumentException.class)
public void illegalCalculate() {
interestCalculator.calculate(-10000, 2);
}
}
@Test의 expected 속성에 예외형을 적어 이 예외가 던져지길 기대
TestNG 테스트는 전용 클래스와 애너테이션 타입을 사용하는 차이점
public class SimpleInterestCalculatorTestNGTests {
private InterestCalculator interestCalculator;
@BeforeMethod
public void init() {
interestCalculator = new SimpleInterestCalculator();
interestCalculator.setRate(0.05);
}
@Test
public void calculate() {
double interest = interestCalculator.calculate(10000, 2);
assertEquals(interest, 1000.0);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void illegalCalculate() {
interestCalculator.calculate(-10000, 2);
}
}
TestNG의 특장점은 데이터 주도 테스트를 기본 지원
TestNG는 테스트 데이터와 로직을 깔끔하게 분리하므로 데이터 세트만 바꿔가면서 테스트 메서드를 여러 번 실행 가능
데이터 세트는 @DataProvider를 붙인 데이터 공급자 메서드가 제공
public class SimpleInterestCalculatorTestNGTests {
private InterestCalculator interestCalculator;
@BeforeMethod
public void init() {
interestCalculator = new SimpleInterestCalculator();
interestCalculator.setRate(0.05);
}
@DataProvider(name = "legal")
public Object[][] createLegalInterestParameters() {
return new Object[][]{new Object[]{10000, 2, 1000.0}};
}
@DataProvider(name = "illegal")
public Object[][] createIllegalInterestParameters() {
return new Object[][]{
new Object[]{-10000, 2},
new Object[]{10000, -2},
new Object[]{-10000, -2}
};
}
@Test(dataProvider = "legal")
public void calculate(double amount, double year, double result) {
double interest = interestCalculator.calculate(amount, year);
assertEquals(interest, result);
}
@Test(
dataProvider = "illegal",
expectedExceptions = IllegalArgumentException.class)
public void illegalCalculate(double amount, double year) {
interestCalculator.calculate(amount, year);
}
}
테스트를 실행하면 calculate() 메서드는 1회, illegalCalculate()는 3회 실행, 데이터 공급자 illegal은 세 데이터 세트를 반환