<sub id="l9qyp"><listing id="l9qyp"></listing></sub>

    <form id="l9qyp"><legend id="l9qyp"></legend></form>
      1. <wbr id="l9qyp"></wbr>
        1. 更多課程 選擇中心

          軟件測試培訓
          達內IT學院

          400-111-8989

          前輩支招|單元測試反反復復,到底要如何編寫單元測試?

          • 發布:樂搏-墨白
          • 來源:軟件測試資源共享
          • 時間:2018-09-03 17:58

          單元測試到底要如何編寫才能不反反復復?也許前輩的經驗對你很有用哦,前人踩過的坑你就不用再猜了,快來看吧:

          相信大家或因為社區影響、或因為上級領導的要求、抑或純粹的想挑戰自身的編碼水平,也嘗試寫過單元測試,或許都已經上了Jenkins、TravisCI等集成工具。

          想必最初看到單元測試一路綠燈的時候,自己的內心一定是愉悅的。今天又向更高的軟件質量邁進了堅實的一步!然而隨著開發的持續,單元測試逐漸變得偶爾失敗,再到持續的失敗,等大家閑下來想補下單元測試的時候,發現之前寫的測試已經祖國江山一片紅,完全不能使用了。想到又要補充大量的測試,以及去讀那些之前晦澀的測試代碼在再三的衡量工作量之后,覺得代價太大無法承擔,于是你不得不承認,寫單元測試的又一次努力最終以失敗告終。

          這種事情是不是很熟悉?甚至在我司也經歷了數次反復,摸爬滾打之后最終才調整過來。那么這些反復的出現到底是哪里出了問題?

          1、做單元測試沒有明確的目標感

          2、我知道單元測試失敗了,但是測試環境過了,業務能過

          3、不知道寫的測試失敗了

          做單元測試沒有明確的目標感

          如果我們做一件事情沒有明確的目標感,或者對做這個事的意義只有模糊的感受,那這個事情確實會變得十分難堅持下去。

          當然會有朋友指出,我寫單元測試當然有目標啊,是為了 提高軟件質量 啊,這么重要的目標怎么能說沒有呢。 但是,這真的是個目標么? 想想上學時代的晨跑、或者在背單詞的時候,不都也有“我這是為了健康”、或者“我這是為了提高英語”,為什么沒有最后堅持下來?

          因為這種目標過于遠大,以至于你感覺不到它的變化。除非有一個強大的內心,否則堅持這件事情真的會變得很難。

          那么,就讓我們把目標變得具體起來。

          以前看《把時間當做朋友》的時候,說了一個關于記單詞的有趣故事:

          因為,一共要搞定20,000個單詞,而因此可能獲得的獎學金是每年40,000美元左右——并且連續四年沒有失業可能(后來的事實是,他直到五年之后才獲得了博士學位)。當時的美元兌換人民幣的匯率差不多是8:1,所以,大約應該相當于320,000元人民幣。而如果一年的稅后收入是320,000元人民幣的話,那么稅前就要賺取差不多400,000元人民幣。那么,每個單詞應該大約值20元人民幣——這還只不過是這算了一年的收入而已。

          所以,他終于明白背單詞是非常快樂的。他每天都強迫自己背下200個單詞。而到了晚上驗收效果的時候,每在確定記住了的單詞前面畫上一個勾的時候,他就要想象一下剛剛數過一張20元人民幣的鈔票。每天睡覺的時候總感覺心滿意足,因為今天又賺了4000塊!

          如果你是 Team leader ,那么問題就變得十分簡單了:給出一條線即可:提交的代碼測試覆蓋率達到70%以上,且能跑過的代碼才是好代碼。最開始可以就是models層的單元測試。整個團隊會因為霍桑效應從而做出相應的轉變。制定這個的規定有一個技巧:不要人工的去進行評判,可以在git server 的hook 加一個腳本來進行認證。因有了人工的判斷,就會有特例,一旦開了特例,馬上就會有下一個特例,具體參見破窗理論。

          當然做出這一點的前提有兩個:首先,你自己得信單元測試,其次,你得是領導,頂得住壓力。

          如果你不是領導,那我們拿什么來說服自己寫測試呢? 當年我最初寫單元測試的目的非常簡單:避免我犯下的低級錯誤進入到代碼倉庫,被別人看到了我丟不起這人。因為自己用IDE 調試的時間與單元測試的時間實際上差不多,更重要的是,我可以向同事吹噓:我信仰自動化,我測試覆蓋率能達到XX。

          我知道單元測試失敗了,但是我測過了,業務能過

          隨著開發與測試的持續進行,幾乎所有人都發現了一個很惱火的事情 “原來寫的單元測試因為代碼的變化導致運行失敗了,但是我測過了,業務上沒問題”。

          首先有一個很重要的原則:

          一旦單元測試掛了,團隊應該首先解決這個問題。

          注意,這里是“單元測試”,而不是"UI級別的功能測試",后者以后有機會再聊。

          首先要說,單元測試為什么會掛,我總結的原因如下:

          1、由于語法錯誤導致的掛

          2、配置原因導致的掛

          3、因為代碼結構發生改變,從而導致的之前寫的單元測試失敗

          4、部分測試有一定概率的失敗,即常說的測試出現了“假摔”

          語法一旦出錯,立即去修,沒有什么好說的,因為語法出錯必然導致了部分或全部業務跑不起來。

          配置原因多半是因為測試依賴的第三方組件并沒有啟動起來,這也是大多數人不推薦數據庫的原因,我對此點的態度中立,我覺得可以依賴部分外部環境的,只要速度足夠快,沒什么不好的,畢竟在真正部署上線的時候,你也真是依賴它,如果在平時測試的時候就能熟練處理這些問題,到真正上線的時候也不會忙的手忙腳亂的。

          因為代碼結構發生改變,從而導致了測試的失敗,這種情況通常有兩種情況,第一種是我們喜聞樂見的:我們發現了過去的一個舊方法因為其他代碼的改變而發生了改變,導致了最后的處理不符合我們原先設計的這個函數的目的。這正是將測試自動化的好處,我們沒有足夠的時間精力去測我們沒有修改過的函數的正確性,但是機器可以。 這種情況沒有什么好說的修bug 就好了。第二種情況是:我非常確定對代碼的修改會影響到其他舊有函數的功能,且這個變化是我期待的正確的業務處理變更,換句話說:“測試測的是老舊的業務方式,已經不是最新的期待的函數的功能了”。這種情況對應的就是修改單元測試本身。然而這里就有個問題了,我發現隨便的修改都會導致單元測試報錯,修改單元測試的成本變得非常的高,但是需求卻是滿足的

          這就涉及到了單元測試在編寫的時候的一些問題了,這是我在寫單元測試編寫的時候的實踐:

          1、不要重復檢測已經檢測過的邏輯。

          盡量避免在A 函數的單元測試中去測試B函數的功能。這個含義非常重要,在初期我們寫單元測試的時候通常會很隨意,往往覺得這個地方有點猶豫,我就需要assert 一下,但這么做的缺點就變成了本來A函數的Test 由A來保證。舉個例子:

          it "could build adult correctly" do

          person = Person.init_adult

          assert_equal true, person.age >= 18

          end

          it "adult could buy beer" do

          person = Person.init_adult

          assert_equal true, person.age >= 18 # 又一次檢測了init_adult的正確與否

          assert_equal true, person.could_buy_beer

          end

          上面的代碼當init_adult 發生改變,age 由18 提升到了21 的時候,兩個測試會同時掛,但是這里的buy_beer 函數本身是沒有發生任何邏輯上的錯誤的,假設更多的測試用例都增加了person = Person.init_adult; assert person.age > 18的話,有可能更多的測試都會失敗,而你從眾多的測試失敗中想找到真正的測試失敗的adult_init 的難度也會變得更大。產品又催的急,很可能你就不會修復這個測試,只手動測試一下產品的邏輯,沒問題,就上線了。下次你再跑測試的時候,又發現掛一片,感覺修改無力,遂放棄,轟轟烈烈的單元測試理想就此失敗了

          2、謹慎對待私有函數的測

          對私有函數的測試我保持一個謹慎的態度。其他語言測試私有方法會比較麻煩,但是這個麻煩在ruby這門語言上是不存在了:僅僅需要調用call 就可以輕松的使用私有方法。但是我們是否要真正的測試私有方法呢?

          私有方法一定會被公開的方法調用,否則私有方法就沒有存在的意義。如果私有方法出現了問題,一定會反應到最終調用的共有方法身上。那么如果我對私有方法本身做一些優化或者修改,只要不影響到公開的方法的行為,為什么要讓測試失敗呢?同時我也認為私有方法是不穩定的,因為沒有對外公開暴露,所以這個方法隨時隨地都有可能被人修改,甚至因為其他的優化而被刪除,這樣就會導致之前對私有方法的測試莫名的掛掉。

          當然有些人覺得只要一個方法稍微復雜一點,就有必要對其進行測試,這個概念我也比較贊同,所以我中庸的贊同這樣一個方式處理

          當我不確定我新編寫的私有方法的正確性的時候,我對其寫上單元測試。同時我也會在測試旁邊備注到:如果將來你跑這個單元測試掛了的時候,請刪除掉這個測試。這樣就避免了別人在測試的時候看到這個莫名的私有方法測試失敗后又不知道如何處理的尷尬。

          關于假摔,我總結了如下的可能

          1、依賴有網絡,但網絡不穩定

          2、異步導致失敗

          3、加載順序導致的假摔

          我的想法是,在單元測試的時候,就不要有 “依賴網絡” 這個情況。如果真的有依賴網絡,請打stub,或者請從代碼編寫的時候遵循依賴注入 的原則。

          異步也是單元測試里的忌諱,我在上篇文章中已經介紹過了如何避免,這里就不再復述了。

          關于單元測試加載順序導致的假摔,一般存在于解釋型語言里,比如ruby。這主要是因為語言本身的性質決定的: ruby可以在任意時刻改變 class,但是運行單元測試的時候是在運行前加載所有的class,每個case 跑完的時候并不做重新加載。如果你在某個case中修改了某個class 的方法,其他的測試也會被影響。當你運氣好的時候,這個case 在其他受影響的case跑完后運行,測試ok,但是運氣不好的時候,后面的測試對于你來講,就變成了“莫名其妙的掛掉”。解決他的方式很簡單粗暴,改了之后記得改回來就好了。合理的使用alias_method方法會很好的解決這個問題。解決這類問題的核心的原則就是讓單元測試不依賴對case執行的順序。

          總而言之,不要讓測試掛了后大家仍然無動于衷我們人對于少數能夠快速處理的問題的時候,往往是愿意解決的,但是當問題變得巨大無比的時候,行動就變得沒那么容易了。正所謂防微杜漸就是這個道理。

          最后說一個情況,簡單卻又重要:“不知道寫的測試失敗了”。

          不知道寫的測試失敗了

          為什么寫的單元測試失敗了我們不知道?因為我們沒有運行這些單元測試。別笑,這就是事實。

          跑測試,只需要簡單的一個命令行就行了,但是我們真的隨時隨地都運行了這條命令么?并沒有。原因主要是:

          · 跑完單元測試對于過于漫長了

          · 忘記要運行測試了

          單元測試應該合理的控制時間,比較多的推薦是5mins, 最長不超過10 mins。我仍然對此時間表示巨大的懷疑,每次運行單元測試,盯著屏幕上的綠點,都有一種經歷了一次奇點爆炸到宇宙湮滅的感覺。我能忍受的速度最多是10s,于是只運行正在編寫的方法的單元測試就變成了合理的策略。但是這樣的話,其他的測試似乎又沒有運行到?答案很簡單,交給持續集成工具(CI)去做就好了

          市面上有大把的持續集成工具可以選擇,比如著名的開源軟件 jenkins,你只需要將其運行在你自己的服務器上,做出適當的配置即可;或者你覺得麻煩,甚至可以用基于SaaS 的CI 工具,比如travis.CI 以及flow.ci,簡單的幾分鐘就能搭建一套持續集成系統,連設置與機器都省了。

          我們將持續集成工具設置為當新的代碼push 進代碼倉庫的時候,就運行所有的單元測試,并最終將運行的結果郵件通知給我們。這樣,我們就可以做到既能夠足夠快速的運行我們自己想運行的單元測試結果,又能夠從稍后的郵件中得知整個單元測試的結果。

          同時,當你上了持續集成工具后,就算你自己不運行測試,工具也會在你每次push 的時候忠實的運行你之前寫的單元測試,這樣也解決了忘記跑單元測試的問題。

          當持續集成工具告訴你測試失敗的時候,這又回到了“當測試出錯的時候,我們應該怎么辦”的問題上了。再次啰嗦下:

          一旦單元測試掛了,團隊應該首先解決這個問題。

          感謝您的閱讀, 以上就是對單元測試編寫方面的問題進行的簡單總結,希望對你有所幫助!更多軟件測試相關內容,敬請關注!

          免責聲明:內容和圖片源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

          預約申請免費試聽課

          填寫下面表單即可預約申請免費試聽!怕錢不夠?可就業掙錢后再付學費! 怕學不會?助教全程陪讀,隨時解惑!擔心就業?一地學習,可全國推薦就業!

          上一篇:必備接口測試基礎知識,收好不謝!
          下一篇:在軟件測試中,我們也要注重非功能性測試!

          軟件測試必備的數據庫知識有哪些?(終)

          日志在快速定位自動化腳本故障中的重要性研究

          測試慣例是什么?怎么打破測試慣例?

          “用鼠標點點點”的測試,未來還有機會嗎?

          • 掃碼領取資料

            回復關鍵字:視頻資料

            免費領取 達內課程視頻學習資料

          • 視頻學習QQ群

            添加QQ群:1143617948

            免費領取達內課程視頻學習資料

          Copyright ? 2021 Tedu.cn All Rights Reserved 京ICP備08000853號-56 京公網安備 11010802029508號 達內時代科技集團有限公司 版權所有

          選擇城市和中心
          黑龍江省

          吉林省

          河北省

          陜西省

          湖南省

          貴州省

          云南省

          廣西省

          海南省

          奇米影视奇米色777欧美欧美一级高清片在线观看876av电影高清 百度 好搜 搜狗
          <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>