JUnit理论简介
您讀過數學理論嗎?
它通常讀取如下內容:
對于所有a,b> 0滿足以下條件:a + b> a和a + b> b
通常,這些語句更難以理解。
這種陳述有一些有趣之處:它適用于相當大(在這種情況下為無限)集合的每個元素(或元素組合)。
將其與典型測試的陳述進行比較:
@Testpublic void a_plus_b_is_greater_than_a_and_greater_than_b(){int a = 2;int b = 3;assertTrue(a + b > a);assertTrue(a + b > b);}這僅是關于我們所討論的大集合中單個元素的陳述。 不太令人印象深刻。 當然,我們可以通過遍歷測試(或使用參數化測試 )來解決此問題:
@Testpublic void a_plus_b_is_greater_than_a_and_greater_than_b_multiple_values() {List<Integer> values = Arrays.asList(1, 2, 300, 400000);for (Integer a : values)for (Integer b : values) {assertTrue(a + b > a);assertTrue(a + b > b);}}當然,這仍然僅測試了幾個值,但也變得非常難看。 我們正在使用9行代碼來測試數學家在一行中寫的內容! 這種關系對于任何值a,b都應保持的要點在翻譯中完全消失了。
但是還是有希望的: JUnit理論 。 讓我們看看使用該工具的測試效果:
import org.junit.experimental.theories.DataPoints; import org.junit.experimental.theories.Theories; import org.junit.experimental.theories.Theory; import org.junit.runner.RunWith;import static org.junit.Assert.assertTrue;@RunWith(Theories.class) public class AdditionWithTheoriesTest {@DataPointspublic static int[] positiveIntegers() {return new int[]{1, 10, 1234567};}@Theorypublic void a_plus_b_is_greater_than_a_and_greater_than_b(Integer a, Integer b) {assertTrue(a + b > a);assertTrue(a + b > b);} }使用JUnit理論,測試分為兩個獨立的部分:提供數據點(即用于測試的值)的方法以及理論本身。 該理論看起來幾乎像一個測試,但是它具有不同的注釋(@Theory),并且需要參數。 類中的理論將與數據點的每種可能組合一起執行。
這意味著,如果我們對測試主題有一個以上的理論,則只需聲明一次數據點即可。 因此,讓我們添加以下理論,這對于加法而言應該是正確的:a + b = b + a因此,我們將以下理論添加到我們的類中@Theory public void add_is_commutative(Integer a,Integer b){assertTrue(a + b == b + a); }
這就像一種魅力,并且可以開始看到它實際上也節省了一些代碼,因為我們不重復數據點。 但是,我們僅使用正整數進行測試,而交換屬性應適用于所有整數! 當然,我們的第一個理論仍然只適用于正數
也有一個解決方案: 假設 。 假設您可以檢查理論的先決條件。 如果對于給定的參數集不正確,則該參數集的理論將被跳過。 所以我們的測試現在看起來像這樣:
@RunWith(Theories.class)public class AdditionWithTheoriesTest {@DataPointspublic static int[] integers() {return new int[]{-1, -10, -1234567,1, 10, 1234567};}@Theorypublic void a_plus_b_is_greater_than_a_and_greater_than_b(Integer a, Integer b) {Assume.assumeTrue(a >0 && b > 0 );assertTrue(a + b > a);assertTrue(a + b > b);}@Theorypublic void addition_is_commutative(Integer a, Integer b) {assertTrue(a + b == b + a);} }這使測試表現力很好。
將測試數據與測試/理論實現分開,除了簡潔之外,還可以帶來另一個積極的效果:您可能會開始考慮與實際測試內容無關的測試數據。
讓我們做到這一點。 如果要測試采用整數參數的方法,那么哪些整數可能會引起問題? 這是我的建議:
@DataPointspublic static int[] integers() {return new int[]{0, -1, -10, -1234567,1, 10, 1234567, Integer.MAX_VALUE, Integer.MIN_VALUE};}在我們的示例中,哪個當然會導致測試失敗。 如果將正整數添加到Integer.MAX_VALUE,則會溢出! 因此,我們剛剛得知我們目前的理論是錯誤的! 是的,我知道這很明顯,但是請看一下當前項目中的測試。 使用整數的所有測試是否都以MIN_VALUE,MAX_VALUE,0,正值和負值測試? 是的,是這樣。
那更復雜的對象呢? 琴弦? 日期? 收藏? 還是領域對象? 使用JUnit Theories,您可以設置測試數據生成器一次,創建所有容易出現問題的場景,然后使用這些理論在所有測試中重用這些場景。 這將使您的測試更具表現力,并提高發現錯誤的可能性。
翻譯自: https://www.javacodegeeks.com/2013/12/introduction-to-junit-theories.html
總結
- 上一篇: 舟方读什么 舟方是什么字
- 下一篇: JBoss Fuse 6.1 + Haw