[英]Dealing with TDD / Unit Testing fatigue
所以我已經習慣了TDD,但我遇到了一個意想不到的問題:我已經厭倦了100%的代碼覆蓋率。 編寫的代碼比代碼本身更加繁瑣,而且我不確定我是否做得對。 我的問題是: 你應該測試什么樣的東西,以及什么樣的東西是矯枉過正的?
例如,我有一個如下測試,我不確定它是否有用。 我該怎么辦才能繼續關注TDD,但又不厭倦寫測試?
describe 'PluginClass'
describe '.init(id, type, channels, version, additionalInfo, functionSource, isStub)'
it 'should return a Plugin object with correct fields'
// Create test sets
var testSets = new TestSets()
var pluginData = {
'id' : null,
'type' : null,
'channels' : null,
'version' : null,
'additionalInfo' : null,
'functionSource' : null,
'isStub' : true
}
testSets.addSet({ 'pluginData' : pluginData })
var pluginData = {
'id' : "testPlugin1",
'type' : "scanner",
'channels' : ['channelA', 'channelB'],
'version' : "1.0",
'additionalInfo' : {'test' : "testing"},
'functionSource' : "function () {alert('hi')}",
'isStub' : false
}
testSets.addSet({ 'pluginData' : pluginData })
for (var t = 0; t < testSets.getSets().length; t ++) {
var aTestSet = testSets.getSet(t)
var plugin = new Plugin().init( aTestSet.pluginData.id,
aTestSet.pluginData.type,
aTestSet.pluginData.channels,
aTestSet.pluginData.version,
aTestSet.pluginData.additionalInfo,
aTestSet.pluginData.functionSource,
aTestSet.pluginData.isStub )
plugin.getID().should.eql aTestSet.pluginData.id
plugin.getType().should.eql aTestSet.pluginData.type
plugin.getChannels().should.eql aTestSet.pluginData.channels
plugin.getVersion().should.eql aTestSet.pluginData.version
plugin.getAdditionalInfo().should.eql aTestSet.pluginData.additionalInfo
eval("fn = " + aTestSet.pluginData.functionSource)
JSON.stringify(plugin.getFunction()).should.eql JSON.stringify(fn)
plugin.getIsStub().should.eql aTestSet.pluginData.isStub
}
end
end
end
當然,上述“測試”在很多方面都是過度的。 它太長而復雜,幾乎不可讀,並且斷言太多東西。 我很難想象這是如何從TDD過程中產生的。 你厭倦了這樣的東西就不足為奇了......
測試驅動開發意味着:你應該在嬰兒的步驟,其中每一步都是一個單獨的測試,聲稱只有一件事去,絕對不含邏輯(即沒有for
, if/else
或類似的...)。 因此,上面的代碼將產生大約4-6個單獨的測試方法,然后您將逐個實現。 首先斷言正確的屬性初始化(根據需要使用不同的值),然后確保方法按預期工作,依此類推......
代碼覆蓋率指標不會告訴您有關測試的任何信息,除了它可以顯示任何測試都沒有觸及的生產代碼。 特別是它不會告訴你觸摸的代碼是否真的被測試(並且不僅僅被觸摸......)。 這僅取決於測試的質量。 因此,不要將代碼覆蓋率過於嚴重,有很多情況下,更好的測試覆蓋范圍更低,更為可取...
總而言之:對幾乎所有內容(100%覆蓋率)進行測試並不過分,但在您的示例中進行測試肯定是個問題。
我建議你回顧一下你的TDD /單元測試實踐,單元測試藝術書可能是一個很好的資源......
HTH!
托馬斯
我認為人們忘記的一件事是,通過自動化單元測試,它仍然是一種編碼實踐。 設置模板化/泛型類,基類,幫助程序類或您熟悉的任何其他常規軟件開發模式來進行單元測試是完全可以接受的。 如果你覺得你一遍又一遍地做同樣的事情,你可能就是這樣! 這是你的大腦告訴你的一個信號:“有一種更好的方式”。
所以去吧。
單元測試的目標應該是測試可能包含錯誤的代碼部分。 實現100%的測試覆蓋率不應該是一個目標,而AFAIK,TDD並沒有將其作為目標。
為不太可能包含重大錯誤的代碼創建詳盡的測試是現在和隨着系統的發展而浪費時間的繁瑣。 (將來,重復單元測試可能會成為測試本身無意義回歸的根源,只會浪費某些人的時間來查找和修復。)
最后,在將一些開發方法應用於項目時,您和您的管理層應始終使用常識 。 沒有任何方法發明將是所有問題/項目的完美契合。 你的部分工作是發現方法不能最佳運作的情況......如有必要,可以適應,甚至放棄。 在這種情況下,您/您的項目使用TDD的方式讓您瘋狂的事實清楚地表明某些事情是不對的 。
您的測試試圖一次驗證太多東西。 將其拆分為多個測試並重構您的測試代碼(是的,允許使用輔助方法)。
此外,我得到的印象是被測代碼也做得太多了。 通過使用Extract Class和Extract Method等來解耦代碼(重構)並單獨測試每個生產代碼。 您會發現這些測試將變得更少,更簡單,更容易讀寫。
看來你是
plugin.should.eql expected_plugin
應該是單獨的斷言 疲勞,懶惰和冷漠是我們避免毫無意義的工作的本能本能,例如寫瑣碎的測試,這可能就是這種情況。 嘗試停止單元測試瑣碎的東西,你應該立即感覺更好。
你的特殊考試遠非復雜。 我參與了許多項目中的代碼審查員,他們擁有數千個單元和集成測試,但還沒有看到一個項目,其中測試比實際的實時代碼更容易閱讀和理解。 TDD可讀性,“作為文檔測試”和那種承諾根本不是真的。 它很容易證明 - 嘗試通過只讀取測試或只讀取實時代碼來學習新的代碼庫。 哪種方式更全面? 正確設計的實時代碼提供了組件的完整和整體圖片,而測試只是對它的碎片斷言。
測試的唯一好處是自動化 - 對代碼的一些額外驗證,您不必手動執行/無法通過編譯器或代碼分析完成。 期。 這種好處來自於顯着的成本 - 編寫和維護測試,因此請仔細選擇要測試的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.