JUnit4注解基本介紹
JUnit4 中@AfterClass @BeforeClass @after @before的區別對比
junit之測試順序
1、JUnit4基本注解
@Before
When writing tests, it is common to find that several tests need similar objects created before they can run. Annotating a public void method with @Before causes that method to be run before the Test method. The @Before methods of superclasses will be run before those of the current class. No other ordering is defined.
當編寫測試方法時,經常會發現一些方法在執行前需要創建相同的對象。使用@Before注解一個public void 方法會使該方法在每個@Test注解方法被執行前執行(那么就可以在該方法中創建相同的對象)。
父類的@Before注解方法會在子類的@Before注解方法執行前執行。
@After
If you allocate external resources in a Before method you need to release them after the test runs.Annotating a public void method with @After causes that method to be run after the Test method. All @After methods are guaranteed to run even if a Before or Test method throws an exception. The @After methods declared in superclasses will be run after those of the current class.
使用@After注解一個public void方法會使該方法在每個@Test注解方法執行后被執行。
如果在@Before注解方法中分配了額外的資源,那么在測試執行完后,需要釋放分配的資源,這個釋放資源的操作可以在After中完成。
即使在@Before注解方法、@Test注解方法中拋出了異常,所有的@After注解方法依然會被執行。
父類中的@After注解方法會在子類@After注解方法執行后被執行。
@Test
The Test annotation tells JUnit that the public void method to which it is attached can be run as a test case. To run the method, JUnit first constructs a fresh instance of the class then invokes the annotated method. Any exceptions thrown by the test will be reported by JUnit as a failure. If no exceptions are thrown, the test is assumed to have succeeded.
The Test annotation supports two optional parameters.
The first, expected,declares that a test method should throw an exception. If it doesn't throw an exception or if it throws a different exception than the one declared, the test fails.
The second optional parameter, timeout, causes a test to fail if it takes longer than a specified amount of clock time (measured in milliseconds).
@Test注解的public void方法將會被當做測試用例,JUnit每次都會創建一個新的測試實例,然后調用@Test注解方法,任何異常的拋出都會認為測試失敗。當以一個類為測試單元時,所有測試用例(測試方法)共屬同一個測試實例(具有同一個環境);當以一個方法為測試單元時,JUnit每次都會創建一個新的測試實例。
@Test注解提供2個參數:
1,“expected”,定義測試方法應該拋出的異常,如果測試方法沒有拋出異常或者拋出了一個不同的異常,測試失敗;
2,“timeout”,如果測試運行時間長于該定義時間,測試失敗(單位為毫秒)。
@BeforeClass
Sometimes several tests need to share computationally expensive setup (like logging into a database). While this can compromise the independence of tests, sometimes it is a necessary optimization.Annotating a public static void no-arg method with @BeforeClass causes it to be run once before any of the test methods in the class. The @BeforeClass methods of superclasses will be run before those the current class.
有些時候,一些測試需要共享代價高昂的步驟(如數據庫登錄),這會破壞測試獨立性,通常是需要優化的。
使用@BeforeClass注解一個public static void 方法,并且該方法不帶任何參數,會使該方法在所有測試方法被執行前執行一次,并且只執行一次。
父類的@BeforeClass注解方法會在子類的@BeforeClass注解方法執行前執行。
@AfterClass
If you allocate expensive external resources in a Before Class method you need to release them after all the tests in the class have run. Annotating a public static void method with @AfterClass causes that method to be run after all the tests in the class have been run. All @AfterClass methods are guaranteed to run even if a Before Class method throws an exception.The @AfterClass methods declared in superclasses will be run after those of thecurrent class.
如果在@BeforeClass注解方法中分配了代價高昂的額外的資源,那么在測試類中的所有測試方法執行完后,需要釋放分配的資源。
使用@AfterClass注解一個public static void方法會使該方法在測試類中的所有測試方法執行完后被執行。
即使在@BeforeClass注解方法中拋出了異常,所有的@AfterClass注解方法依然會被執行。
父類中的@AfterClass注解方法會在子類@AfterClass注解方法執行后被執行。
@Ignore
Sometimes you want to temporarily disable a test or a group of tests. Methods annotated with Test that are also annotated with @Ignore will not be executed as tests. Also, you can annotate a class containing test methods with @Ignore and none of the containing tests will be executed. Native JUnit 4 test runners should report the number of ignored tests along with the number of tests that ran and the number of tests that failed.
對包含測試類的類或@Test注解方法使用@Ignore注解將使被注解的類或方法不會被當做測試執行;JUnit執行結果中會報告被忽略的測試數。
2、Junit測試順序:@FixMethodOrder
Junit 4.11里增加了指定測試方法執行順序的特性,測試類的執行順序可通過對測試類添加注解 @FixMethodOrder(value)
來指定,其中value 為執行順序 ,下面是value值下對應的測試順序行為:
** MethodSorters.DEFAULT **(默認)
默認順序由方法名hashcode值來決定,如果hash值大小一致,則按名字的字典順序確定。
由于hashcode的生成和操作系統相關(以native修飾),所以對于不同操作系統,可能會出現不一樣的執行順序,在某一操作系統上,多次執行的順序不變 。** MethodSorters.NAME_ASCENDING (推薦) **
按方法名稱的進行排序,由于是按字符的字典順序,所以以這種方式指定執行順序會始終保持一致;
不過這種方式需要對測試方法有一定的命名規則,如 測試方法均以testNNN開頭(NNN表示測試方法序列號 001-999) 。** MethodSorters.JVM **
按JVM返回的方法名的順序執行,此種方式下測試方法的執行順序是不可預測的,即每次運行的順序可能
都不一樣(JDK7里尤其如此)。
3、栗子
import org.junit.*;
import org.junit.runners.MethodSorters;
@FixMethodOrder(value = MethodSorters.DEFAULT) // <<--- I will change here for testing ...
public class MathTest {
private static int flag = 0;
@Test(timeout = 1000)
public void testA(){
System.out.println("here is testA");
System.out.println("flag = " + flag);
flag = 1;
System.out.println("flag = " + flag);
}
@Test
public void testB(){
System.out.println("here is testB");
System.out.println("flag = " + flag);
flag = 2;
System.out.println("flag = " + flag);
}
@Test
public void testC(){
System.out.println("here is testC");
System.out.println("flag = " + flag);
flag = 3;
System.out.println("flag = " + flag);
}
@Before
public void beforeEveryTest(){
System.out.println("\n=== beforeEveryTest ===\n");
}
@After
public void afterEveryTest(){
System.out.println("\n=== afterEveryTest ===\n");
}
// must be static
@BeforeClass
public static void beforeClassTest(){
System.out.println("\n===beforeClassTest===\n");
}
// must be static
@AfterClass
public static void afterClassTest(){
System.out.println("\n===afterClassTest===\n");
}
}
默認順序
===beforeClassTest===
=== beforeEveryTest ===
here is testA
flag = 0
flag = 1
=== afterEveryTest ===
=== beforeEveryTest ===
here is testB
flag = 1
flag = 2
=== afterEveryTest ===
=== beforeEveryTest ===
here is testC
flag = 2
flag = 3
=== afterEveryTest ===
===afterClassTest===
字典順序
同上
JVM順序
===beforeClassTest===
=== beforeEveryTest ===
here is testB
flag = 0
flag = 2
=== afterEveryTest ===
=== beforeEveryTest ===
here is testA
flag = 2
flag = 1
=== afterEveryTest ===
=== beforeEveryTest ===
here is testC
flag = 1
flag = 3
=== afterEveryTest ===
===afterClassTest===