JUnit 테스트 Framework

MisCaminos·2021년 4월 1일
0

Server & Web

목록 보기
17/23

개발자가 외부에 test program(case)를 작성해서 application내 부분적 기능을 test를 해볼 수 있도록 지원하는 Java unit test framework이다.

Program test동안 걸리는 시간도 관리 할 수 있게 해준다. 그리고 JUnit은 보이지 않고 숨겨진 단위 테스트를 끌어내어 정형화시켜 단위 테스트를 쉽게 할 수 있도록 해준다.

Junit 단위 테스트의 제공 기능
. assertions : 테스트결과 값과 예상값이 같은지 비교하는 단정문
. test fixture : 일관된 테스트 실행환경
. test runner : 테스트 작업수행을 위한 테스트 실행 클래스
. 단위 테스트 케이스와 단위 테스트 메소드

JUnit의 특징

(notes from lectureblue)

  • Java 5의 애노테이션 지원
  • 이전버전에서 사용했던 test라는 글자로 method 이름으로 시작해야 하는
    제약 해소 test 메소드는 @Test 선언
  • 애노테이션 기반 픽스처
    @BeforeClass, @AfterClass, @Before, @After
  • 예외 테스트
    @Test(expected=NumberFormatException.class)
  • 시간 제한 테스트
    @Test(timeout=1000)
  • 테스트 무시
    @Ignore("this method isn't working yet")
  • 배열 지원
    assertArrayEquals([msg],예상값,실제값);
  • @RunWith(클래스이름.class)
    JUnit Test 클래스를 실행하기 위한 러너(Runner)를 명시적으로 지정한다.
    @RunWith는 junit.runner.Runner를 구현한 외부 클래스를 인자로 갖는다.
  • @SuiteClasses(Class[])
    보통 여러 개의 테스트 클래스를 수행하기 위해 쓰인다. @RunWith를 이용해
    Suite.class를 러너로 사용한다.
  • 파라메터를 이용한 테스트
    @RunWith(Parameterized.class)
    @Parameters
    public static Collection data(){
    .....
    }

JUnit4

JUnit 4는 @Test 애노테이션만 선언하면 테스트 메소드로 인식한다. "test~"로 메소드이름을 시작하지 않아도 된다.

fixture method

test는 아래 그림과 같은 순서로 진행된다.


JUnit 4는 @BeforeClass, @AfterClass 애노테이션으로 하나의 테스트 클래스 내에서 한 번만 실행하는 메소드 만들수 있다.

예외 test
JUnit3에서는 try/catch문을 사용해야했지만, JUnit4에서는 annotation을 이용해서 다음과 같이 코딩할 수 있다.

@Test(expected=NumberFormatException.class)
public void testException(){
      String value = "a123";
     System.out.println(Integer.parseInt(value));
}

expected 값으로 예외 클래스를 지정했을 때, 만일 테스트 메소드 내에서 해당 예외가 발생하지 않으면 테스트 메소드는 실패로 간주한다.

test 시간제한
밀리초 단위의 시간을 정해준 후 해당 시간 내에 테스트 메소드가 수행완료가 되지 않으면 실패한 테스트 케이스로 간주하다.

@Test(timeout=5000)
public void testPingback() throws Exception
        :
}

skip하고싶은 test 메소드 무시
@Ignore 가 선언된 메소드는 수행하지 않는다.

배열지원
배열을 비교할 수 있다 (assertArrayEquals(names, anotherNames);
배열의 순서가 다르면 테스트가 실패한다.


실습 1

Maven으로 build한 Spring framework project에 JUnit 테스트를 진행하려면pom.xml에서 버젼확인 및 dependency확인이 필요하다.

pom.xml:

<properties>
<java-version>1.8</java-version>
<org.springframework-version>4.3.20.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
....
  <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>

   <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2</version>
    </dependency>

 <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>

test할 클래스를 정하고, test를 진행 할 JUnit Test Case파일을 하나 생성하다.

STS>File>New>JUnit Test Case를 선택해서
src/test/java/test.TerminalTest.java를 생성 한다.

여기서 src/test 경로를 주의해야한다. src/main에는 test하고자하는 DTO java class 또는 Mapper interface가 들어가있고, src/test에는 테스트를 지휘하고 test case들을 정의하는 test.java 클래스가 들어간다.

JUnit Test Case생성 창에서,

"Which method stubs would you like to create" 항목에는
setUpBeforeClass(), tearDownAfterClass(), setUp(), tearDown()등 필요한 method stub를 선택한다.

"Class under test" 항목에는 test하려는 클래스를 입력한다.

아래와같이 TerminalTest.java 클래스를 작성하고 이 클래스에서 Run as > JUnit Test를 실행한다.

Test결과, test에 걸린 시간, 그리고 failure trace등을 Package Explorer 옆에 있는 JUnit tab에서 확인할 수 있다.

package test;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**TerminalTest.java
 * 
 *  1) New>JUnit Test Case를 생성
 *  2) "Class under test"항목에 src/main/java/model에서 test하려는 클래스를 지정한다. 
 *  	(for this case, src/main/java/model/test/Terminal.java)
 *  3) Before, AfterClass 등 필요한 method stubs 생성을 위해 check한다.
 *  4) JUnit Test실행시, 동작 순서: 
 *  	BeforeClass->Before->Test1->After->Before->Test2->After->...->AfterClass
 *  참고: import error발생시, Maven>Update Project 진행 try.
 **/
public class TerminalTest {
	
	//Test하려는 클래스 객체
	private static Terminal term;

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		term = new Terminal();
		term.netConnect();
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		term.netDisConnect();
	}

	@Before
	public void setUp() throws Exception {
		term.logon("user", "1234");
	}

	@After
	public void tearDown() throws Exception {
		term.logoff();
	}
	
	@Test
	public void terminalConnected() throws Exception{
		assertTrue(term.isLogon());
		System.out.println("===logon test===");
	}
	
	@Test
	public void getReturnMsg() throws Exception{
		term.setMsg("hello");
		assertEquals("hello",term.getReturnMsg());
		System.out.println("===Msg test===");
	}
}

실습 2

spring_webtest project에서 JUnit4 test를 진행해보았다.

먼저 pom.xml에 spring-test부분을 추가해야한다. spring과 mybatis가 정상적으로 연동되는지 테스트를 지원한다.

<!-- spring-test : -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>${org.springframework-version}</version>
	<scope>test</scope>
</dependency>

Spring에서 JUnit test를 위한 annotations

  • @RunWith: JUnit에 내장된 Runner대신 테스트시에 Spring에서 확장 기능을 제공하는
    SpringJUnit4ClassRunner라는 Runner 클래스를 설정
  • @ContextConfiguration: 테스트시에 필요한 애플리케이션 컨텍스트 파일 위치
  • @WebAppConfiguration : Servlet의 ServletContext를 이용(servlet-context.xml 인식)
  • @Autowired : 의존성 관리
  • @Before: @Test가 붙은 메소드 실행전에 실행한다.
  • @Test: JUnit 테스트가 작동하는 메소드로 테스트할 주요 기능을 명시한다.
  • @After: @Test가 붙은 메소드 후 에 실행한다.
    @Before --> @Test --> @After 순으로 실행하며 @Test가 5개이면 이런 과정을 5회 반복한다.

src/main/java/sping/model/bbs/BbsDTO.java에 BbsDTO(게시글 BBS테이블의 row 정보를 담을) 클래스를 define하고,

src/main/java/sping/model/bbs/BbsMapper.java와 src/resources/mybatis/bbs.xml에서 MyBatis persistene framework를 사용하는 DB-Java Object mapping 정보를 설정한 후,

BbsMapper에서 선언한 메소드들이 잘 작동하는지를 test하기 위해 아래와 같이 BbsMapperTest.java 클래스를 작성하고 JUnit test를 실행했다.

src/test/java/spring/model/bbs/BbsMapperTest.java:

package practice.spring.model.bbs;

import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations= {"file:src/main/webapp/WEB-INF/spring/root-context.xml",
		"file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml"})
//src부터 경로 명시하기

public class BbsMapperTest {
	//logger를 통해서 실행내용 기록
	private static final Logger logger = LoggerFactory.getLogger(BbsMapperTest.class);
	
	@Autowired 
	private BbsMapper mapper;
	
	@Test
	public void testMapper() {
		logger.info("mapper:"+mapper.getClass().getName());	
	}
	
	@Test 
	public void testCreate() {
		BbsDTO dto = new BbsDTO();
		dto.setWname("Ed Sheeran");
		dto.setTitle("Tenerife Sea");
		dto.setContent("The best song of the year");
		dto.setPasswd("1234");
		dto.setFilename(" ");
		dto.setFilesize(0);
		assertTrue(mapper.create(dto)>0);
		
	}
	
}

Reference:

애노테이션 기반의 JUnit 4 from lectureblue

profile
Learning to code and analyze data

0개의 댓글