JUnit4注解基本介紹
JUnit4 中@AfterClass @BeforeClass @after @before的區(qū)別對(duì)比
junit之測(cè)試順序
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.
當(dāng)編寫(xiě)測(cè)試方法時(shí)螃诅,經(jīng)常會(huì)發(fā)現(xiàn)一些方法在執(zhí)行前需要?jiǎng)?chuàng)建相同的對(duì)象因谎。使用@Before注解一個(gè)public void 方法會(huì)使該方法在每個(gè)@Test注解方法被執(zhí)行前執(zhí)行(那么就可以在該方法中創(chuàng)建相同的對(duì)象)卵佛。
父類(lèi)的@Before注解方法會(huì)在子類(lèi)的@Before注解方法執(zhí)行前執(zhí)行呻顽。
@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注解一個(gè)public void方法會(huì)使該方法在每個(gè)@Test注解方法執(zhí)行后被執(zhí)行。
如果在@Before注解方法中分配了額外的資源句葵,那么在測(cè)試執(zhí)行完后厕鹃,需要釋放分配的資源兢仰,這個(gè)釋放資源的操作可以在After中完成。
即使在@Before注解方法剂碴、@Test注解方法中拋出了異常把将,所有的@After注解方法依然會(huì)被執(zhí)行。
父類(lèi)中的@After注解方法會(huì)在子類(lèi)@After注解方法執(zhí)行后被執(zhí)行忆矛。
@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方法將會(huì)被當(dāng)做測(cè)試用例察蹲,JUnit每次都會(huì)創(chuàng)建一個(gè)新的測(cè)試實(shí)例,然后調(diào)用@Test注解方法洪碳,任何異常的拋出都會(huì)認(rèn)為測(cè)試失敗递览。當(dāng)以一個(gè)類(lèi)為測(cè)試單元時(shí),所有測(cè)試用例(測(cè)試方法)共屬同一個(gè)測(cè)試實(shí)例(具有同一個(gè)環(huán)境)瞳腌;當(dāng)以一個(gè)方法為測(cè)試單元時(shí),JUnit每次都會(huì)創(chuàng)建一個(gè)新的測(cè)試實(shí)例镜雨。
@Test注解提供2個(gè)參數(shù):
1嫂侍,“expected”,定義測(cè)試方法應(yīng)該拋出的異常荚坞,如果測(cè)試方法沒(méi)有拋出異程舫瑁或者拋出了一個(gè)不同的異常,測(cè)試失斖怯啊各淀;
2,“timeout”诡挂,如果測(cè)試運(yùn)行時(shí)間長(zhǎng)于該定義時(shí)間碎浇,測(cè)試失敗(單位為毫秒)璃俗。
@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.
有些時(shí)候奴璃,一些測(cè)試需要共享代價(jià)高昂的步驟(如數(shù)據(jù)庫(kù)登錄),這會(huì)破壞測(cè)試獨(dú)立性城豁,通常是需要優(yōu)化的苟穆。
使用@BeforeClass注解一個(gè)public static void 方法,并且該方法不帶任何參數(shù)唱星,會(huì)使該方法在所有測(cè)試方法被執(zhí)行前執(zhí)行一次雳旅,并且只執(zhí)行一次。
父類(lèi)的@BeforeClass注解方法會(huì)在子類(lèi)的@BeforeClass注解方法執(zhí)行前執(zhí)行间聊。
@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注解方法中分配了代價(jià)高昂的額外的資源攒盈,那么在測(cè)試類(lèi)中的所有測(cè)試方法執(zhí)行完后,需要釋放分配的資源甸饱。
使用@AfterClass注解一個(gè)public static void方法會(huì)使該方法在測(cè)試類(lèi)中的所有測(cè)試方法執(zhí)行完后被執(zhí)行沦童。
即使在@BeforeClass注解方法中拋出了異常仑濒,所有的@AfterClass注解方法依然會(huì)被執(zhí)行。
父類(lèi)中的@AfterClass注解方法會(huì)在子類(lèi)@AfterClass注解方法執(zhí)行后被執(zhí)行偷遗。
@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.
對(duì)包含測(cè)試類(lèi)的類(lèi)或@Test注解方法使用@Ignore注解將使被注解的類(lèi)或方法不會(huì)被當(dāng)做測(cè)試執(zhí)行墩瞳;JUnit執(zhí)行結(jié)果中會(huì)報(bào)告被忽略的測(cè)試數(shù)。
2氏豌、Junit測(cè)試順序:@FixMethodOrder
Junit 4.11里增加了指定測(cè)試方法執(zhí)行順序的特性喉酌,測(cè)試類(lèi)的執(zhí)行順序可通過(guò)對(duì)測(cè)試類(lèi)添加注解 @FixMethodOrder(value)
來(lái)指定,其中value 為執(zhí)行順序 ,下面是value值下對(duì)應(yīng)的測(cè)試順序行為:
** MethodSorters.DEFAULT **(默認(rèn))
默認(rèn)順序由方法名hashcode值來(lái)決定泵喘,如果hash值大小一致泪电,則按名字的字典順序確定纪铺。
由于hashcode的生成和操作系統(tǒng)相關(guān)(以native修飾),所以對(duì)于不同操作系統(tǒng)鲜锚,可能會(huì)出現(xiàn)不一樣的執(zhí)行順序,在某一操作系統(tǒng)上芜繁,多次執(zhí)行的順序不變 旺隙。** MethodSorters.NAME_ASCENDING (推薦) **
按方法名稱(chēng)的進(jìn)行排序,由于是按字符的字典順序蔬捷,所以以這種方式指定執(zhí)行順序會(huì)始終保持一致榔袋;
不過(guò)這種方式需要對(duì)測(cè)試方法有一定的命名規(guī)則周拐,如 測(cè)試方法均以testNNN開(kāi)頭(NNN表示測(cè)試方法序列號(hào) 001-999) 。** MethodSorters.JVM **
按JVM返回的方法名的順序執(zhí)行摘昌,此種方式下測(cè)試方法的執(zhí)行順序是不可預(yù)測(cè)的速妖,即每次運(yùn)行的順序可能
都不一樣(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");
}
}
默認(rè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===