수색…
비고
매개 변수 | 문맥 | 세부 |
---|---|---|
@BeforeClass | 공전 | 클래스가 처음 생성 될 때 실행됩니다. |
@전에 | 예 | 수업 중 각 시험 전에 실행 |
@테스트 | 예 | 테스트 할 각 메소드를 선언해야합니다. |
@후 | 예 | 수업 중 각 시험 후에 실행 |
@방과후 | 공전 | 수업이 파기되기 전에 실행 |
테스트 클래스 형식의 예
public class TestFeatureA {
@BeforeClass
public static void setupClass() {}
@Before
public void setupTest() {}
@Test
public void testA() {}
@Test
public void testB() {}
@After
public void tearDownTest() {}
@AfterClass
public static void tearDownClass() {}
}
}
JUnit을 사용한 유닛 테스트
여기에는 countNumbers()
및 hasNumbers()
메서드를 사용하는 Counter
클래스가 있습니다.
public class Counter {
/* To count the numbers in the input */
public static int countNumbers(String input) {
int count = 0;
for (char letter : input.toCharArray()) {
if (Character.isDigit(letter))
count++;
}
return count;
}
/* To check whether the input has number*/
public static boolean hasNumber(String input) {
return input.matches(".*\\d.*");
}
}
이 클래스를 단위 테스트하려면 Junit 프레임 워크를 사용할 수 있습니다. 프로젝트 클래스 경로에 junit.jar
을 추가하십시오. 그런 다음 아래와 같이 Test case 클래스를 만듭니다.
import org.junit.Assert; // imports from the junit.jar
import org.junit.Test;
public class CounterTest {
@Test // Test annotation makes this method as a test case
public void countNumbersTest() {
int expectedCount = 3;
int actualCount = Counter.countNumbers("Hi 123");
Assert.assertEquals(expectedCount, actualCount); //compares expected and actual value
}
@Test
public void hasNumberTest() {
boolean expectedValue = false;
boolean actualValue = Counter.hasNumber("Hi there!");
Assert.assertEquals(expectedValue, actualValue);
}
}
IDE에서이 클래스를 "Junit testcase"로 실행하고 GUI의 출력을 볼 수 있습니다. 명령 프롬프트에서 다음과 같이 테스트 케이스를 컴파일하고 실행할 수 있습니다.
\> javac -cp ,;junit.jar CounterTest.java
\> java -cp .;junit.jar org.junit.runner.JUnitCore CounterTest
성공적인 테스트 실행의 결과는 다음과 유사해야합니다.
JUnit version 4.9b2
..
Time: 0.019
OK (2 tests)
테스트 실패의 경우 다음과 같이 보입니다.
Time: 0.024
There was 1 failure:
1) CountNumbersTest(CounterTest)
java.lang.AssertionError: expected:<30> but was:<3>
... // truncated output
FAILURES!!!
Tests run: 2, Failures: 1
비품
위키 백과에서 :
테스트 픽스쳐는 일부 항목, 장치 또는 소프트웨어를 일관성있게 테스트하는 데 사용됩니다.
또한 테스트 메소드 자체에서 일반적인 초기화 / 종료 코드를 추출하여 테스트의 가독성을 향상시킬 수 있습니다.
공통 초기화는 각 테스트가 수행되기 전에 한 번 실행될 수 있으므로 테스트를 실행하는 데 걸리는 시간을 줄일 수 있습니다.
아래 예제는 JUnit이 제공하는 주요 옵션을 보여주기 위해 고안되었습니다. 초기화하는 데 비용이 많이 드는 Foo
클래스를 가정합니다.
public class Foo {
public Foo() {
// expensive initialization
}
public void cleanUp() {
// cleans up resources
}
}
다른 클래스 Bar
에는 Foo
대한 참조가 있습니다.
public class Bar {
private Foo foo;
public Bar(Foo foo) {
this.foo = foo;
}
public void cleanUp() {
// cleans up resources
}
}
아래 테스트는 하나의 Bar
포함하는 List의 초기 컨텍스트를 예상합니다.
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
public class FixturesTest {
private static Foo referenceFoo;
private List<Bar> testContext;
@BeforeClass
public static void setupOnce() {
// Called once before any tests have run
referenceFoo = new Foo();
}
@Before
public void setup() {
// Called before each test is run
testContext = Arrays.asList(new Bar(referenceFoo));
}
@Test
public void testSingle() {
assertEquals("Wrong test context size", 1, testContext.size());
Bar baz = testContext.get(0);
assertEquals(referenceFoo, baz.getFoo());
}
@Test
public void testMultiple() {
testContext.add(new Bar(referenceFoo));
assertEquals("Wrong test context size", 2, testContext.size());
for (Bar baz : testContext) {
assertEquals(referenceFoo, baz.getFoo());
}
}
@After
public void tearDown() {
// Called after each test is run
for (Bar baz : testContext) {
baz.cleanUp();
}
}
@AfterClass
public void tearDownOnce() {
// Called once after all tests have run
referenceFoo.cleanUp();
}
}
이 예제에서 @BeforeClass
주석이 setupOnce()
메소드 setupOnce()
는 Foo
객체를 만드는 데 사용되며 초기화하는 데 비용이 많이 듭니다. 어떤 테스트에 의해서도 수정되지 않는 것이 중요합니다. 그렇지 않으면 테스트 실행의 결과가 개별 테스트의 실행 순서에 따라 달라질 수 있습니다. 아이디어는 각 테스트가 독립적이며 하나의 작은 기능을 테스트한다는 것입니다.
@Before
annotated 메소드 setup()
은 테스트 컨텍스트를 설정합니다. 컨텍스트는 테스트 실행 중 수정 될 수 있으므로 각 테스트 전에 초기화되어야합니다. 이 방법에 포함 된 코드를 각 테스트 메소드의 시작 부분에 포함 시키면 동일한 효과를 얻을 수 있습니다.
@After
주석이 달린 메소드 tearDown()
은 테스트 컨텍스트 내에서 리소스를 정리합니다. 이것은 각 테스트 호출 후에 호출되며, @Before
어노테이션으로 @Before
메소드에서 할당 된 자원을 비우기 위해 종종 사용됩니다.
@AfterClass
주석이있는 메소드 tearDownOnce()
는 모든 테스트가 실행되면 리소스를 정리합니다. 이러한 메서드는 일반적으로 초기화 또는 @BeforeClass
주석이있는 메서드에서 할당 된 리소스를 해제하는 데 사용됩니다. 즉, 테스트가 외부 테스트 클래스에 의존하지 않도록 단위 테스트에서 외부 리소스를 피하는 것이 가장 좋습니다.
이론을 이용한 단위 테스트
이론 러너는 무한 데이터 세트의 서브 세트에 대해 특정 기능을 테스트 할 수 있습니다.
러닝 이론
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
@RunWith(Theories.class)
public class FixturesTest {
@Theory
public void theory(){
//...some asserts
}
}
@Theory
주석 된 메소드는 Theories 러너에 의해 이론으로 @Theory
것입니다.
@DataPoint 주석
@RunWith(Theories.class)
public class FixturesTest {
@DataPoint
public static String dataPoint1 = "str1";
@DataPoint
public static String dataPoint2 = "str2";
@DataPoint
public static int intDataPoint = 2;
@Theory
public void theoryMethod(String dataPoint, int intData){
//...some asserts
}
}
@DataPoint
주석 된 각 필드는 이론에서 주어진 유형의 메소드 매개 변수로 사용됩니다. 위의 예제에서 theoryMethod
는 다음 매개 변수로 두 번 실행됩니다 : ["str1", 2] , ["str2", 2]
@DataPoints 주석 @RunWith (Theories.class) public class FixturesTest {
@DataPoints
public static String[] dataPoints = new String[]{"str1", "str2"};
@DataPoints
public static int[] dataPoints = new int[]{1, 2};
@Theory
public void theoryMethod(String dataPoint, ){
//...some asserts
}
}
@DataPoints
어노테이션으로 주석 된 배열의 각 요소는 이론에서 주어진 유형의 메소드 매개 변수로 사용됩니다. 위의 예제에서 theoryMethod
는 ["str1", 1], ["str2", 1], ["str1", 2], ["str2", 2]
매개 변수로 네 번 실행됩니다 ["str1", 1], ["str2", 1], ["str1", 2], ["str2", 2]
성능 측정
테스트 방법이 너무 오래 실행되는지 확인해야하는 경우 @Test 주석의 timeout 속성을 사용하여 예상 실행 시간을 언급하면됩니다. 테스트 실행이 해당 밀리 초보다 오래 걸리면 테스트 메소드가 실패하게됩니다.
public class StringConcatenationTest {
private static final int TIMES = 10_000;
// timeout in milliseconds
@Test(timeout = 20)
public void testString(){
String res = "";
for (int i = 0; i < TIMES; i++) {
res += i;
}
System.out.println(res.length());
}
@Test(timeout = 20)
public void testStringBuilder(){
StringBuilder res = new StringBuilder();
for (int i = 0; i < TIMES; i++) {
res.append(i);
}
System.out.println(res.length());
}
@Test(timeout = 20)
public void testStringBuffer(){
StringBuffer res = new StringBufferr();
for (int i = 0; i < TIMES; i++) {
res.append(i);
}
System.out.println(res.length());
}
}
대부분의 경우 JVM 예열 을하지 않으면 testString
이 실패합니다. 그러나 testStringBuffer
와 testStringBuilder
는이 테스트를 성공적으로 통과해야합니다.