编码的喜悦……以及Java中的变异测试
多年以來,為源代碼編寫單元測試一直是一種好習慣。 并且還可以使用測試覆蓋率報告來查看測試覆蓋了多少代碼。 盡管行+分支覆蓋率報告非常有用,但是它并不能告訴您單元測試的實際效果。 因此,甚至在測試中沒有一個斷言的情況下,甚至有可能達到100%的覆蓋率。
對更好的測試方法感興趣,我參加了今年的“ 歡樂編碼 ”會議期間的“突變測試”研討會。
變異測試是執行和分析單元測試的結果及覆蓋范圍的一種截然不同的方法。 無需衡量單元測試“訪問了”多少代碼,而是確定單元測試實際上“測試了”多少代碼。
那么它實際上是如何工作的
變異測試背后的基本思想是對(字節)代碼進行小改動(變異),然后執行測試以查看是否被單元測試檢測到。
可能的突變是將“ > ”更改為“ >= ”,將“ ++ ”替換為“ -- ”,并刪除“ void ”方法調用。
因此,每個突變都會創建代碼的變更版本,稱為“突變”。
在進行實際的變異測試之前,首先需要針對原始代碼執行單元測試,以查看是否沒有測試失敗。
然后,將對每個“突變體”運行單元測試(這可能非常耗時),看是否:
- 我們的單元測試檢測到該突變體:測試失敗,因此“突變體”被視為“已殺死”。
- 在我們的單元測試中,突變體仍然未被注意到:測試沒有“沒有”失敗(“突變體”被認為是“存活”)并且沒有注意到突變; 這意味著單元測試實際上是“未”測試(未發現)“突變體”的。
變異測試的一個例子
那么,這種“變異測試”實際上是如何工作的呢?
請考慮以下方法:
單元測試僅包含一種測試方法:
@Test public void testFoo() {testee.foo(0); } 如果我們要創建代碼的“突變體”,將“ >= ”更改為“ > ”,該怎么辦?
我們希望我們的單元測試方法能夠檢測到這一點,對吧? 好吧,在這種情況下不是因為測試方法不包含單個斷言。
我們將更改一個“ testFoo”方法以包含一個斷言:
@Test public void testFoo() {String result = testee.foo(0);assertEquals("foo", result); }現在,我們的單元測試方法將失敗并檢測(也稱為“殺死”)“突變”代碼。
除了將“ >= ”更改為“ > ”以外,還可以創建其他“突變體”:
- 可以將第一個return方法更改為返回null (而不是"foo" );
由于使用“ assertEquals”語句,此“突變體”被“ testFoo”方法“殺死”,但仍未被注意到原始的“ testFoo”方法(沒有任何斷言)。 - 可以將第二個return方法更改為返回null (而不是"bar" );
由于沒有測試方法實際覆蓋此執行路徑,因此該“突變”將不會被注意到。
注意 :一些變異測試工具(例如Java的PIT)甚至不會費心為第二個return語句創建“變異”,因為它不會被單元測試所覆蓋(如傳統的行覆蓋率所檢測)。
等效突變導致假陽性
與傳統的行+分支覆蓋相比,突變覆蓋可能會導致假陽性。
它可能“錯誤地”報告(假陽性)單元測試未檢測到“突變”為“未”。
例如,考慮以下Java代碼:
public int someNonVoidMethod() { return 0; } public void foo() {int i = someNonVoidMethod();// do more stuff with i }在變異測試期間(使用具有某些“非”默認配置的PIT變異測試),可能會創建以下“變異”:
public int someNonVoidMethod() { return 0; } public void foo() {int i = 0;// do more stuff with i } “ mutant”中的“ int i = 0 ”語句在功能上與“ someNonVoidMethod ”返回0的原始代碼“等效”。
由于單元測試不會(也不應)失敗,因此無法檢測到這種“等效突變”。
因此,它將被報告為未覆蓋,而實際上它是一個假陽性。
根據文檔 ,在使用PIT(一種用于Java的突變測試框架)時,“等效突變”應使用“默認”的一組突變體最小化。
例如,默認情況下會禁用導致“ int i = 0 ”等效突變的PIT的“非無效方法調用突變器”。
結論
在參加了研討會,一些額外的調查并與PIT合作之后,我非常熱衷于在不久的將來在當前項目中使用“變異測試”(從新組件開始)。
與傳統的覆蓋率報告相適應,變異測試覆蓋率實際上可以衡量您的測試質量,不能像傳統的覆蓋率報告那樣被愚弄。
如果您也有興趣:
- 請查看克里斯·里默(Chris Rimmer)的這個非常有趣的演講 ,內容涉及突變測試的基本概念。
- 此外,還有一家名為TheLadders的公司使用PIT突變測試工具撰寫了一篇有趣的文章 。
- Filip van Laenen還寫了一篇有關超載雜志第108版中的“變異測試”的文章。
- 最后但并非最不重要的一點是PIT突變測試網站上的文檔。
翻譯自: https://www.javacodegeeks.com/2014/03/joy-of-coding-and-mutation-testing-in-java.html
總結
以上是生活随笔為你收集整理的编码的喜悦……以及Java中的变异测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么加回删掉的微信好友
- 下一篇: 牛排有八分熟吗 牛排分几成熟