只要一提到關(guān)于軟件質(zhì)量的問題,會(huì)有人問到這個(gè)問題。有些學(xué)生想知道進(jìn)行多少測試才行。對于那些認(rèn)為測試只是在浪費(fèi)時(shí)間或吹毛求疵的學(xué)生,我會(huì)給他們一個(gè)機(jī)會(huì)讓他們以測試工作量小(有時(shí)甚至是沒有)的策略來完成他們的軟件工程的課程項(xiàng)目 。

  我的學(xué)生經(jīng)常向我說起他們的模塊和類編寫得多么巧妙,他們是如何認(rèn)真地遵守了建模原則。有許多學(xué)生還使用了UML(Unified Modeling Language,統(tǒng)一建模語言)圖來幫助自己進(jìn)行開發(fā)。這些做法都很好,但測試絕不僅僅是保證你的源代碼與你的模型相匹配那么簡單。有不少對自己的編程技巧很自信的學(xué)生交上來的作業(yè)經(jīng)常存在著一些功能方面的小毛病。雖然那些小毛病一般不至于引發(fā)致命錯(cuò)誤或崩潰(這在開發(fā)工作中經(jīng)常會(huì)遇到),但在集成和軟件的運(yùn)行方面經(jīng)常出問題。也是說,這些學(xué)生沒能做到讓他們的軟件按照顧客希望的那樣工作。

  如果你對這種場景很熟悉,說明你已經(jīng)了解了軟件測試的價(jià)值。軟件測試的形式有很多,目的都是保證和控制軟件的質(zhì)量。在什么時(shí)候選擇什么技術(shù)進(jìn)行測試是軟件測試學(xué)需要解決的根本問題。

  提示 如果你還沒有過從測試入手進(jìn)行軟件開發(fā)或是與一位專業(yè)軟件測試人員合作的經(jīng)歷,我建議你趕快去找一位這方面的專業(yè)人士。他們對軟件的故障往往有著超常的洞察力,很少有開發(fā)人員能做到像他們一樣。不要因?yàn)樗麄冎赋隽四愦a中的缺陷而感到羞愧--那是他們的工作,而且他們都精于此道!

  1、測試與調(diào)試

  有不少人把“測試”和“調(diào)試”混為一談。雖然它們的目標(biāo)是同一個(gè)--找出缺陷,但它們并不是一回事。調(diào)試是一種交互式的過程,是通過分析源代碼的內(nèi)部工作情況去尋找源代碼邏輯中的缺陷。測試是通過執(zhí)行源代碼去發(fā)現(xiàn)其中隱藏著的缺陷,不需要分析源代碼的內(nèi)部工作情況。

  2、測試驅(qū)動(dòng)開發(fā)

  測試驅(qū)動(dòng)開發(fā)(test-driven development)通常與敏捷編程技術(shù)相關(guān)。事實(shí)上,測試驅(qū)動(dòng)開發(fā)在采用極限編程(extreme programming,XP)方法的軟件公司里為常見。這聽起來有點(diǎn)兒唬人,我可以向你透露一個(gè)關(guān)于XP的秘密:你不必采用XP方法也可以進(jìn)行敏捷編程。

  因?yàn)榉磳φ卟回?fù)責(zé)任的言辭,有不少人對敏捷編程技術(shù)持很深的懷疑態(tài)度。傳統(tǒng)的軟件工程方法學(xué)在理論和實(shí)踐方面的成功是有目共睹的,人們把它奉為“金科玉律”也情有可原,但僅憑一知半解把敏捷開發(fā)技術(shù)與偷工減料和質(zhì)量低劣等同起來是毫無道理的,因?yàn)槭聦?shí)完全不是這樣。

  敏捷開發(fā)技術(shù)的核心概念是大限度地減少軟件開發(fā)過程中的不必要環(huán)節(jié),重視與顧客的交流,只在需要的時(shí)候才編寫需要的功能,把工作的重點(diǎn)放在滿足客戶此時(shí)此刻的需求上。敏捷開發(fā)技術(shù)圍繞著顧客展開,具體過程并不是它關(guān)心的焦點(diǎn)。敏捷開發(fā)技術(shù)可以全面推廣,也可以有選擇地在小范圍應(yīng)用。換句話說,在轉(zhuǎn)向敏捷開發(fā)技術(shù)的時(shí)候,軟件公司應(yīng)該根據(jù)自己的具體情況摸著石頭過河,而不是一下扎進(jìn)自己不熟悉的技術(shù)中,那會(huì)讓它們的開發(fā)人員感到難以適應(yīng)。欲速則不達(dá),有不少軟件公司是因?yàn)樵诮蛹{敏捷開發(fā)技術(shù)方面太過急于求成才會(huì)陷入困境。正是因?yàn)檫@類負(fù)面案例時(shí)有發(fā)生,才會(huì)有人反對或懷疑敏捷開發(fā)技術(shù) 。如果想了解關(guān)于敏捷開發(fā)技術(shù)與傳統(tǒng)方法孰優(yōu)孰劣之爭的更多情況,請?jiān)L問Agile Alliance網(wǎng)站www.agilealliance.org。

  在各種敏捷開發(fā)技術(shù)當(dāng)中,有用的要屬測試驅(qū)動(dòng)開發(fā)技術(shù)了。測試驅(qū)動(dòng)開發(fā)技術(shù)的基本思路很簡單:從整個(gè)解決方案的一個(gè)基本模塊開始,編寫測試,運(yùn)行測試,編寫解決方案,用測試來驗(yàn)證它確實(shí)能夠解決問題。這個(gè)過程聽起來不難理解,但在實(shí)踐中往往會(huì)變得相當(dāng)復(fù)雜。在編寫代碼之前先編寫測試讓人有一種本末倒置的感覺--如果某個(gè)東西不存在,我們該如何去測試它呢?這么做真的有用嗎?先行開發(fā)有關(guān)測試可以讓你把精力集中到你的軟件設(shè)計(jì)方案而不是代碼上。我將解釋一個(gè)典型的測試驅(qū)動(dòng)開發(fā)過程,讓大家看看測試驅(qū)動(dòng)開發(fā)技術(shù)是如何緊扣設(shè)計(jì)方案并“驅(qū)動(dòng)”程序員編寫出源代碼的。我知道這聽起來有點(diǎn)兒奇怪,但我希望大家能給我個(gè)機(jī)會(huì)來證明它是有道理的。

  測試驅(qū)動(dòng)開發(fā)活動(dòng)從整個(gè)系統(tǒng)的一個(gè)簡單模塊開始。用一個(gè)簡單的類圖把系統(tǒng)里的各個(gè)基本類以及它們之間的關(guān)系畫出來。在這個(gè)類圖中,除了一個(gè)暫定的類名外,各個(gè)類的代碼塊部分可以是空白。我說“暫定”是因?yàn)檫@通常是采用傳統(tǒng)方法的程序員感到困惑的地方。在敏捷開發(fā)技術(shù)里,沒有什么是固定不變的,什么東西都允許修改。簡單地說,只要能把顧客需要的軟件交付給顧客,做什么都行。

  設(shè)計(jì)好初的類關(guān)系框圖之后,把它復(fù)制下來放在旁邊,它是所謂的“域模型”(domain model);它確定了整個(gè)系統(tǒng)中類的初始布局。接下來創(chuàng)建用例圖(use case diagram)和輔助用例場景(用例及各種執(zhí)行順序的文本描述)。然后每個(gè)都用一個(gè)順序圖來擴(kuò)充,這制定出了所引用的類需要的函數(shù)。

  等每一個(gè)類都大致成形之后,可以開始編寫測試了。是的,雖然那些類還都不存在,你仍然可以為它們編寫測試。這些測試包括對域模型中的每一個(gè)類進(jìn)行集成測試、系統(tǒng)測試和接口測試(它們都屬于黑盒測試)。

  注解 黑盒測試是在不了解系統(tǒng)內(nèi)部構(gòu)造的情況下進(jìn)行的測試。白盒測試是在了解系統(tǒng)內(nèi)部結(jié)構(gòu)的情況下對其行為進(jìn)行的測試。

  絕大多數(shù)以敏捷開發(fā)技術(shù)開發(fā)的項(xiàng)目而言,從這個(gè)過程的第一遍循環(huán)里學(xué)到的東西是在這個(gè)時(shí)候融合到設(shè)計(jì)方案的相關(guān)部分(用例圖、順序圖,等等)中并根據(jù)具體情況做出調(diào)整的。

  注解 有些敏捷程序員還會(huì)使用健壯性圖(robustness diagram)給這個(gè)過程增加一個(gè)建模步驟。這種做法與ICONIX過程很相似。關(guān)于ICONIX過程的更多信息請參考Agile Development with ICONIX Procress 一書。

  這些修改包括:新類的發(fā)現(xiàn)、對現(xiàn)有類的重新組織以及定義某個(gè)類的方法和屬性等。換句話說,在編寫代碼之前編寫測試可以幫助你驗(yàn)證你的設(shè)計(jì)方案。這真的很酷:等你完成了你的設(shè)計(jì)并開始編寫源代碼的時(shí)候,你已經(jīng)完成了測試!只需運(yùn)行測試來證明你的代碼的工作情況符合設(shè)計(jì)要求行了。當(dāng)然,如果需要改變測試或改變設(shè)計(jì)方案,你隨時(shí)都可以這樣做;這正是敏捷開發(fā)技術(shù)的魅力所在。