반응형

사실 JUnit을 아래 링크에서 이미 기술한 적이 있다.

https://www.crocus.co.kr/1544

 

Android UnitTest, JUnit을 이용한 유닛 테스트

1. JUnit이란? 어느 정도 개발이 진행되면 프로그램에 대한 단위 테스트는 반드시 수행해야 하는데, JUnit은 보이지 않고 숨겨진 단위 테스트를 끌어내어 정형화시켜 단위 테스트를 쉽게 해주는 테스트용 Framewor..

www.crocus.co.kr

하지만 필자도 다시 가다듬어보고자 한번 간단하게 다시 적어보고자 한다.

 

 

JUnit?

 

JUnit은 Espresso testing framework가 build된 Java 커뮤니티에서 개발한 가장 널리 알려진 unit-testing 프레임워크이다. JUnit이 비록 유닛 테스트로 유명하긴 하지만 instrumentation testing 또한 완벽하게 지원해준다.

이런 JUnit을 이용하여 Espresso testing library는 구동된다.

 

 

 

Simple Unit Test

 

아래와 같이 간단한 덧셈, 곱셈 연산을 하는 클래스를 하나 만들어보자.

public class Computation {
   public Computation() {}
   public int Sum(int a, int b) {
      return a + b;
   }
   public int Multiply(int a, int b) {
      return a * b;
   }
}

 

그리고 나서 UnitTest 클래스를 하나 만들어보자. 이는 app/src/test/ 폴더 밑에 있어야한다.

 

import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class UnitTest {
   @Test
   public void sum_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Multiply(2,2));
   }
}

 

위와 같은 코드가 Unit Test를 위한 코드이다. (좀 더 자세히 보기 위해서는 https://www.crocus.co.kr/1544 링크에서 Unit Test를 확인해보자.)

 

이때 우리는 @Test라는 Annotation과 assertEquals라는 메서드를 사용했다.

 

보통 JUnit은 테스트 케이스인지 확인하기 위해 @Test라는 Annotation을 사용하고

어떻게 test를 실행할지에 대해 Annotation 뒤에 부가적으로 더 적어줄 수 있기도하다.

 

그리고 여기서 나온 assertEquals는 첫번째 파라미터 값과 두번째 파라미터 값이 같은지 판별해주는 메서드이다.

 

 

 

Annotations

@BeforeClass, @Rule, @Before, @Test, @After, @AfterClass

다섯개의 annotation을 알아보고자 하고 실제로 클래스에서 이 순서가 어노테이션의 플로우다.

 

 

JUnit framework에서 사용하는 annotation중 중요한 항목들은 아래와 같다.

  • @Test

@Test는 JUnit framework에서 가장 중요한 annotation이다.

@Test는 테스트 케이스 메서드임을 표시하고 일반 메서드와 다름을 명시하는데 사용한다.

메서드가 @Test annotation을 사용하면 이러한 특정 메서드는 테스트 케이스로 간주되고 JUnit Runner에 의해 실행된다. 

JUnit Runner는 Java 클래스 내부에서 사용가능한 JUnit test case를 찾아 실행하는데 사용되는 특수한 클래스이다.

아래 코드는 @Test annotation을 이용한 JUnit test case이다.

import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   @Test
   public void multiply_isCorrect() {
      Computation computation = new Computation();
      assertEquals(4, computation.Multiply(2,2));
   }
}

 

 

 

  • @Before

@Before annotation은 어떤 테스트 메서드를 실행하기 전에 호출되도록 하는 annotation이다.

아래 코드를 보면 알수있듯이, Computation 객체는 @Before annotation에서 생성된다.

즉, @Before은 @Test 메서드가 실행되기 전에 실행되는 annotation임을 알 수 있다.

이때 중요한 것은 @Before는 각 @Test가 진행될때마다 실행되므로 아래에서 총 2번 실행된다.

( ** Before 어노테이션을 여러개 둔 경우 어떤 @Before가 먼저 실행될지는 보장 받을 수 없다.)

import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   Computation computation = null;
   @Before
   public void CreateComputationObject() {
      this.computation = new Computation();
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, this.computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, this.computation.Multiply(2,2));
   }
}

 

 

 

  • @After

@After annotation은 @Before와 유사하다.

보면 바로 알수 있듯이, @Test가 끝난 후 실행되는 annotation 역할을 한다.

( ** After 어노테이션은 테스트가 실패하더라도 실행된다.)

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   Computation computation = null;
   @Before
   public void CreateComputationObject() {
      this.computation = new Computation();
   }
   @After
   public void DestroyComputationObject() {
      this.computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, this.computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, this.computation.Multiply(2,2));
   }
}

 

 

 

  • @BeforeClass

@BeforeClass는 @Before와 유사하지만 이는 특정 클래스에서 모든 테스트 케이스를 실행하기 전에 한번만 실행된다.

이는 데이터베이스 연결 개체와 같은 리소스 객체를 생성하는데 유용하다.

이것은 테스트 케이스의 실행 시간을 줄여준다. 그리고 이 메서드는 적절하게 사용되기 위해서는 static이어야만 한다.

이때 중요한 것은 @BeforeClass는 @Test 수와 관계없이 딱 한번만 실행된다.

import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

 

 

 

  • @AfterClass

@AfterClass는 @BeforeClass와 유사하다.

@AfterClass annotation도 마지막 딱 한번만 실행되는 것이기에 static으로 두어야한다.

 

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @AfterClass
   public static void DestroyComputationObject() {
      computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

 

 

  • @Rule

@Rule annotation은 JUnit에서 가장 중요한 특징중 하나이다.

이것은 test case들에게 행동을 부여하는데 사용된다.  이 annotation은 오직 TestRule 타입의 필드에서만 사용할 수 있다. 실제로 @Before 및 @After annotation이 제공하는 기능을 효율적이고 재사용이 가능한 방식으로 제공해준다.

 

예를들어 보자. test case에서 어떤 데이터를 저장하기 위해 임시 폴더를 필요로 할때 일반적으로 우리는 임시 폴더를 test case를 실행하기 전에 생성해두고(@Before 또는 @BeforeClass에서) test case가 끝나면 삭제할 것이다.(@After 또는 @AfterClass에서)

이러한 것 대신에 우리는 TemporaryFolder이라는 클래스를 JUnit framework로부터 제공받아 모든 테스트케이스에 대한 임시 폴더로 사용할 수 있다.

 

이러한 것을 사용하기 위해 우리는 @Rule라는 annotation을 사용한다.

 

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import static junit.framework.TestCase.assertTrue;
import static org.junit.Assert.assertEquals;

public class ComputationUnitTest {
   private static Computation computation = null;
   @Rule
   public TemporaryFolder folder = new TemporaryFolder();
   @Test
   public void file_isCreated() throws IOException {
      folder.newFolder("MyTestFolder");
      File testFile = folder.newFile("MyTestFile.txt");
      assertTrue(testFile.exists());
   }
   @BeforeClass
   public static void CreateComputationObject() {
      computation = new Computation();
   }
   @AfterClass
   public static void DestroyComputationObject() {
      computation = null;
   }
   @Test
   public void sum_isCorrect() {
      assertEquals(4, computation.Sum(2,2));
   }
   @Test
   public void multiply_isCorrect() {
      assertEquals(4, computation.Multiply(2,2));
   }
}

 

 

Assertion

Assertion은 테스트를 할 때 예상되는 값을 체크하기위해 사용되는 메서드이다. 이는 직관적이므로 아래 내용을 보고 참고하자.

  • fail() − To explicitly make a test case fail.

  • assertTrue(boolean test_condition) − Checks that the test_condition is true

  • assertFalse(boolean test_condition) − Checks that the test_condition is false

  • assertEquals(expected, actual) − Checks that both values are equal

  • assertNull(object) − Checks that the object is null

  • assertNotNull(object) − Checks that the object is not null

  • assertSame(expected, actual) − Checks that both refers same object.

  • assertNotSame(expected, actual) − Checks that both refers different object.

 

https://www.tutorialspoint.com/espresso_testing/espresso_testing_overview_of_junit.htm

반응형