應該知道的事
- 範例使用 Java
- 這場活動使用人肉找尋變異
- 實務上應使用工具
- 但是不能完全相信工具
- 活動聯結
- 講師是 Odd-e 的姚若舟
- 簡報 preview 版
什麼是變異
前言
想像一下產品(Production
)就是你的身體,
我們可以透過健康檢查(Unit Test
);
檢查你的身體有沒有異狀 ?
但是檢查真的可靠嗎 ?
比如說一般的流感的快篩只有 50~60%的準確率,
我們的測試也無法達到 100%準確率(這裡不是指覆蓋率喔).
如何抓到測試抓不到的漏網之魚就是變異測試的目的.
我們透過讓 Production 產生變異(Mutation)
來確認我們的 Unit Test 是否可靠.
題外話,當大流行的時候會跳過快篩節省醫療資源,
因為可能有一半(50%)的患者都是流感,
而快篩準確率也只有 50%,加上時間及醫材成本,
不如直接開克流感能有效抑止疫情
變異測試(Mutation Testing)
變異後導致測試失敗?
yes , good
應該要失敗,表示你的測試有覆蓋到這個變異
no , test not covered
這表示你的測試並未
測試不一定能補捉變異
比如說 邊際值
或是 隱含的互動
;
測試覆蓋率 100%也不一定能補捉變異
要麼少了 test case,
要麼多了無意義的代碼
看看以下例子
ex:
1 | foo(x,y) |
反思一下, 測試過了代碼就沒問題 ?
不能捉到變異的測試,
有發揮它的功能嗎 ?
一般來說如果透過 TDD 進行軟體開發,
我們的測試應該是會恰巧符合一項 Test Case
而如果是先寫代碼再寫測試,
將很難通過變異測試(容易產生多餘的代碼)
找到變異的幾個方向
- 邊界條件(
<
=><=
) - 反向條件(
<
=>>
) - 移除條件(永真/永偽)
- 數學
- 遞增/遞減
- 常量
- 返回值
- 移除代碼
先寫代碼再寫測試有問題是很正常的
Kata-PokerHands 範例
原碼(使用 java)
變異實例
有問題 ,反向測試案例不足
1 | private List<Integer> getPairCardRanks(List<Integer> cardRanks) { |
有問題 , -1 但是預期中的行為
1 | protected Integer getThreeOfAKindCardRank(List<Integer\> cardRanks) { |
其它
- 沒有 TDD 沒有單元測試,別跑變異測試
- 至少要有行級別的覆蓋率(line coverage)
- 分支覆蓋(Branch Coverage)好一點 仍不夠
- 在需求不變的情況下,再作變異測試
- 以變異測試的角度來說,覆蓋率 100%是木有用的(testing coverage is useless)
- 發現變異怎麼辦
- 報告(記錄)
- 重現
- 評估
- 修改 或 補測試
- 依靠工具不要相信工具,上一步的評估
Ex: mock 物件會取代互動實際的行為,導致變異測試失敗
Tools
- http://pitest.org
- https://en.wikipedia.org/wiki/Mutation_testing
- 使用 Sonarqube with mulations test(應該不用錢)
- tudou.com/home/yaoruozhou
參與者心得
心得
- 佩服當天就能寫出文章的人
- 變異測試是好上加好的測試
- Odd-e 的講師真的很粉棒, 雖然不致到毀三觀 不過眼界大開
參考
(fin)