junit规则_jUnit:规则
junit規則
規則在測試,測試用例或測試套件周圍增加了特殊處理。 他們可以對該類中的所有測試執行通用的其他驗證,并發運行多個測試實例,在每個測試或測試用例之前設置資源,然后在之后拆除它們。
該規則可以完全控制將要應用到的測試方法,測試用例或測試套件。 完全控制意味著規則決定運行它之前和之后要做什么以及如何處理拋出的異常。
第一章介紹了如何使用規則,第二章介紹了內置規則可以做什么。 第三章介紹了我發現的第三方規則庫,最后一章介紹了如何創建新規則。
使用規則
本章說明如何在測試用例中聲明和使用規則。 大多數規則可以分別應用于每種測試方法,一次應用于整個測試用例,一次應用于整個測試套件。 為每個測試單獨運行的規則稱為測試規則,應用于整個測試用例或套件的規則稱為類規則。
我們將以臨時文件夾規則為例,因此第一個子章節將說明它的作用。 第二小節將其聲明為測試規則,第三小節將其聲明為類規則。 最后一個子章節顯示了如何從測試內部訪問該文件夾。
規則示例–臨時文件夾
臨時文件夾規則創建一個新的空文件夾,運行測試或測試用例,然后刪除該文件夾。 您可以指定在哪里創建新文件夾,也可以在系統臨時文件目錄中創建它。
臨時文件夾既可以用作測試規則,也可以用作類規則。
聲明測試規則
測試規則(例如,針對每種測試方法分別運行的規則)必須在帶有@Rule注釋的公共字段中聲明。
聲明測試規則:
public class SomeTestCase {@Rulepublic TemporaryFolder folder = new TemporaryFolder(); }上面的folder規則會在每種測試方法之前創建一個新文件夾,然后將其銷毀。 所有測試都可以使用該目錄,但不能通過該目錄共享文件。 由于我們使用的構造函數沒有參數,因此該文件夾將在系統臨時文件目錄中創建。
測試規則在使用@Before注釋的方法之前和之后使用@After注釋的方法之前進行工作。 因此,他們也將有權訪問臨時文件夾。
宣布班級規則
類規則(例如,針對整個測試用例或測試套件運行一次的規則)必須在公共靜態字段中聲明,并使用@ClassRule注釋進行注釋。
聲明測試用例規則:
public class SomeTestCase {@ClassRulepublic static TemporaryFolder folder = new TemporaryFolder(); }上面的folder規則在運行第一個測試方法之前創建一個新文件夾,并在最后一個測試方法之后銷毀它。 所有測試都可以使用該目錄,并且可以查看以前運行的測試所創建的文件。
類規則在該類內部的任何內容之前運行。 例如,用@BeforeClass或@AfterClass注釋的方法也可以訪問臨時文件夾。 該規則在它們之前和之后運行。
在測試中使用規則
規則是任何其他類,測試可以自由調用其公共方法并使用其公共字段。 這些調用用于將測試特定的配置添加到規則或從中讀取數據。
例如,可以使用newFile , newFolder或getRoot方法訪問臨時文件夾。 前兩個在臨時文件夾中創建新文件或文件夾,而getRoot方法返回臨時文件夾本身。
創建臨時文件和文件夾:
@Test public void test1() {// Create new folder inside temporary directory. Depending on how you // declared the folder rule, the directory will be deleted either // right after this test or when the last test in test case finishes.File file = folder.newFolder("folder"); }@Test public void test2() {// Create new file inside temporary folder. Depending on how you // declared the folder rule, the file will be deleted either // right after this test or when the last test in test case finishes.File file = folder.newFile("file.png"); }默認規則
JUnit帶有五個直接可用的規則 :臨時文件夾,預期的異常,超時,錯誤收集器和測試名稱。 臨時文件夾已在上一章中進行了說明,因此我們將僅簡要介紹其余四個規則。
預期異常
預期異常將運行測試并捕獲其引發的所有異常。 該規則能夠檢查異常是否包含正確的消息,正確的原因以及是否由正確的行拋出。
預期的異常具有私有構造函數,必須使用靜態none方法進行初始化。 每個異常引發測試都必須配置預期的異常參數,然后調用規則的expect方法。 該規則在以下情況下失敗:
- 測試在expect方法調用之前引發任何異常,
- 在expect方法調用之后,測試不會引發異常,
- 引發的異常沒有正確的消息,類或原因。
最后一條測試行引發異常。 在導致異常之前立即配置了預期的異常規則:
@Rule public ExpectedException thrown= ExpectedException.none();@Test public void testException() {// Any exception thrown here causes failuredoTheStuff();// From now on, the rule expects NullPointerException exception// to be thrown. If the test finishes without exception or if it // throws wrong one, the rule will fail.thrown.expect(NullPointerException.class);// We well check also messagethrown.expectMessage("Expected Message.");// this line is supposed to throw exceptiontheCodeThatThrowsTheException(); }獎勵:預期的消息方法也接受hamcrest匹配器參數。 這樣,您就可以測試消息前綴后綴是否與某些正則表達式匹配。
超時
超時規則可以同時用作測試規則和類規則。 如果將其聲明為測試規則,則它將相同的超時限制應用于該類中的每個測試。 如果將其聲明為類規則,則它將超時限制應用于整個測試用例或測試套件。
錯誤收集器
通過錯誤收集器,您可以在測試內部運行多個檢查,然后在測試結束后立即報告所有失敗。
期望值與實際值的斷言使用規則公開的checkThat方法進行評估。 它接受hamcrest匹配器作為參數,因此可以用來檢查任何內容。
可以使用addError(Throwable error)方法直接報告意外異常。 或者,如果有要運行的Callable實例,則可以通過checkSucceeds方法調用它, checkSucceeds方法將所有拋出的異常添加到錯誤列表中。
測試名稱
測試名稱規則在測試內部公開測試名稱。 當您需要創建自定義錯誤報告時,它可能會很有用。
第三方規則庫
規則與測試類分離,因此很容易編寫通用規則庫并在項目之間共享它們。 本章介紹了三個這樣的庫。
系統規則是用于測試使用java.lang.System的代碼的規則集合。 它有充分的文檔證明,可在maven中使用,并根據Common Public License 1.0(與jUnit相同)發布。 系統規則使您可以輕松:
- 測試System.err和System.out內容,
- 模擬System.in輸入,
- 配置系統屬性并將其值還原回
- 測試System.exit()調用–是否被調用以及返回的值是什么,
- 自定義Java SecurityManager并將其還原。
一個大集的有用的規則是可以在GitHub上aisrael帳戶。 它的文檔有所限制,但是您可以隨時查看代碼 。 所有規則均根據MIT許可發布:
- 啟動和停止內存中的derby數據庫 ,
- 啟動和停止默認的Java HttpServer ,
- 啟動和停止Jetty服務器,
- 運行存根jndi ,
- 對dbUnit測試的一些支持。
github上另一套未公開的規則。 我不會在這里列出它們,因為它們的名稱是不言自明的,并且它們沒有指定的許可證。 查看規則目錄以查看其列表。
自訂規則
本章介紹如何創建新規則。 可以通過實現TestRule接口或擴展TestRule提供的兩個便捷類ExternalResource和Verifier之一來從頭實現它們。
我們將從頭開始創建一個新規則,然后使用ExternalResource類重寫它。
新規則
新規則可確保在每個測試完成工作后,正確刪除由測試創建的所有文件。 測試本身僅具有一項責任:使用規則公開的ensureRemoval(file)方法報告所有新文件。
如何聲明和使用DeleteFilesRule規則:
@Rule public DeleteFilesRule toDelete = new DeleteFilesRule();@Test public void example() throws IOException {// output.css will be deleted whether the test passes, fails or throws an exceptiontoDelete.ensureRemoval("output.css");// the compiler is configured to create output.css filecompileFile("input.less");checkCorrectess("output.css"); }從頭開始
每個規則(包括類規則)必須實現@TestRule接口。 該接口只有一種方法:
public interface TestRule {Statement apply(Statement base, Description description); }我們的工作是獲取base參數中提供的語句,然后將其轉換為另一個語句。 該語句表示一組要運行的動作,例如測試,測試用例或測試套件。 它可能已經被其他聲明的規則修改,并且包括在測試或類方法之前和之后。
第二個description參數描述輸入語句。 它可以告訴測試類名稱,測試名稱,放置在其上的注釋,它知道我們是在處理測試還是在測試套件等。我們將不需要它。
我們需要創建一個新的語句,它將執行三件事:
- 清空要刪除的文件列表。
- 運行底層測試,測試案例或測試套件由所表示的base參數。
- 刪除先前運行的語句中測試報告的所有文件。
該語句是具有一個抽象方法的類:
public abstract class Statement {public abstract void evaluate() throws Throwable; }由于基礎語句可能引發異常,因此刪除所有文件的代碼必須在finally塊中運行:
public class DeleteFilesRule implements TestRule {public Statement apply(final Statement base, final Description description) {return new Statement() {@Overridepublic void evaluate() throws Throwable {emptyFilesList(); // clean the list of filestry {base.evaluate(); // run underlying statement} finally {removeAll(); // delete all new files}}};} }引用的方法emptyFilesList和removeAll都在new語句外部,直接在DeleteFilesRule類內部聲明:
public class DeleteFilesRule implements TestRule {private List<File> toDelete;private void emptyFilesList() {toDelete = new ArrayList<File>();}private void removeAll() {for (File file : toDelete) {if (file.exists())file.delete();}}/* ... the apply method ... */ }我們需要的最后一件事是能夠添加要刪除的文件的公共方法:
public void ensureRemoval(String... filenames) {for (String filename : filenames) {toDelete.add(new File(filename));} }全班
public class DeleteFilesRule implements TestRule {private List<File> toDelete;public void ensureRemoval(String... filenames) {for (String filename : filenames) {toDelete.add(new File(filename));}}private void emptyFilesList() {toDelete = new ArrayList<File>();}private void removeAll() {for (File file : toDelete) {if (file.exists())file.delete();}}public Statement apply(final Statement base, final Description description) {return new Statement() {@Overridepublic void evaluate() throws Throwable {emptyFilesList(); // clean the list of filestry {base.evaluate(); // run underlying statement} finally {removeAll(); // delete all new files}}};} }擴展內置類
JUnit包含兩個便捷類ExternalResource和Verifier旨在進一步簡化上述過程。
外部資源
當您需要圍繞基礎測試語句進行某種預處理和后處理時, ExternalResource幫助。 如果需要預處理,請覆蓋before方法。 如果需要后處理,請覆蓋after方法。 的
從finally塊調用after ,無論如何它將運行。
我們的DeleteFilesRule可以這樣重寫:
public class DeleteFilesRule2 extends ExternalResource {/* ... list, ensureRemoval and removeAll methods ... */@Overrideprotected void before() throws Throwable {toDelete = new ArrayList<File>();}@Overrideprotected void after() {removeAll();}}驗證者
Verifier者只有一種verify要覆蓋的方法。 只有在包裝測試未引發異常后,該方法才會運行。 顧名思義,如果您想在測試后進行其他檢查,則驗證程序是不錯的選擇。
有關jUnit的更多信息
關于jUnit 4功能的上一篇文章:
- jUnit:動態測試生成
翻譯自: https://www.javacodegeeks.com/2014/09/junit-rules-2.html
junit規則
總結
以上是生活随笔為你收集整理的junit规则_jUnit:规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win10无法开机并显示PXE-MOF:
- 下一篇: 老虎为什么打不过黑豹(老虎和黑豹打架谁最