JavaRush /Java Blog /Random-TW /JUnit for JavaRush 或一些在家測試的資訊。
Sdu
等級 17

JUnit for JavaRush 或一些在家測試的資訊。

在 Random-TW 群組發布
厭倦了在控制台中多次輸入測試資料來檢查您的任務?歡迎來到這隻貓,我會告訴你能用它做什麼。 本資料的最終目標是自動啟動使用各種參數解決的任務並檢查結果,而無需更改其原始程式碼。正如您可能已經從標題中了解到的,在這個相當簡單的問題上我們的主要助手將是 JUnit。如果你還沒有聽說過 單元測試單元測試,我建議你休息一下並熟悉這些概念,幸運的是互聯網上有足夠的資訊。不,你不想嗎?好吧,我認為這不會成為理解正在發生的事情的大問題。畢竟,您知道測試和一般測試是什麼嗎?每次啟動任務時,您都會執行此操作,輸入初始資料並將結果與您期望看到的結果進行比較。
你好,世界JUnit!
什麼是 JUnit?在該項目的 官方網站上我們可以看到以下描述:
JUnit 是一個用於編寫可重複測試的簡單框架。它是單元測試框架的 xUnit 架構的一個實例。
對我們來說,這意味著能夠編寫專門設計的類,其方法將與我們的程式交互,將結果與參考結果進行比較,如果不匹配則通知我們。要理解原理,請考慮一個簡單的例子。假設我們有一個輔助類,其中一個方法接受兩個 int類型的變數並傳回它們的和: JUnit for JavaRush 或一些在家測試的資訊。 - 1 這是我們將嘗試測試的功能。幸運的是,我們最喜歡的IDEA 已經具備了快速建立測試所需的一切,我們所需要做的就是將遊標放在類別聲明行中,按「Alt + Enter」並在上下文選單中選擇「建立測試」:指定 JUnit for JavaRush 或一些在家測試的資訊。 - 2 位置後你應該建立一個測試,IDEA建議選擇一個測試庫(在本材料中我使用JUnit4;為了將庫類別連接到項目,你需要點擊「Fix」按鈕)、要測試的方法和其他選項。 JUnit for JavaRush 或一些在家測試的資訊。 - 3 IDE 將建立一個測試類別範本: ClassName = TestClassName + "Test" MethodName = "test" + TestMethodName JUnit for JavaRush 或一些在家測試的資訊。 - 4 我們只需要填入方法體。 JUnit 提供的所謂「斷言」方法將對此有所幫助。簡單來說,他們的工作是這樣的:預期結果和調用被測方法的結果都傳遞給 .assert* 方法;為了方便起見,您可以添加解釋性訊息作為第一個參數。如果測試期間參數不匹配,您將收到通知。您可以像常規類別一樣啟動測試類別來執行,我更喜歡使用組合鍵 Ctrl+Shift+F10 JUnit for JavaRush 或一些在家測試的資訊。 - 5
讓我們來指定任務
從理論上講,一切都是簡單而美麗的,但在所提出的示例的背景下,這並不是真正必要的;我們可以相信計算機會將兩個數字相加。我們更感興趣的是 JavaRush 學生解決的實際問題會如何發展;例如,我建議學習深受喜愛的 level05.lesson12.bonus03。
/* 演算法問題 寫一個程式: 1. 從控制台輸入數字 N > 0 2. 然後從控制台輸入 N 個數字 3. 顯示輸入的 N 個數字中的最大值。*/
我們需要寫三個測試,分別針對正數、負數和混合集。
越往森林深處...
這裡有一些驚喜等著我們: public class UtilApp { public static void main(String[] args) throws Exception { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); //напишите здесь ваш code int n; int maximum; /* Конечно же я не буду размещать решение задачи ;) Код приведенный тут переработан для наглядности, и не в коем случае не означает что он должен присутствовать в "правильном решении" */ System.out.println(maximum); } }
  • 程式邏輯放在main()方法中
  • 來源資料不會傳遞給方法,而是從鍵盤輸入。
  • main()方法不傳回結果,而是將其輸出到控制台。
如果第一點不是特別有問題(我們可以照常呼叫main()方法),那麼接下來的兩點就迫使我們深入主題,絞盡腦汁。我找到了解決該問題的幾種方法:
  1. 將查找最大值的邏輯移至單獨的方法中。
    • 優點:重構方面的正確方法
    • 缺點:程式變得過多的程式碼、不必要的結構,至少增加了一個陣列或ArrayList(取決於品味和顏色...)。僅測試尋找最大值的機制;不檢查資料輸入和輸出。
  2. 為 System.in/System.out 編寫包裝器。
    • 優點:我們不使用第三方函式庫。
    • 缺點:該路徑不適合初學者。測試實現的相對複雜性;測試中的程式碼量可能大於正在測試的任務中的程式碼量。
  3. 使用額外的庫進行測試。
    • 優點:測試中的程式碼乾淨,寫測試相對容易。被測類的原始碼沒有改變。
    • 缺點:需要將第三方函式庫連接到專案。
說實話,我最喜歡第三個選項,所以讓我們嘗試實現它。
系統規則
經過簡短的搜索,我進入了頁面 http://stefanbirkner.github.io/system-rules/,我立即意識到這就是我所需要的。
用於測試使用 java.lang.System 的程式碼的 JUnit 規則集合。
那麼, 讓我們下載這個庫。下載系統規則發揮作用所需的 Commons IO庫。我們將兩個庫連接到我們的專案(檔案-> 專案結構-> 庫-> + -> Java)並開始雕刻:啟動後,我們的任務要求您從控制台輸入N+1 個數字,其中第一個數字告訴您有多少人會跟隨他。在系統規則中,TextFromStandardInputStream類別用於這些目的。最初,我們需要將這種類型的欄位加入我們的測試類別中,並用@Rule註解標記它:然後,直接在測試方法中我們指示必要的資料 @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream();systemInMock.provideText("4\n2\n6\n1\n3\n"); 可以看到,數字以文字形式傳輸,並用連字號“\n”分隔。基於此,結果 N 將等於 4,我們將從數字 {2, 6, 1, 3} 中尋找最大值。接下來,我們需要建立被測試類別的實例並呼叫 main() 方法。我們的程式從systemInMock讀取數據,處理它並列印結果,我們要做的就是讀取它並與標準進行比較。為此,系統規則為我們提供了 StandardOutputStreamLog 類別。我們新增一個指定類型的欄位: @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); 可以使用 .getLog() 方法讀取列印的數據,同時需要考慮到換行符的存在,最終的選項可以是這樣的: assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); // or assertEquals("{2, 6, 1, 3}, max = 6", "6\r\n", log.getLog()); 在測試之間,為了避免數據分層,需要清除日誌 log.clear(); 我的測試類全文: import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.StandardOutputStreamLog; import org.junit.contrib.java.lang.system.TextFromStandardInputStream; import static org.junit.Assert.*; import static org.junit.contrib.java.lang.system.TextFromStandardInputStream.emptyStandardInputStream; public class UtilAppTest { @Rule public final TextFromStandardInputStream systemInMock = emptyStandardInputStream(); @Rule public final StandardOutputStreamLog log = new StandardOutputStreamLog(); @Test public void testAddition() throws Exception { systemInMock.provideText("4\n2\n6\n1\n3\n"); UtilApp utilApp = new UtilApp(); utilApp.main(new String[]{}); assertEquals("{2, 6, 1, 3}, max = 6", "6", log.getLog().trim()); systemInMock.provideText("5\n-100\n-6\n-15\n-183\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{-100, -6, -15, -183, -1}, max = -1", "-1", log.getLog().trim()); systemInMock.provideText("3\n2\n0\n-1\n"); log.clear(); utilApp.main(new String[]{}); assertEquals("{2, 0, -1}, max = 2", "2", log.getLog().trim()); } } 我們啟動並享受。 -=!!! 重要!!!=- 本材料僅供參考;如果任務包中存在無關的類,我不保證在伺服器上成功測試該任務。在向伺服器發送驗證任務之前,請刪除所有無關的內容:不必要的檔案、不必要的類別、註解掉的程式碼。成功完成您所建立的測試並不能保證伺服器上的測試會成功完成。我故意不去咀嚼理論材料:單元測試理論、JUnit註釋、assert等等,所有資料都在文中提供的連結中。也許您有自己的測試任務的方法,我很樂意在評論中與您討論。
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION