簡體   English   中英

為什么要使用JUnit進行測試?

[英]Why use JUnit for testing?

也許我的問題是一個新手,但我不能真正理解我將使用

無論我是編寫簡單的應用程序還是更大的應用程序,我都會使用System.out語句對它們進行測試,它對我來說非常容易。

為什么要在項目中創建帶有JUnit的測試類,如果我們仍然需要調用相同的方法,檢查它們返回的內容,那么我們是否需要注釋所有內容?

為什么不編寫一個類並使用System.out一次測試它但不創建Test-classes?

PS。 我從未參與過我剛剛學習的大型項目。

那么目的是什么?

那不是測試,那就是“手動查看輸出”(在商業中稱為LMAO)。 更正式地,它被稱為“手動查找異常輸出”(LMFAO)。 (見下面的注釋)

每次更改代碼時,必須為受這些更改影響的所有代碼運行應用程序和LMFAO。 即使在小型項目中,這也是有問題且容易出錯的。

現在可以在任何時候進行代碼更改時擴展到50k,250k,1m LOC或更多,以及LMFAO。 它不僅令人不愉快,而且是不可能的:你擴大了輸入,輸出,標志,條件的組合,而且很難運用所有可能的分支。

更糟糕的是,LMFAO可能意味着訪問網頁上的網頁,運行報告,瀏覽數十萬個文件和機器上的數百萬條日志行,閱讀生成和發送的電子郵件,檢查短信,檢查機器人的路徑,填寫一瓶蘇打水,匯總來自一百個網絡服務的數據,檢查金融交易的審計跟蹤......你明白了。 “輸出”並不意味着幾行文本,“輸出”意味着聚合系統行為。

最后,單元和行為測試定義系統行為。 測試可以由持續集成服務器運行並檢查其正確性。 當然, System.out也可以,但CI服務器不會知道其中一個是否錯誤 - 如果是,它們是單元測試,你也可以使用框架。

無論我們認為我們有多好,人類都不是好的單元測試框架或CI服務器。


注意:LMAO 正在測試,但是在非常有限的意義上。 在整個項目中或作為流程的一部分,它不能以任何有意義的方式重復。 它類似於在REPL中逐步開發,但從未將這些增量測試正式化。

我們編寫測試來驗證程序行為的正確性。

通過用眼睛檢查輸出語句的內容來驗證程序行為的正確性是一個手冊 ,或者更具體地說,是一個可視化過程。

你可以爭辯

視覺檢查工作 ,我檢查代碼是否做了它的意圖,對於這些場景,一旦我看到它是正確的,我們很高興去。

現在,首先,您對代碼是否正常工作感興趣。 這是好事。 你處於領先地位! 可悲的是,作為一種方法存在問題。

目視檢查的第一個問題是,你是一個糟糕的焊接事故,從而無法再次檢查你的代碼的正確性。

第二個問題是使用的眼睛與眼睛主人的大腦緊密耦合。 如果代碼的作者也擁有視覺檢查過程中使用的眼睛,則驗證正確性的過程依賴於視覺檢查員大腦中內化的程序的知識。

一雙新眼睛難以進入並驗證代碼的正確性,因為它們與原始編碼器的大腦沒有合作。 第二對眼睛的擁有者將不得不與代碼的原始作者交談 ,以便完全理解所討論的代碼。 作為分享知識的手段,對話是眾所周知的不可靠的。 如果原始編碼器不適用於新配對眼睛,那么這一點就沒有實際意義了。 在那種情況下,新的眼睛必須閱讀原始代碼。

讀取單元測試未涵蓋的其他人的代碼比閱讀具有相關單元測試的代碼更困難。 最好閱讀其他人的代碼是棘手的工作,最壞的情況是這是軟件工程中最棘手的任務。 雇主在宣傳職位空缺時強調一個項目是一個綠地(或全新)項目,這是有原因的。 從頭開始編寫代碼比修改現有代碼更容易,從而使廣告工作對潛在員工更具吸引力。

通過單元測試,我們將代碼划分為其組成部分。 對於每個組件,我們然后設置我們的停頓,說明程序應該如何表現 每個單元測試都講述了程序的這一部分應該如何在特定場景中起作用的故事。 每個單元測試就像合同中的一個條款,它描述了從客戶端代碼的角度來看應該發生什么。

這意味着一雙新眼睛在所討論的代碼上有實時和准確的文檔。

首先,他們擁有代碼本身,實現, 代碼如何完成 ; 第二,他們擁有原始程序員在一組正式陳述中描述的所有知識,這些陳述講述了這段代碼應該如何表現的故事

單元測試捕獲並正式描述原作者在實現課程時所擁有的知識。 它們提供了客戶端使用時該類行為的描述。

你是否正確地質疑這樣做是否有用,因為有可能編寫無用的單元測試,不覆蓋所有相關代碼,變得過時或過時等等。 我們如何確保單元測試不僅模仿,而且改進了知識淵博,盡職盡責的作者在運行時直觀地檢查其代碼的輸出語句的過程? 首先編寫單元測試然后編寫代碼以使測試通過。 完成后,讓計算機運行測試,他們很快就能完成重復性任務,非常適合工作。

每次觸發他們測試的代碼並運行每個構建的測試時,通過查看測試質量來確保測試質量。 如果測試失敗,請立即修復。

我們自動執行運行測試的過程,以便在每次構建項目時運行它們。 我們還自動生成代碼覆蓋率報告,詳細說明測試涵蓋和執行的代碼百分比。 我們追求高百分比。 如果代碼更改沒有足夠的單元測試來描述代碼行為的任何變化,則有些公司會阻止將代碼更改簽入到源代碼控制中。 通常,第二對眼睛將與更改的作者一起審查代碼更改。 審核人員將通過更改確保更改可以理解且充分涵蓋測試。 因此,審核流程是手動的,但是當測試(單元和集成測試以及可能的用戶驗收測試)通過此手動審核流程時,它將成為自動構建流程的一部分。 每次簽入更改時都會運行這些更改。 服務器在構建過程中執行此任務。

自動運行的測試,維護代碼行為的完整性,並有助於防止將來更改代碼庫以破壞代碼

最后,通過提供測試,您可以積極地重新調整代碼因素,因為您可以在知道更改不會破壞現有測試的情況下安全地進行大規模代碼改進。

測試驅動開發有一個警告,那就是你必須編寫代碼以使其可測試。 這涉及編碼到接口並使用諸如依賴注入之類的技術來實例化協作對象。 查看Kent Beck的工作,他很好地描述了TDD。 查找編碼到接口並研究

當您使用類似System.out之類的東西進行測試時,您只測試了一小部分可能的用例。 當您處理可以接受幾乎無限量的不同輸入的系統時,這不是很徹底。

單元測試旨在允許您使用大量不同的數據輸入快速運行應用程序上的測試。 此外,最佳單元測試還考慮了邊界情況,例如位於被認為有效邊緣的數據輸入。

對於人類來說,測試所有這些不同的輸入可能需要數周時間,而機器可能需要幾分鍾。

可以這樣想:你也沒有“測試”一些靜態的東西。 您的應用程序很可能會經歷不斷變化。 因此,這些單元測試旨在在編譯或部署周期的不同點運行。 也許最大的優勢是:

如果您在代碼中破壞了某些內容,那么您現在就會知道它,而不是在部署之后,而不是在QA測試人員發現錯誤時,而不是在您的客戶取消時。 你也有一個更好的機會立即修復故障,因為很明顯,破壞了有關代碼部分的事情很可能發生在你上次編譯之后。 因此,大大減少了解決問題所需的調查工作量。

我添加了一些其他System.out不能做:

  • 使每個測試用例獨立(這很重要)

    JUnit可以這樣做:每次創建新的測試用例實例並@Before

  • 從源代碼中分離測試代碼

    JUnit可以做到。

  • 與CI集成

    JUnit可以使用Ant和Maven來完成。

  • 輕松安排和組合測試用例

    JUnit可以做@Ignore和測試套件。

  • 易於檢查結果

    JUnit提供了許多Assert方法( assertEqualsassertSame ......)

  • 模擬和存根使您專注於測試模塊。

    JUnit可以這樣做:使用mock和stub讓你設置正確的fixture,並專注於測試模塊邏輯。

單元測試確保代碼按預期工作。 它們也非常有用,可以確保代碼仍然按預期工作,以防您以后必須更改它以構建新功能來修復錯誤。 對代碼進行高測試覆蓋后,您可以繼續開發功能,而無需執行大量手動測試。

System.out手動方法很好但不是最好的方法。這是您執行的一次性測試。 在現實世界中,需求不斷變化,並且大多數時候您對現有函數和類進行了大量修改。 所以...並不是每次你測試已經寫好的代碼片段。

還有一些比JUnit更高級的功能

斷言

JUnit提供了測試某些條件的方法,這些方法通常以斷言開頭,允許您指定錯誤消息,預期和實際結果

其中一些方法是

  1. fail([message]) - 讓測試失敗。 可能用於檢查是否未達到代碼的某個部分。 或者在實施測試代碼之前進行失敗的測試。
  2. assertTrue(true) / assertTrue(false) - 將始終為true / false。 如果測試尚未實現,可用於預定義測試結果。
  3. assertTrue([message,] condition) - 檢查布爾condition是否為真。
  4. assertEquals([message,] expected, actual) - 測試兩個值是否相等(如果實現則根據equals方法,否則使用==引用比較)。 注意:對於數組,它是檢查的引用,而不是內容,使用assertArrayEquals([message,] expected, actual)
  5. assertEquals([message,] expected, actual, delta) - 測試兩個float值或double值是否彼此相距一定距離,由delta值控制。
  6. assertNull([message,] object) - 檢查對象是否為空

等等。 看到所有示例的完整的Javadoc 在這里

套房

使用測試套件,您可以多個測試類組合到一個單元中,以便您可以一次執行所有測試類。 一個簡單的例子,將測試類MyClassTestMySecondClassTest到一個名為AllTests Suite中:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)
@SuiteClasses({ MyClassTest.class, MySecondClassTest.class })
public class AllTests { } 

JUnit的主要優點是它是自動化的,而不是您手動檢查打印輸出。 您編寫的每個測試都保留在您的系統中。 這意味着如果您進行具有意外副作用的更改,您的測試將捕獲並失敗,而不是您必須記住在每次更改后手動測試所有內容。

JUnit是Java編程語言的單元測試框架。 它在測試驅動開發中很重要,並且是一系列單元測試框架之一,統稱為xUnit。

JUnit提出了“首先測試然后編碼”的想法,強調為一段代碼設置測試數據,這些代碼可以先測試然后再實現。 這種方法就像“測試一點,代碼少,測試一點,代碼有點......”,這可以提高程序員的工作效率和程序代碼的穩定性,從而減少程序員壓力和調試時間。

功能JUnit是一個開源框架,用於編寫和運行測試。

提供注釋以標識測試方法。

提供斷言以測試預期結果。

提供用於運行測試的測試運行器。

JUnit測試允許您更快地編寫代碼,從而提高質量

JUnit非常簡單。 它不那么復雜,花費的時間也少。

JUnit測試可以自動運行,並檢查自己的結果並提供即時反饋。 無需手動梳理測試結果報告。

JUnit測試可以組織成包含測試用例甚至其他測試套件的測試套件。

Junit顯示測試進度,如果測試正常,則為綠色條,測試失敗時變為紅色。

我對JUnit需要的原因略有不同。

您實際上可以自己編寫所有測試用例,但這很麻煩。 以下是問題:

  1. 我們可以添加if(value1.equals(value2))並返回0或-1或錯誤消息,而不是System.out 在這種情況下,我們需要一個“主”測試類,它運行所有這些方法並檢查結果並維護哪些測試用例失敗以及哪些測試用例通過。

  2. 如果要添加更多測試,還需要將它們添加到此“主”測試類中。 對現有代碼的更改。 如果要從測試類中自動檢測測試用例,則需要使用反射。

  3. eclipse無法檢測到所有測試和運行測試的主類,您需要編寫自定義調試/運行配置來運行這些測試。 你仍然沒有看到那些漂亮的綠色/紅色輸出。

這是JUnit正在做的事情:

  1. 它有assertXXX()方法,可用於從條件打印有用的錯誤消息並將結果傳遞給“main”類。

  2. “main”類叫做JUnit提供的runner,所以我們不必寫任何。 它通過反射自動檢測測試方法。 如果使用@Test注釋添加新測試,則會自動檢測它們。

  3. JUnit還具有eclipse集成和maven / gradle集成,因此很容易運行測試,您不必編寫自定義運行配置。

我不是JUnit的專家,所以這就是我現在所理解的,將來會增加更多。

您不能在不使用測試框架的情況下編寫任何測試用例,否則您將不得不編寫測試框架以確保您的測試用例。 以下是有關JUnit Framework的一些信息,您可以使用TestNG框架。

什么是Junit?

Junit是一種廣泛使用的測試框架以及Java編程語言。 您可以將此自動化框架用於單元測試和UI測試。它可以幫助我們使用不同的注釋定義代碼的執行流程。 Junit建立在“首次測試然后編碼”的基礎上,這有助於我們提高測試用例的生產率和代碼的穩定性。

Junit測試的重要特征 -

  1. 它是開源測試框架,允許用戶有效地編寫和運行測試用例。
  2. 提供各種類型的注釋以識別測試方法。
  3. 提供不同類型的斷言以驗證測試用例執行的結果。
  4. 它還為測試運行者提供了有效運行測試的能力。
  5. 它非常簡單,因此節省了時間。
  6. 它提供了以測試套裝的形式組織測試用例的方法。
  7. 它以簡單而優雅的方式給出了測試用例結果。
  8. 您可以將jUnit與Eclipse,Android Studio,Maven和Ant,Gradle和Jenkins集成

JUNIT是java開發人員通常接受的方法。 如果他們可以為函數提供類似的預期輸入並相應地決定編寫的代碼是完美的寫入,或者如果測試用例失敗,則可能還需要實現不同的方法。 JUNIT將快速開發並確保功能中的0缺陷。

JUNIT:觀察和調整

這是我對JUNIT的看法。

JUNIT可以用來,
1)在該系統中添加新單元時,觀察系統行為。
2)在系統中進行調整,以歡迎系統中的“新”單元。
什么? 究竟。

現實生活,例如。

當你的親戚訪問你的大學宿舍時,
1)你會假裝更負責任。
2)你將保留所有應有的東西,比如鞋架上的鞋子不在椅子上,櫥櫃里的衣服不在椅子上。
3)你將擺脫所有的違禁品。
4)你將在你擁有的每台設備上開始清理。

在編程方面

系統:您的代碼
UNIT:新功能。
由於JUNIT框架用於JAVA語言所以JUNIT = JAVA UNIT(可能是)。

假設你已經有一個很好的防彈代碼,但是出現了新的要求,你必須在代碼中添加新的需求。 這個新要求可能會破壞您的代碼以進行某些輸入(測試用例)。

適應這種變化的簡單方法是使用單元測試(JUNIT)。
為此,您應該在構建代碼庫時為代碼編寫多個測試用例。 每當有新要求出現時,您只需運行所有測試用例以查看是否有任何測試用例失敗。 如果否,則您是BadA **藝術家,並且您已准備好部署新代碼。
如果任何測試用例失敗,則更改代碼並再次運行測試用例,直到獲得綠色狀態。

使用白盒測試方法進行單元測試。 白盒測試是一種測試軟件的方法,用於測試應用程序的內部結構或工作方式。

什么時候進行? 單元測試是第一級軟件測試,在集成測試之前執行。

https://onlyfullstack.blogspot.com/2019/02/junit-tutorial.html

https://onlyfullstack.blogspot.com/2019/02/what-is-junit-how-to-use-junit.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM