레시피 16-1 JUnit과 TestNG로 단위 테스트 작성하기

umtuk·2022년 1월 27일
0

JUnit과 TestNG로 단위 테스트 작성하기

과제

자동화한 테스트를 작성해서 자바 애플리케이션이 제대로 작동하는지 반복적으로 검증하기

해결책

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;
    }
}

JUnit 테스트 작성하기

테스트 케이스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);
    }
}

@Testexpected 속성에 예외형을 적어 이 예외가 던져지길 기대

TestNG 테스트 작성하기

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은 세 데이터 세트를 반환

profile
https://github.com/umtuk

0개의 댓글