JUnit의 기본 정리
TDD(Test -Driven Development) - 2장
What’s JUnit?
-
Java 언어에서 TDD나 단위 테스트를 하기위한 단위 프레임 워크
-
단위 테스트를 수행하기 위해 기본적으로 기능을 제공한다.
-
테스트 결과 예상과 같은지를 판별해주는 단정문(assertions)
-
여러 테스트에서 공용으로 사용할 수 있는 테스트 픽스처(test fixture)
-
테스트 작업을 수행할 수 있게 해주는 테스트 러너(test runner)
-
JUnit 설정 (JUnit4 기준)
Maven 사용시
- pom.mxl에 다음과같은 dependency 추가
<!-- pom.xml -->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
https://mvnrepository.com/artifact/junit/junit/4.12
Eclipse 로 할때는
- Project property 중 ‘Build Path -> Configure Build Path..’ 선택
- ‘Java Build Path’ 메뉴에 있는 ‘Libraries’ 탭 선택후 ‘Add Library..’ 버튼 클릭
- ‘JUnit’ 선택
- 버전 선택
JUnit에서 기본적으로 제공하는 기능
-
테스트 결과가 예상과 같은지 판별해주는 단정문(assertions)
- 여러 테스트에서 공용으로 사용할 수 있는 테스트 픽스쳐(test fixture)
일관된 테스트 환경을 말한다
예를들어 테스트케이스에서 사용할 객체의 인스턴스를 만들다던가, 데이터베이스와 연동할 수 있는 참조를 선언한다 던가 1장 예제에서 사용한 setUp 이나 tearDown 메소드는 테스트 픽스쳐 메소드라 할 수 있다.
-> 테스트 픽스쳐를 만들고 정리하는 작업을 수행하는 메소드
ex) setUp은 자원할당 , 객체 생성, DB 연결 등 / tearDown 은 자원 해체, 연결 해제, 객체 초기화 등
- 테스트 작업을 수행할 수 있게 해주는 테스트 러너(test runner)
JUnit 프레임워크는 엄연히 독립적인 소프트웨어이다. 명령행 프롬프트에서 실행하거나 셀 스크립트 등을 이용해 실행할 수도 있다. 이를 위해 JUnit은 테스트 러너라는 테스트 실행 클레스를 제공한다
Purpose
-
규칙
-
TestCase를 상속받는다.
- ex) AccouintTest extends TestCase
-
테스트 메소드의 이름은 반드시 test로 시작해야 한다.
- ex) testGetAddress(), testCalculateValue() 등
-
-
대표적인 단정문
- assertEquals([Message], expected, actual)
- 두값이 같은지 비교하는 단정문, 예상에 해당하는 expected와 실제 테스트 수행결과에 해당하는 actual이 서로 일치하는지 비교 판단한다. (기본 타입 전체에 대해 오버로딩 되어있기때문에 다양한 값을 비교할 수 있다)
- assertTrue([Message], expected ) / assertFalse([Message], expected )
- 예상값의 참/거짓을 판별하는 단정문, boolean 타입 메소드를 이용할 경우나, 부등호 비교, 범위비교 등을 판단할 때 사용한다.
- assertNull([Message], expected ) / assertNotNull([Message], expected )
- 대상 값의 null 여부를 판단하는 단정문, 확인하고 싶은 참조 변수가 null일때 녹색램프가 켜진다.
- fail( [Message] )
- assertEquals([Message], expected, actual)
-
왜 Junit 테스트 클래스에는 생성자가 없을까 ?
-
좋은 테스트 케이스는 기본적으로 다른 테스트 케이스의 수행이나 수행 결과에 영향을 받지 않아야 한다.
-
수행전에 테스트 클래스 자체를 리셋 하여 각각의 테스트 메소드만 수행하도록 한다.
-
예를 들어 AccountTest라는 클래스에 메소드가 5개가 있으면 AccountTest 클래스의 생성자는 5번이 호출되는 것이다.
-
-
Assertion
-
AssertEquals ([message], expected, actual)
: 두 값이 같은지 비교하는 단정문
-
assertEquals ([message], double expected, double actual, double delta)
Example
// JUnit에서 assertEquals([Message], expected, actual)를 정의한 부분
/* 둘다 null이면 통과 ecpected가 null이 아니고 expected의 equals 메소드를 이용해 비교했을 때 같으면 또 통과 위의 두가지 경우가 모두 아니면 실패(fail)로 처리됨*/
static public void assertEquals(String message, Object expected, Object actual){
if(expected == null && actual == null){
return;
}
if(expected == null && expected.equals(actual)){
return;
}
failNotEquals(message, expected, actual);
}
: 추가된 delta는 소수점을 갖는 float난 double 데이터형의 경우 정확하게 일치하는 값을 찾기 어려우니 delta라는 오차 보정 값을 이용 ( 보정값 범위 내 값은 동일한 값으로 판단할 수 있게 해줌)
-
assertSame([message], expected, actual)
: 두 객체가 정말 동일한 객체인지 주소값으로 비교하는 단정문
ex) 싱글톤으로 만들어진 객체를 비교할 때 쓰이기도 한다
-
assertTrue([message], expected)
예상값의 참/거짓을 판별하는 단정문, boolean 타입 메소드를 이용할 경우나, 부등호 비교, 범위비교 등을 판단할 때 사용한다.
-
assertNull([message], expected)
대상 값의 null 여부를 판단하는 단정문, 확인하고 싶은 참조 변수가 null일때 녹색램프가 켜진다.
-
fail([message])
: 이 메소드가 호출되면 해당 테스트케이스는 그 즉시 실패.
테스트 케이스를 작성중인데 완료하지 못한 채 구현을 중단해야 하는 경우라면 끝 부분에 fail()을 추가해놓으면 도움이 됨 -> 어디부터 해야할지 표시할 수 있는 용
# 실습 예제
[]
-> 원래는 main이 필요하지만 @Test 어노테이션을 통해 Junit으로 Run 을 시킬 수 있다
흔히, 클래스 작성시 속성을 먼저 생각하게 된다.
하지만, 중요한 것은 ‘동작’이다. ‘동작’을 먼저 정하고, 그 동작에 필요한 속성을 고려한다는 식으로 접근하자
‘F11’ 을 누르면 최근에 추가한 함수에 대해서 Junit을 실행해볼 수 있다.
Errors & Failures
Failures(실패) : 테스트 조건식을 만족시키지 못했다는 것 -> 내부적으로 fail(); 함수 호출됨
Errors(오류) : 테스트 케이스 수행 중 예상치 못한 예외가 발생해서 테스트 수행을 멈췄다는 것을 뜻함
( fail() 대신에 예외가 발생했다면, 실패가 아니라 오류로 간주!)
* 오류가 아닌 실패가 나오도록 짜보자
@Test
public void testGetBalance() throws Exception {
Account account=new Account(10000);
//if(account.getBalance()!=10000) {fail("get balance() => "+account.getBalance());}
assertEquals(10000, account.getBalance());
assertEquals("1000원으로 계좌 생성 후 잔고 조회",10000, account.getBalance());
}
assertEquals ( 10000, account.getBalance());
-> 왼쪽 값과 오른쪽 값을 비교. 틀리면 fail()
@Before
private void setup() {
account = new Account(10000);
}
@Test 가 시작하기 전 @Before을 통해서 먼저 실행되게 할 수도 있다!
https://junit.org/junit5/docs/current/user-guide/