Junit

2018-09-29

JUnit에 대하여

Junit이란

프로그램을 작성하면서 가장 필요한 것은 내가 만든 코드가 정상적으로 작동하는지 테스트하는 것이다.

(TDD 주도 개발이라고도 한다.)

하지만 매번 많은 코드를 테스트 하기에는 많은 시간을 필요로한다.

그래서 코드를 작성을 할때는 코드를 항상 단위적으로 나눠서 단위테스트를 하는게 가장 좋은 방법이다.

오늘은 내가 작성한 코드를 어떠한 방법으로 테스트 할것인지 알아볼 것이다.

JUnit은 간단하면서 반복적인 테스트를 실행할 수 있는 오픈소스 프레임워크이다.

설정하기

     <!-- 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/org.springframework/spring-test -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>4.3.18.RELEASE</version>
    <scope>test</scope>
</dependency>

매처(Matcher)를 위한 Maven

<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all -->
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>

프로젝트에 JUnit 추가하기

Junit은 버전 4로 이용할 것이다.

JUnit을 사용하기 앞서 프로젝트에 JUnit을 추가하는 과정을 해줘야 한다.

Junit 설정

img

img

img

img

이제 테스트를 할 수 있게 되었다.

가장 기본적인 테스트부터 시작해보겠다.

아무 클래스를 생성 해보자.

JUnitTest.java

public class JUnitTest {

    @Test
    public void Test() {
        String str = "hi Junit";
        assertThat(str, is("hi Junit"));
    }
}

Test() 함수하나를 만든뒤 (함수이름은 아무거나 상관없다.)

String 형인 str 변수의 값이 “hi Junit”인지 테스트 해볼 것이다.

그러기 위해서는 Junit에서 제공해주는 assertThat스태틱함수를 사용할 것이다.

코드설명

assertThat 함수

public static <T> void assertThat(T actual, Matcher<? super T> matcher)

assertThat 함수는 두번째 파라미터인 matcher조건이 일치하는지 확인한다.

만약 일치하지 않는다면 2번째 변수의 값과 함께 AssertionError Exception이 발생하게 된다.

2번째 변수는 Matcher 타입과 같이 사용해야 하는데 보통 CoreMatchers에 있는

public class CoreMatchers {
 public static <T> org.hamcrest.Matcher<T> is(org.hamcrest.Matcher<T> matcher) {
     return org.hamcrest.core.Is.<T>is(matcher);
}

첫번 째 값이 is("이 값과 같은지")로 자주 쓰인다.

테스트 성공시 초록불이 뜬다

img

CoreMatches에 관한 메서드들

- allOf(Iterable<Matcher<? super T» matchers) : 선언된 모든 매처가 전부 맞으면 통과한다.

- any(Class<T> type) : type의 오브젝트와 일치할 때 통과한다.

- anyOf(Iterable<Matcher<? super T» matchers) : 선언된 객체가 하나라도 일치하는 경우 통과한다.

- anything() : 선언된 객체에 상관없이 모든지 일치한다.

- both(Matcher<? super LHS> matcher) : 선언된 객체가 둘다 일치할 경우 통과한다.

- containsString(String substring) : 선언해준 문자를 포함하는 경우 통과한다.

- either(Matcher<? super LHS> matcher) : 선언된 매처중 둘중에 하나라도 일치하면 통과한다.

- endsWith(String suffix) : 문자열이 선언된 문자열로 끝나는 경우 통과한다.

- equalTo(T operand) : equals 메소드처럼 객체는 다르나 논리적으로 같을 때 통과한다.

assertThat("hi",equalTo("hi"));

- hasItem(Matcher<? super T> itemMatcher) : 배열중에 하나라도 해당 값이 있을 때 통과한다.

- hasItems(Matcher<? super T>… itemMatchers) : 배열중 선언된 값이 모두 있을 때 통과한다.

- instanceOf(Class<?> type): 선언된 객체가 같은 객체일 때 통과한다.

- is(T value) : 주로 equlaTo()처럼 논리적으로 같은지 확인한다.

- is(Matcher matcher) : 다른 매처를 꾸며줌, 용도에는 지장주지 않고 좀더 향샹된 표현식을 제공.

assertThat("hi",is("hi"))

- not(Matcher matcher) : 매처의 결과를 뒤집는다.

- not(T value) : not(equalTo(x))로 짧게 쓰는 단축어

-notNullValue() : not(nullValue())를 짧게쓰는 단축어

- notNullValue(Class type) : not(nullValue(X.class))를 짧게쓰는 단축어

- sameInstance(T target) : 선언된 객체가 같은 인스턴스면 통과한다.

- startsWith(String prefix) : String이 선언된 객체로 시작하면 통과한다.

- theInstance(T target) : 선언된 객체가 같은 인스턴스면 통과 한다.

JUnit의 유용한 어노테이션들

@Test

가장 자주쓰이는 어노테이션으로 public void로 쓰여진 함수 위에 적어주면 JUnit에게 이건 test할 함수라도 알려주는 것이다.

@Before

테스트 하기전에 미리 만들어져야 할 오브젝트들이 만들어져야 할 함수에게 써준다.

@BeforeClass

몇몇 테스트 작업들은 (예를 들면 DB 로깅 작업들)은 많은 자원을 필요로 하는데 이때 사용하는 어노테이션

@After

테스트가 끝나고 할 작업이 적힌 함수에게 붙여준다. 주로 테스트가 끝나고 자원 해제 등 마무리 작업을 해주어야할 때 사용하는 어노테이션이다.

@AfterClass

모든 테스트가 끝나고 실행될 클래스 ( 예를 들면 BeforeClass에 적어논 것들을 해제해준다든지) 같은 작업을 해주는 어노테이션

@Ignore

가끔 test를 하고싶지 않는 메소드에 붙여주면 그걸 제외하고 테스트하게 된다.

@RunWith(SpringJUnit4ClassRunner.class)

이 어노테이션을 클래스위에 붙여주게되면 내장된 Runner 클래스 대신 해당 클래스를 테스트 하기 위한 다른 클래스를 불러온다.

@ContextConfiguration

설정 파일이름을 지정하지 않으면 클래스이름 + “-comtext.xml” 이 디폴트로 사용된다.

(반드시 같은 폴더내에 있어야 한다.)

다른 이름의 xml 파일을 사용하고 싶다면

@ContextConfiguration(locations = “/test-applicationContext.xml”)

을 사용하면 된다.

@RunWith 어노테이션이랑 같이 쓸것.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/test-applicationContext.xml")
//@ContextConfiguration
public class UserDaoTest {

   
}

JUnit의 특징

JUnit의 장점중 하나는 @Test 함수 하나하나 단일 객체로 다른 Test에는 영향을 안준다는 것이다.

public class JUnitTest {
    Math math;

    @Before

    public void setUp() {
        math = new Math();
    }

    @Test
    public void test() {
        System.out.println(math.hashCode());    
    }

    @Test
    public void test2() {
        System.out.println(math.hashCode());
    }

}

같은 해시코드가 아니므로 객체가 두개 생기는걸 알 수 있다.

img

테스트 실행순서

setUp() -> test() -> test 끝 -> SetUp() -> test2() -> test2 끝

이렇게 계속 된다.

코드를 짤때 반드시 테스트 지향적인 코드를 짠다면

**유지보수에서 굉장히 좋다. 한번만 run해보면 정상코드인지 바로 알수있기 떄문이다.