공부/Java

JUnit을 이용한 단위 테스트와 Assert 메소드

동곤영 2022. 3. 31. 21:03

내가 있던 SI 프로젝트는 규모가 너무 커서 JUnit을 활용한 단위 테스트를 적용할 수 없었다.

그래서 난 JUnit을 사용해본적이 없다. 대부분 Logger.debug를 이용하여 파라미터만 콘솔에 출력했다.

JUnit을 활용한 테스트 코드 작성이 목표였기 때문에 관련 내용을 정리해보고자 한다.

 

1. JUnit이란?

자바용 단위 테스트 도구이다.

 

2. 단위테스트(Unit Test)란?

- 소스코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차

- 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차

 

3. JUnit 특징 

- @Test 메소드가 호출할 때마다 새로운 인스턴스를 생성하여 독립적인 테스트가 이루어지게 함

- 단정(assert)메소드로 테스트 케이스의 수행 결과를 판별할 수 있음.

- 패턴(given/when/then)

  given (준비) : 어떤 데이터가 준비됐을 때

  when (실행) : 어떤 메소드를 실행하면

  then (검증) : 어떤 결과가 나와야 한다.

 

4. Assert클래스 정리

assertArrayEquals(a, b) : 배열 a, b가 일치함을 확인한다.

 

assertEquals(a, b) : 객체 a와 b가 같은 값을 가지는지 확인한다.

 

assertEquals(a, b, c) : 객체 a와 b가 값이 일치함을 확인한다. (a : 예상 값, b : 결괏값, c : 오차범위)

 

assertSame(a, b) : 객체 a와 b가 같은 객체임을 확인한다. (a와 b가 같은 객체를 참조하면 테스트 통과)

 

assertNotSame(a, b) : 객체 a와 b가 같은 객체를 참조하고 있지 않으면 통과

 

assertTrue(a) : a가 True인지 확인한다.

 

assertFalse(a) : a가 False인지 확인한다. 

 

assertTrue(message, condition) : condition이 True면 message표시

 

assertNull(a) : 객체 a가 null인지 확인한다.

 

assertNotNull(a) : 객체 a가 null이 아닌지 확인한다.

 

assertfail() : 테스트 실패 처리

 

5. 어노테이션

1. 테스트 메소드를 지정하기
@Test // @Test 어노테이션이 메소드 위에 선언되면 이 메소드는 테스트 대상 메소드임을 의미  
public void testA() {
	// TODO
}

2. 테스트 메소드 수행시간 지정하기
@Test(timeout=5000) // timeout을 지정 (단위 : 밀리 초) 5,000밀리 초를 넘기면 테스트 실패
public void testA() {
	// TODO
}

3. 테스트 메소드 Exception 지정하기
@Test(expected=RuntimeException.class) // 이 테스트는 RuntimeException이 발생해야 테스트 성공 
public void testA() {
	// TODO
}

4. @BeforeClass, @AfterClass, @before, @After 
@BeforeClass -> 테스트 클래스 테스트 시작시 1번만 호출
@Before -> 테스트 케이스 시작전 각각 호출
@After -> 테스트 케이스 종료시 각각 호출
@AfterClass -> 테스트 클래스 모든 테스트 종료시 1번만 호출
// 순서를 적어보자면
EX)
@BeforeClass
@Before
케이스1
@After
@before
케이스2
@After
@AfterClass

 

 

 

 

지금부터는 위의 정보를 바탕으로 어떤 클래스에 대해 테스트 코드를 작성해 볼 것이다.

 

TESTDOME이라는 코딩테스트 사이트에서 발췌한 문제이다.

 

https://www.testdome.com/questions/java/account-test/38495

 

Account Test | Java | TestDome

Account Test programming interview question screens programmers for knowledge of: Java.

www.testdome.com

 

위의 4가지 케이스에 부합하는 테스트 코드를 작성해보자!

Account 클래스

public class Account {
    private double balance;
    private double overdraftLimit;
    
    public Account(double overdraftLimit) {
        this.balance = 0;
        this.overdraftLimit = overdraftLimit > 0 ? overdraftLimit : 0;
    }
    
    public boolean deposit(double amount) {
        if(amount >= 0) {
            this.balance += amount;
            return true;
        }
        return false;
    }
    
    public boolean withdraw(double amount) {
        if(this.balance - amount >= -this.overdraftLimit && amount >= 0) {
            this.balance -= amount;
            return true;
        }
        return false;
    }
    
    public double getBalance() {
        return balance;
    }
    
    public double getOverdraftLimit() {
        return overdraftLimit;
    }
}

 

 

AccountTest 클래스 (실제 내가 구현해야하는 클래스)

import org.junit.Assert;
import org.junit.Test;

public class AccountTest {
    private double epsilon = 1e-6;

    @Test
    public void accountCannotHaveNegativeOverdraftLimit() {
        Account account = new Account(-20);
        
        Assert.assertEquals(0d, account.getOverdraftLimit(), epsilon);
    }
    
    /* The deposit and withdraw methods will not accept negative numbers */
    /* deposit, withdraw 메소드는 음수를 허용하지 않는다. */
    /* 그래서 두 개의 메소드에 음수를 넣어 볼 것이다. */
    @Test
    public void negativeDeposit() { // deposit 메소드 테스트
        // given
        Account account = new Account(20); 
        // when 
        boolean result = account.deposit(-10); // 음수를 넣으면 return은 false이다.
        // then
        Assert.assertFalse(result); // assertFalse(result) fasle 이므로 통과.
    }
    @Test
    public void negativeWithDraw() { // withdraw 메소드 테스트
        // given
        Account account = new Account(20);
        // when
        boolean result = account.withdraw(-10); // 음수를 넣으면 return은 false이다.
        // then
        Assert.assertFalse(result);// assertFalse(result) fasle 이므로 통과.
    }
    
    /* Account cannot overstep its overdraft limit. */
    /* Account는 overdraftlimit을 초과할 수 없다. */
    /* Account를 초과하는 수를 넣어볼 것이다. */
    @Test
    public void overstepWithdraw() {
        // given
        Account account = new Account(20); // 생성자에 의해 balance = 0, overdraftlimit = 20;
        // when
        boolean result = account.withdraw(30); // false를 리턴
        // then
        Assert.assertFalse(result); // assertFalse(result) false 이므로 통과.
    }
    
    /* The deposit and withdraw methods will deposit or withdraw the correct amount, respectively */
    /* deposit, withdraw메소드가 각각 올바른 금액을 입출금 한다. */
    /* getBalance() 메소드를 활용해 deposit, withdraw에 대해 assertEquals을 해본다 */
    @Test
    public void correctAmount() {
        Account account = new Account(0);
        account.deposit(20); // deposit(20) --> balance = 20
        boolean result = account.withdraw(10); --> balance = 10
        // 20을 deposit 하고 10을 withdraw 했으니 balance는 10
        Assert.assertEquals(10, account.getBalance(), epsilon); // , assertEquals(10, account.getBalance()) true 이므로 통과
    }
    
    /* The withdraw and deposit methods return the correct results */
    /* withdraw와 deposit 메소드는 올바른 결과를 반환한다. */
    /* depsoit메소드와 withdraw가 true를 리턴하도록 유도해보자. */
    @Test
    public void correctDeposit() {
        // given
        Account account = new Account(0); 
        // when
        boolean result = account.deposit(20); // true를 리턴
        // then
        Assert.assertTrue(result); // assertTrue(result) true 이므로 통과.
    }
    @Test
    public void correctWithdraw() {
        Account account = new Account(0);
        account.deposit(20);
        boolean result = account.withdraw(10); // true를 리턴
        Assert.assertTrue(result); // assertTrue(result) true 이므로 통과.
    }
    
}

 

 

이상 간단한 JUnit 사용법을 알아보았습니다만 찾아보니 JUnit 관련 내용은 더 많은게 있다....

그만 알아보자..

 

참고

https://devuna.tistory.com/39

 

Junit - Assert 메소드

단정 메소드(assert method) ·         JUnit에서 가장 많이 이용되는 단정(assert) 메소드입니다. ·         단정 메서드로 테스트 케이스의 수행 결과를 판별합니다. 메소드 설..

beomseok95.tistory.com

https://beomseok95.tistory.com/302

 

@BeforeClass, @AfterClass ,@Before,@After 순서 알아보기

@BeforeClass, @AfterClass ,@Before,@After 순서 알아보기 Junit에 @BeforeClass, @AfterClass ,@Before,@After 어노테이션이 있습니다. 이전 이후..? 뭐지 어떻게 호출되는건지 알아보도록 하겠습니다. Example..

beomseok95.tistory.com

https://in-the-garden.tistory.com/9

 

Junit 단위테스트

>> Java단위테스트시 필요한 라이브러리 1. JUnit5 : 자바 단위 테스트를 위한 테스트 프레임워크 2. AssertJ : 자바 테스트를 돕기 위해 다양한 문법을 지원하는 라이브러리 >> 패턴(given/when/then) - given (

in-the-garden.tistory.com