用置换破坏您的JUnit5测试
編寫JUnit測試可能是一個乏味而乏味的過程。 了解如何使用排列結合TestFactory方法和DynamicTest對象以最少的編碼工作來改進測試類。
在本文中,我將使用Java流ORM Speedment,因為它包含一個現成的Permutation類,從而幫助我節省了開發時間。 否則,加速可以將數據庫表連接到標準Java流。 Speedment是一個開放源代碼工具,也有免費版本供商業數據庫使用。
測試流
考慮以下JUnit5測試:
@Test void test() {List<String> actual = Stream.of("CCC", "A", "BB", "BB").filter(string -> string.length() > 1).sorted().distinct().collect(toList());List<String> expected = Arrays.asList("BB", "CCC");assertEquals(actual, expected); } 如可以看到的,該測試將創建一個Stream與所述元素“CCC”,“A”,“B-B”和‘BB’,然后應用一個過濾器,將刪除‘A’元素(因為它的長度是不大于1的)。 之后,對元素進行排序,以便流中具有元素“ BB”,“ BB”和“ CCC”。 然后,應用獨特的操作,刪除流中的所有重復項,在調用最終終止運算符之前保留元素“ BB”和“ CCC”,從而將這些其余元素收集到
List 。
經過一番考慮,可以理解,中間操作filter() , sorted()和distinct()的應用sorted()無關緊要。 因此,無論操作員應用程序的順序如何,我們都期望得到相同的結果。
但是,我們如何才能找到一個JUnit5測試來證明該順序對于所有排列都是無關緊要的,而無需手動為所有六個排列編寫單獨的測試用例?
使用TestFactory
除了編寫單個測試,我們還可以使用TestFactory生成任意數量的DynamicTest對象。 這是演示該概念的簡短示例:
@TestFactory Stream<DynamicTest> testDynamicTestStream() {return Stream.of(DynamicTest.dynamicTest("A", () -> assertEquals("A", "A")),DynamicTest.dynamicTest("B", () -> assertEquals("B", "B"))); } 這將產生兩個可能毫無意義的名為“ A”和“ B”的測試。 請注意,我們如何方便地返回DynamicTest對象Stream ,而無需先將它們收集到
諸如List Collection 。
使用排列
Permutation類可用于創建任何類型T所有可能組合。 這是帶有類型的簡單示例
String :
因為Permutation創建了類型為T的Stream的Stream ,所以我們添加了一個中間映射操作,將內部Stream收集到List 。 上面的代碼將產生以下輸出:
[A, B, C] [A, C, B] [B, A, C] [B, C, A] [C, A, B] [C, B, A]容易證明,這是將“ A”,“ B”和“ C”組合在一起的所有方式,每個要素應恰好發生一次。
創建運算符
在本文中,我選擇為中間操作創建Java對象,而不是使用lambda,因為我想覆蓋toString()方法并將其用于方法標識。 在其他情況下,直接使用lambda或方法引用就足夠了:
UnaryOperator<Stream<String>> FILTER_OP = new UnaryOperator<Stream<String>>() {@Overridepublic Stream<String> apply(Stream<String> s) {return s.filter(string -> string.length() > 1);}@Overridepublic String toString() {return "filter";}};UnaryOperator<Stream<String>> DISTINCT_OP = new UnaryOperator<Stream<String>>() {@Overridepublic Stream<String> apply(Stream<String> s) {return s.distinct();}@Overridepublic String toString() {return "distinct";} };UnaryOperator<Stream<String>> SORTED_OP = new UnaryOperator<Stream<String>>() {@Overridepublic Stream<String> apply(Stream<String> s) {return s.sorted();}@Overridepublic String toString() {return "sorted";} };測試排列
現在,我們可以輕松地在運算符上測試置換的工作方式:
void printAllPermutations() {Permutation.of(FILTER_OP,DISTINCT_OP,SORTED_OP).map(is -> is.collect(toList())).forEach(System.out::println); }這將產生以下輸出:
[filter, distinct, sorted] [filter, sorted, distinct] [distinct, filter, sorted] [distinct, sorted, filter] [sorted, filter, distinct] [sorted, distinct, filter]可以看出,這些都是我們要測試的中間操作的置換。
拼接起來
通過結合以上學習,我們可以創建TestFactory ,以測試應用于初始流的中間操作的所有排列:
@TestFactory Stream<DynamicTest> testAllPermutations() {List<String> expected = Arrays.asList("BB", "CCC");return Permutation.of(FILTER_OP,DISTINCT_OP,SORTED_OP).map(is -> is.collect(toList())).map(l -> DynamicTest.dynamicTest(l.toString(),() -> {List<String> actual = l.stream().reduce(Stream.of("CCC", "A", "BB", "BB"),(s, oper) -> oper.apply(s),(a, b) -> a).collect(toList());assertEquals(expected, actual);})); } 請注意我們如何使用Stream::reduce方法將中間操作逐步應用于初始Stream.of("CCC", "A", "BB", "BB") 。 合路器lambda
(a, b) -> a只是一個虛擬對象,僅用于合并并行流(此處未使用)。
爆炸警告
最后,對置換的內在數學復雜性提出了警告。 根據定義,排列的復雜度為O(n!) ,例如,僅將一個元素添加到現有的八個元素的排列中,排列的數量將從40,320增加到362,880。
這是一把雙刃劍。 我們幾乎免費地獲得了許多測試,但是我們必須付出在每個構建上執行每個測試的代價。
碼
測試的源代碼可以在這里找到。
可以在這里下載Speedment ORM
結論
Permutation , DynamicTest和TestFactory類是用于創建編程JUnit5測試的出色構建塊。
注意不要在排列中使用太多元素。 “炸毀”可能意味著兩件事……
翻譯自: https://www.javacodegeeks.com/2018/10/blow-junit5-tests-permutations.html
總結
以上是生活随笔為你收集整理的用置换破坏您的JUnit5测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓最高系统版本(安卓最高系统)
- 下一篇: servlet异步_如何使用异步Serv