• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 新聞中心

    EEPW首頁 > 測試測量 > 設(shè)計(jì)應(yīng)用 > 嵌入C語言的測試驅(qū)動開發(fā):為什么要調(diào)試?

    嵌入C語言的測試驅(qū)動開發(fā):為什么要調(diào)試?

    作者: 時間:2017-06-03 來源:網(wǎng)絡(luò) 收藏

    要點(diǎn)

    本文引用地址:http://www.czjhyjcfj.com/article/201706/347781.htm

    1.為什么你會遇上這些bug?因?yàn)樗鼈兪悄惴诺摹?/p>


    2.在(的開發(fā))中,你會在一個嚴(yán)格的反饋循環(huán)中,開發(fā)測試與生產(chǎn)代碼。


    3.可能有助于避免惱人的Zune bug。


    4.目標(biāo)硬件瓶頸有多種形式,你可以在嚴(yán)格的反饋循環(huán)中,用TDD來避開瓶頸。


    5.TDD幫助你確保自己的代碼如期望那樣運(yùn)行。但如果不是這樣,你該如何建立一個可靠的系統(tǒng)?


    6.TDD快速地發(fā)現(xiàn)小的和大的邏輯錯誤,防止出現(xiàn)bug,使最終得到較少的bug。


    我們的工作方式都是編寫代碼,然后努力讓它運(yùn)行起來。先建立,然后改錯。測試是以后的事,即寫完代碼后才要做的事。在不可預(yù)期的調(diào)試工作上,大概要花掉我們一半的時間。在日程表上,調(diào)試工作都穿著測試與集成的外衣。它是風(fēng)險與不確定性的一個來源。修正了一個bug可能會產(chǎn)生另一個bug,有時甚至是一連串的bug。


    保持調(diào)試的統(tǒng)計(jì)有助于預(yù)測要花多少時間才能消除bug。你要度量和管理bug。看曲線的拐點(diǎn),拐點(diǎn)表示了趨勢,告訴你最后修正的bug要比產(chǎn)生的多。拐點(diǎn)表示的是已經(jīng)做的事,但你永遠(yuǎn)不知道是否在代碼的某個陰暗角落還躲藏著其它的致命bug。


    可制造性設(shè)計(jì)的一個方面是確定為什么你會有這些bug。答案很簡單:錯誤是我們放進(jìn)去的。這就是我們的工作方式。在開發(fā)以后的測試時,就會發(fā)現(xiàn)問題(圖1和參考文獻(xiàn)1)。我們在開發(fā)時會制造錯誤,測試的工作就是找到這些問題。只要仔細(xì)地測試,就會發(fā)現(xiàn)錯誤。開發(fā)后的測試工作意味著必須找到、修復(fù)和管理大量的錯誤。

    圖1,在開發(fā)以后做測試時,會發(fā)現(xiàn)缺陷


    這種調(diào)試居后的編程程序是當(dāng)今最常見的編程方式。先寫代碼,再調(diào)試它。調(diào)試居后的編程方式有風(fēng)險。人都會犯錯誤。你既不能確定bug將在何時現(xiàn)身,也不能確定會花多長時間才能發(fā)現(xiàn)它們(圖2)。

    圖2,人都會犯錯誤。你無法確定bug何時出現(xiàn),以及要花多少時間才能找到它們


    當(dāng)發(fā)現(xiàn)一個bug的時間(TD)增加時,尋找bug根源的時間(TFIND)也會增加,通常增加得更多。如果從錯誤的引入到發(fā)現(xiàn)要花數(shù)小時、數(shù)天、數(shù)周,甚至數(shù)月時間,你已忘掉了當(dāng)時的背景,必須開始做bug大掃蕩。當(dāng)你在開發(fā)周期以外發(fā)現(xiàn)缺陷時,就必須管理bug。對于有些bug,發(fā)現(xiàn)的時間不會影響修復(fù)的時間(TFIX),但有些代碼的運(yùn)行也可能依賴于bug,修改這些bug會造成其它bug。


    短周期以及主動的測試自動化可節(jié)省時間和工作量。這時,你再不需要重復(fù)繁重而易錯的手工測試。有了測試自動化,重復(fù)測試幾乎不會增加額外工作量。測試自動化快速地探測出副作用,避免了對調(diào)試事務(wù)的需求。


    另一種方案是TDD(的開發(fā)),它在一個嚴(yán)格反饋的循環(huán)中開發(fā)出測試代碼與生產(chǎn)代碼(參考文獻(xiàn)2和3)。一個TDD微循環(huán)是:編寫一個測試,未編譯時觀察該測試,做編譯且測試失敗,使編譯通過,清除任何多余內(nèi)容,并重復(fù)該過程直至結(jié)束。編寫測試代碼與編寫生產(chǎn)代碼是整合的過程。如果犯了一個錯誤,沒有通過新測試,你馬上就可以知道并改正錯誤。測試會告訴你是否通過了新測試卻產(chǎn)生了某個錯誤。在設(shè)備測試裝置中加入自動化測試(圖3),就可以自由地做重復(fù)測試。


    圖3,測試會告訴你是否通過了新的測試,但卻引入了一個bug。自動測試要插入到一個單元測試裝置中

    在TDD反饋回路中做開發(fā)與測試時,只能避免一部分bug的出現(xiàn),但不能完全消除。TDD對設(shè)計(jì)以及時間的分配方式有著意義深遠(yuǎn)的影響。


    與后調(diào)試的編程模式相反,TDD并不包含追蹤錯誤的風(fēng)險與不確定性(圖4)。當(dāng)發(fā)現(xiàn)一個錯誤的時間接近于0時,尋找錯誤根源的時間也會趨于0。剛產(chǎn)生的代碼問題通常顯而易見。如果不那么明顯,則開發(fā)人員只要簡單地恢復(fù)剛做的修改,就可以回到一個可運(yùn)行的系統(tǒng)。尋找和修改錯誤的時間和產(chǎn)生的時間一樣少,只有當(dāng)程序員記憶隨時間而模糊,并且有更多的代碼依賴于較早的錯誤時,事件才會變糟。


    TDD為錯誤提供了即時的通知,可防止出現(xiàn)很多要被迫追蹤的bug。TDD可防止出現(xiàn)缺陷,而后調(diào)試編程會帶來耗時耗力的調(diào)試工作。

    Zune bug


    TDD可能有助于避免惱人的Zunebug。微軟公司的Zune是為了與蘋果公司的iPod競爭。2008年12月31日,Zune變成了“專為一天的程序塊(abrick for a day)”。12月31日是新年前夜,是一個閏年的最后一天,這是30G Zune要經(jīng)歷的第一個閏年。很多人都將Zune錯誤歸因于時鐘驅(qū)動程序中的一個函數(shù)。雖然列表1中的代碼并非實(shí)際的驅(qū)動程序碼,但它有相同的效果。你可以從列表1中Zune的無限循環(huán)中找到一些端倪嗎?


    圖4,TDD對于設(shè)計(jì)以及時間的使用有深遠(yuǎn)的影響。與調(diào)試居后的編程模式比較,TDD

    沒有回溯追蹤bug的風(fēng)險與不確定性


    圖5,對快速反饋的需求使TDD微循環(huán)離開目標(biāo)硬件,而原生地運(yùn)行在開發(fā)系統(tǒng)上。一個TDD循環(huán)包括雙重目標(biāo)的風(fēng)險,但提供了快速TDD反饋回路的好處

    很多代碼閱讀專家審查了這個代碼,并得出了可能與您一樣的錯誤結(jié)論。閆年的最后一天是該年第366天,而Zune對這種情況的處理是錯誤的。在這一天,該函數(shù)永遠(yuǎn)不會返回!我編寫了設(shè)定年份以及年中天數(shù)的代碼,看是否像90%的Zune bug專家預(yù)測的那樣,將天數(shù)的布爾代碼設(shè)定為等于或大于366就能解決問題。代碼放入測試裝置后,我編寫了測試用例(列表2)。和Zune一樣,測試進(jìn)入了一個無限循環(huán)。我采用了經(jīng)過數(shù)千名程序員審核的適當(dāng)修復(fù)方法。出乎我的意料,測試失敗了;設(shè)定年份與天數(shù)的測試認(rèn)為日期是2009年1月0日。新年前夜,人們?nèi)詴碛凶约旱囊魳罚玓une仍有個bug。

    一次測試就可以防止Zune bug。可你怎么知道要去寫這樣一個測試?只有知道bug在哪里才會寫測試。問題是,你并不知道bug在哪里;它們可以在任何地方。所以,這意味著你必須為所有的部分寫測試,至少是所有可能中斷的地方。難以想象要考慮到所有需要測試的東西。但不必?fù)?dān)心,你不需要針對全年每一天做測試。你只需要一個針對有關(guān)天數(shù)的測試。


    計(jì)算機(jī)編程很復(fù)雜,TDD能夠系統(tǒng)化地讓你的代碼按本意運(yùn)行起來,并提供能使代碼工作的自動化測試用例。


    嵌入設(shè)計(jì)


    當(dāng)我首次使用TDD時,我認(rèn)識到,它可能有助于解決一個問題:目標(biāo)硬件的瓶頸,這是令很多嵌入軟件開發(fā)人員頭疼的事情。瓶頸有多種形式,你可以使用TDD,在嚴(yán)格的TDD反饋循環(huán)期間避免瓶頸的出現(xiàn)。很多嵌入開發(fā)工作都已實(shí)現(xiàn)了軟硬件的并行開發(fā)。如果軟件只能在目標(biāo)硬件上運(yùn)行,則可能浪費(fèi)至少一次的時間。例如,目標(biāo)硬件可能遲至交付期還不可用,推遲了軟件的測試;硬件可能昂貴且稀少;或者它本身就有問題。目標(biāo)硬件還可能有長的建立時間或長的上傳時間。大多數(shù)嵌入開發(fā)團(tuán)隊(duì)都遇到過這些問題,它們會減緩進(jìn)度,并減少了建立今天復(fù)雜系統(tǒng)的反饋。


    為避免目標(biāo)硬件的瓶頸,可以采用“雙重目標(biāo)”法,即設(shè)計(jì)自己的生產(chǎn)代碼與測試,使之大部分運(yùn)行在標(biāo)準(zhǔn)PC上。但雙重目標(biāo)有自己的風(fēng)險。開發(fā)系統(tǒng)中測試代碼的信任度是建立在交付給目標(biāo)以前的代碼上。大多數(shù)雙重目標(biāo)風(fēng)險是源于開發(fā)環(huán)境與目標(biāo)環(huán)境之間的差異。這些差異包括對語言特性支持的改變量、不同編譯器的bug、運(yùn)行時庫的差異、文件名差異,以及不同的字長等。由于這些風(fēng)險,你會發(fā)現(xiàn),在一個環(huán)境下能無錯運(yùn)行的代碼,可能在另一個環(huán)境下出現(xiàn)測試錯誤。

    不過,執(zhí)行環(huán)境中潛在的差異不應(yīng)成為阻礙采用雙重目標(biāo)方法的理由。相反,你可以在實(shí)現(xiàn)目標(biāo)的路途中解決這些障礙。嵌入TDD周期在不犧牲優(yōu)點(diǎn)的前提下,克服了挑戰(zhàn)。


    開發(fā)循環(huán)


    當(dāng)建立與測試循環(huán)只需幾秒時間時,TDD是最有效的。這種方案為大多數(shù)程序員排除了在循環(huán)中使用目標(biāo)硬件的情況。快速反饋的需求將TDD微循環(huán)與目標(biāo)分離開,而運(yùn)行在開發(fā)系統(tǒng)上。圖5顯示了一個TDD循環(huán),它包含著雙重目標(biāo)的風(fēng)險,提供了快速TDD反饋循環(huán)的好處。

    表1中所列的各個階段,預(yù)計(jì)可以在相應(yīng)的階段發(fā)現(xiàn)問題。例如,你會發(fā)現(xiàn)每個階段都有助于找到這些問題。第1階段會在你編程時給出快速反饋,確定代碼做你想要做的事。第2階段確保你的代碼是在兩種環(huán)境下編譯。第3階段確保代碼在主處理器和目標(biāo)處理器上的運(yùn)行相同。評估硬件可能需要比目標(biāo)更多的存儲器,這樣才能把測試代碼和生產(chǎn)代碼都裝入地址空間。有時候,如果你有一個可靠的目標(biāo)硬件,它有空間運(yùn)行對單元的測試,也可以省略掉第3階段。第4階段是在目標(biāo)硬件上運(yùn)行測試。在第4階段可以引入一些依賴于硬件的單元測試。第5階段是看你的系統(tǒng)完全整合時,是否如其應(yīng)該的那樣運(yùn)行。至少讓第5階段的某些部分自動運(yùn)行,這是一種好的想法。采用TDD的團(tuán)隊(duì)會發(fā)現(xiàn)第1階段中的巨大價值,可能不要實(shí)現(xiàn)全部各個階段。


    嵌入TDD循環(huán)并不能阻止所有問題,不過它應(yīng)有助于在適當(dāng)?shù)碾A段發(fā)現(xiàn)大多數(shù)剛剛產(chǎn)生的問題。你還應(yīng)至少每個夜晚手動執(zhí)行第2至第4階段。連續(xù)的集成服務(wù)器(如Cruise Control或Jenkins)都可以觀察你的源碼庫,在check-in后開始做建立工作。


    TDD有助于確保你的代碼做你想要做的事。如果不是這樣,如何才能建立一個可靠的系統(tǒng)呢?它幫助你讓代碼在最開始時保持正確,它建立一個逐步測試的組件,幫助你維持代碼的運(yùn)行。你在發(fā)現(xiàn)、追蹤和修改bug上要花掉相當(dāng)多的時間。很多開發(fā)人員現(xiàn)在都用TDD來防止這些bug的出現(xiàn)。它基本上改變了你的編程方式。


    TDD能快速地發(fā)現(xiàn)小的和大的邏輯錯誤,阻止bug的產(chǎn)生,并最終得到較少的bug。較少的bug也意味著較少的調(diào)試時間,以及較少的缺陷。當(dāng)新代碼危及一個約束或一個假設(shè)時,測試會告訴你。然后,有良好結(jié)構(gòu)的測試會成為一種形式的可執(zhí)行文檔。


    TDD還讓你放心,這種信心來自于一個帶有完備回歸測試組件的徹底測試代碼。采用TDD的開發(fā)人員稱周末不再受干擾,并且睡眠更好。TDD還監(jiān)控進(jìn)度,追蹤當(dāng)前的工作,以及做了多少工作。當(dāng)代碼變得難以測試時,它還對設(shè)計(jì)問題提出早期警告。



    關(guān)鍵詞: C語言 TDD 測試驅(qū)動

    評論


    相關(guān)推薦

    技術(shù)專區(qū)

    關(guān)閉
    主站蜘蛛池模板: 滨海县| 汉寿县| 邯郸市| 桂阳县| 新平| 和田县| 额敏县| 黔西县| 莒南县| 东丰县| 全州县| 锡林浩特市| 榆树市| 新余市| 博客| 抚州市| 平昌县| 伊通| 句容市| 山西省| 邓州市| 嵊州市| 江西省| 海林市| 保德县| 清徐县| 浦县| 如皋市| 龙陵县| 广州市| 永靖县| 永昌县| 无为县| 舞阳县| 衡水市| 邢台市| 丹江口市| 临清市| 霍山县| 嘉义县| 马边|