軟件測試是為了發(fā)現(xiàn)錯誤而執(zhí)行程序的過程?;蛘哒f,軟件測試是根據(jù)軟件開發(fā)各階段的規(guī)格說明和程序的內(nèi)部結(jié)構(gòu)而精心設(shè)計一批測試用例(即輸入數(shù)據(jù)及其預(yù)期的輸出結(jié)果),并利用這些測試用例去運行程序,以發(fā)現(xiàn)程序錯誤的過程。
軟件測試在軟件生存期中橫跨兩個階段:通常在編寫出每一個模塊之后就對它做必要的測試(稱為單元測試)。模塊的編寫者與測試者是同一個人。編碼與單元測試屬于軟件生存期中的同一個階段。在這個階段結(jié)束之后,對軟件系統(tǒng)還要進(jìn)行各種綜合測試,這是軟件生存期的另一個獨立的階段,即測試階段,通常由專門的測試人員承擔(dān)這項工作。
設(shè)計測試的目標(biāo)是想以最少的時間和人力系統(tǒng)地找出軟件中潛在的各種錯誤和缺陷。
軟件測試的目的,第一是確認(rèn)軟件的質(zhì)量,其一方面是確認(rèn)軟件做了你所期望的事情(Do the right thing),另一方面是確認(rèn)軟件以正確的方式來做了這個事件(Do it right)。第二是提供信息,比如提供給開發(fā)人員或程序經(jīng)理的回饋信息,為風(fēng)險評估所準(zhǔn)備的信息。第三軟件測試不僅是在測試軟件產(chǎn)品的本身,而且還包括軟件開發(fā)的過程。如果一個軟件產(chǎn)品開發(fā)完成之后發(fā)現(xiàn)了很多問題,這說明此軟件開發(fā)過程很可能是有缺陷的。因此軟件測試的第三個目的是保證整個軟件開發(fā)過程是高質(zhì)量的。
測試人員在軟件開發(fā)過程中的任務(wù):
1、尋找Bug;
2、避免軟件開發(fā)過程中的缺陷;
3、衡量軟件的質(zhì)量;
4、關(guān)注用戶的需求。
軟件測試的原則:
① 應(yīng)當(dāng)把“盡早地和不斷地進(jìn)行軟件測試”作為軟件開發(fā)者的座右銘。
不應(yīng)把軟件測試僅僅看作是軟件開發(fā)的一個獨立階段,而應(yīng)當(dāng)把它貫穿到軟件開發(fā)的各個階段中。堅持在軟件開發(fā)的各個階段的技術(shù)評審,這樣才能在開發(fā)過程中盡早發(fā)現(xiàn)和預(yù)防錯誤,把出現(xiàn)的錯誤克服在早期,杜絕某些發(fā)生錯誤的隱患。
② 測試用例應(yīng)由測試輸入數(shù)據(jù)和與之對應(yīng)的預(yù)期輸出結(jié)果這兩部分組成。
測試以前應(yīng)當(dāng)根據(jù)測試的要求選擇測試用例(Test case),用來檢驗程序員編制的程序,因此不但需要測試的輸入數(shù)據(jù),而且需要針對這些輸入數(shù)據(jù)的預(yù)期輸出結(jié)果。
③ 程序員應(yīng)避免檢查自己的程序。
程序員應(yīng)盡可能避免測試自己編寫的程序,程序開發(fā)小組也應(yīng)盡可能避免測試本小組開發(fā)的程序。如果條件允許,最好建立獨立的軟件測試小組或測試機(jī)構(gòu)。這點不能與程序的調(diào)試(debuging)相混淆。調(diào)試由程序員自己來做可能更有效。
④ 在設(shè)計測試用例時,應(yīng)當(dāng)包括合理的輸入條件和不合理的輸入條件。
合理的輸入條件是指能驗證程序正確的輸入條件,不合理的輸入條件是指異常的,臨界的,可能引起問題異變的輸入條件。軟件系統(tǒng)處理非法命令的能力必須在測試時受到檢驗。用不合理的輸入條件測試程序時,往往比用合理的輸入條件進(jìn)行測試能發(fā)現(xiàn)更多的錯誤。
⑤ 充分注意測試中的群集現(xiàn)象。
在被測程序段中,若發(fā)現(xiàn)錯誤數(shù)目多,則殘存錯誤數(shù)目也比較多。這種錯誤群集性現(xiàn)象,已為許多程序的測試實踐所證實。根據(jù)這個規(guī)律,應(yīng)當(dāng)對錯誤群集的程序段進(jìn)行重點測試,以提高測試投資的效益。
⑥ 嚴(yán)格執(zhí)行測試計劃,排除測試的隨意性。
測試之前應(yīng)仔細(xì)考慮測試的項目,對每一項測試做出周密的計劃,包括被測程序的功能、輸入和輸出、測試內(nèi)容、進(jìn)度安排、資源要求、測試用例的選擇、測試的控制方式和過程等,還要包括系統(tǒng)的組裝方式、跟蹤規(guī)程、調(diào)試規(guī)程,回歸測試的規(guī)定,以及評價標(biāo)準(zhǔn)等。對于測試計劃,要明確規(guī)定,不要隨意解釋。
⑦ 應(yīng)當(dāng)對每一個測試結(jié)果做全面檢查。
有些錯誤的征兆在輸出實測結(jié)果時已經(jīng)明顯地出現(xiàn)了,但是如果不仔細(xì)地全面地檢查測試結(jié)果,就會使這些錯誤被遺漏掉。所以必須對預(yù)期的輸出結(jié)果明確定義,對實測的結(jié)果仔細(xì)分析檢查,抓住征侯,暴露錯誤。
⑧ 妥善保存測試計劃,測試用例,出錯統(tǒng)計和最終分析報告,為維護(hù)提供方便。
確認(rèn)(Validation)是一系列的活動和過程,其目的是想證實在一個給定的外部環(huán)境中軟件的邏輯正確性。它包括需求規(guī)格說明的確認(rèn)和程序的確認(rèn),而程序的確認(rèn)又分為靜態(tài)確認(rèn)與動態(tài)確認(rèn)。靜態(tài)確認(rèn)一般不在計算機(jī)上實際執(zhí)行程序,而是通過人工分析或者程序正確性證明來確認(rèn)程序的正確性; 動態(tài)確認(rèn)主要通過動態(tài)分析和程序測試來檢查程序的執(zhí)行狀態(tài),以確認(rèn)程序是否有問題。
驗證(Verification),則試圖證明在軟件生存期各個階段,以及階段間的邏輯協(xié)調(diào)性、完備性和正確性。
確認(rèn)與驗證工作都屬于軟件測試。在對需求理解與表達(dá)的正確性、設(shè)計與表達(dá)的正確性、實現(xiàn)的正確性以及運行的正確性的驗證中,任何一個環(huán)節(jié)上發(fā)生了問題都可能在軟件測試中表現(xiàn)出來。
測試信息流如圖1所示。測試過程需要三類輸入:
§ 軟件配置:包括軟件需求規(guī)格說明、軟件設(shè)計規(guī)格說明、源代碼等; § 測試配置:包括測試計劃、測試用例、測試驅(qū)動程序等; § 測試工具:測試工具為測試的實施提供某種服務(wù)。例如,測試數(shù)據(jù)自動生成程序、靜態(tài)分析程序、動態(tài)分析程序、測試結(jié)果分析程序、以及驅(qū)動測試的工作臺等。 測試之后,用實測結(jié)果與預(yù)期結(jié)果進(jìn)行比較。如果發(fā)現(xiàn)出錯的數(shù)據(jù),就要進(jìn)行調(diào)試。對已經(jīng)發(fā)現(xiàn)的錯誤進(jìn)行錯誤定位和確定出錯性質(zhì),并改正這些錯誤,同時修改相關(guān)的文檔。修正后的文檔一般都要經(jīng)過再次測試,直到通過測試為止。 通過收集和分析測試結(jié)果數(shù)據(jù),對軟件建立可靠性模型。 圖1 測試信息流 如果測試發(fā)現(xiàn)不了錯誤,那么可以肯定,測試配置考慮得不夠細(xì)致充分,錯誤仍然潛伏在軟件中。這些錯誤最終不得不由用戶在使用中發(fā)現(xiàn),并在維護(hù)時由開發(fā)者去改正。但那時改正錯誤的費用將比在開發(fā)階段改正錯誤的費用要高出40倍到60倍。 軟件開發(fā)過程是一個自頂向下,逐步細(xì)化的過程,而測試過程則是依相反的順序安排的 自底向上,逐步集成的過程。低一級測試為上一級測試準(zhǔn)備條件。參看圖1.2,首先對每一個程序模塊進(jìn)行單元測試,消除程序模塊內(nèi)部在邏輯上和功能上的錯誤和缺陷。再對照軟件設(shè)計進(jìn)行集成測試,檢測和排除子系統(tǒng)(或系統(tǒng))結(jié)構(gòu)上的錯誤。隨后再對照需求,進(jìn)行確認(rèn)測試。最后從系統(tǒng)全體出發(fā),運行系統(tǒng),看是否滿足要求。 圖2 軟件測試與軟件開發(fā)過程的關(guān)系 由于人們對錯誤有不同的理解和認(rèn)識,所以目前還沒有一個統(tǒng)一的錯誤分類方法。錯誤難于分類的原因,一方面是由于一個錯誤有許多征兆,因而它可以被歸入不同的類。另一方面是因為把一個給定的錯誤歸于哪一類,還與錯誤的來源和程序員的心理狀態(tài)有關(guān)。 § 較小錯誤:只對系統(tǒng)輸出有一些非實質(zhì)性影響。如,輸出的數(shù)據(jù)格式不合要求等。 § 中等錯誤:對系統(tǒng)的運行有局部影響。如輸出的某些數(shù)據(jù)有錯誤或出現(xiàn)冗余。 § 較嚴(yán)重錯誤:系統(tǒng)的行為因錯誤的干擾而出現(xiàn)明顯不合情理的現(xiàn)象。比如開出了0.00元的支票,系統(tǒng)的輸出完全不可信賴。 § 嚴(yán)重錯誤:系統(tǒng)運行不可跟蹤,一時不能掌握其規(guī)律,時好時壞。 § 非常嚴(yán)重的錯誤:系統(tǒng)運行中突然停機(jī),其原因不明,無法軟啟動。 § 最嚴(yán)重的錯誤:系統(tǒng)運行導(dǎo)致環(huán)境破壞,或是造成事故,引起生命、財產(chǎn)的損失。 ① 功能錯誤 § 規(guī)格說明錯誤:規(guī)格說明可能不完全,有二義性或自身矛盾。 § 功能錯誤:程序?qū)崿F(xiàn)的功能與用戶要求的不一致。這常常是由于規(guī)格說明中包含錯誤的功能、多余的功能或遺漏的功能所致。 § 測試錯誤:軟件測試的設(shè)計與實施發(fā)生錯誤。軟件測試自身也可能發(fā)生錯誤。 § 測試標(biāo)準(zhǔn)引起的錯誤:對軟件測試的標(biāo)準(zhǔn)要選擇適當(dāng),若測試標(biāo)準(zhǔn)太復(fù)雜,則導(dǎo)致測試過程出錯的可能就大。 ② 系統(tǒng)錯誤 § 外部接口錯誤:外部接口指如終端、打印機(jī)、通信線路等系統(tǒng)與外部環(huán)境通信的手段。所有外部接口之間,人與機(jī)器之間的通信都使用形式的或非形式的專門協(xié)議。如果協(xié)議有錯,或太復(fù)雜,難以理解,致使在使用中出錯。此外還包括對輸入/輸出格式錯誤理解,對輸入數(shù)據(jù)不合理的容錯等等。 § 內(nèi)部接口錯誤:內(nèi)部接口指程序之間的聯(lián)系。它所發(fā)生的錯誤與程序內(nèi)實現(xiàn)的細(xì)節(jié)有關(guān)。例如,設(shè)計協(xié)議錯、輸入/輸出格式錯、數(shù)據(jù)保護(hù)不可靠、子程序訪問錯等。 § 硬件結(jié)構(gòu)錯誤:這類錯誤在于不能正確地理解硬件如何工作。例如,忽視或錯誤地理解分頁機(jī)構(gòu)、位址生成、信道容量、I/O指令、中斷處理、設(shè)備初始化和啟動等而導(dǎo)致的出錯。 § 操作系統(tǒng)錯誤:這類錯誤主要是由于不了解操作系統(tǒng)的工作機(jī)制而導(dǎo)致出錯。當(dāng)然,操作系統(tǒng)本身也有錯誤,但是一般用戶很難發(fā)現(xiàn)這種錯誤。 § 軟件結(jié)構(gòu)錯誤:由于軟件結(jié)構(gòu)不合理或不清晰而引起的錯誤。這種錯誤通常與系統(tǒng)的負(fù)載有關(guān),而且往往在系統(tǒng)滿載時才出現(xiàn)。這是最難發(fā)現(xiàn)的一類錯誤。例如,錯誤地設(shè)置局部參數(shù)或全局參數(shù);錯誤地假定寄存器與內(nèi)存單元初始化了;錯誤地假定不會發(fā)生中斷而導(dǎo)致不能封鎖或開中斷;錯誤地假定程序可以繞過數(shù)據(jù)的內(nèi)部鎖而導(dǎo)致不能關(guān)閉或打開內(nèi)部鎖;錯誤地假定被調(diào)用子程序常駐內(nèi)存或非常駐內(nèi)存等等,都將導(dǎo)致軟件出錯。 § 控制與順序錯誤:這類錯誤包括:忽視了時間因素而破壞了事件的順序;猜測事件出現(xiàn)在指定的序列中;等待一個不可能發(fā)生的條件;漏掉先決條件;規(guī)定錯誤的優(yōu)先級或程序狀態(tài);漏掉處理步驟;存在不正確的處理步驟或多余的處理步驟等。 § 資源管理錯誤:這類錯誤是由于不正確地使用資源而產(chǎn)生的。例如,使用未經(jīng)獲準(zhǔn)的資源;使用后未釋放資源;資源死鎖;把資源鏈接在錯誤的序列中等等。 ③ 加工錯誤 § 算術(shù)與操作錯誤:指在算術(shù)運算、函數(shù)求值和一般操作過程中發(fā)生的錯誤。包括:數(shù)據(jù)類型轉(zhuǎn)換錯;除法溢出;錯誤地使用關(guān)系比較符;用整數(shù)與浮點數(shù)做比較等。 § 初始化錯誤:典型的錯誤有:忘記初始化工作區(qū),忘記初始化寄存器和資料區(qū);錯誤地對循環(huán)控制變量賦初值;用不正確的格式,數(shù)據(jù)或類型進(jìn)行初始化等等。 § 控制和次序錯誤:這類錯誤與系統(tǒng)級同名錯誤類似,但它是局部錯誤。包括:遺漏路徑;不可達(dá)到的代碼;不符合語法的循環(huán)嵌套;循環(huán)返回和終止的條件不正確;漏掉處理步驟或處理步驟有錯等。 § 靜態(tài)邏輯錯誤:這類錯誤主要包括:不正確地使用CASE語句;在表達(dá)式中使用不正確的否定(例如用“>”代替“<”的否定);對情況不適當(dāng)?shù)胤纸馀c組合;混淆“或”與“異或”等。 ④ 數(shù)據(jù)錯誤 § 動態(tài)數(shù)據(jù)錯誤:動態(tài)數(shù)據(jù)是在程序執(zhí)行過程中暫時存在的數(shù)據(jù)。各種不同類型的動態(tài)數(shù)據(jù)在程序執(zhí)行期間將共享一個共同的存儲區(qū)域,若程序啟動時對這個區(qū)域未初始化,就會導(dǎo)致數(shù)據(jù)出錯。由于動態(tài)數(shù)據(jù)被破壞的位置可能與出錯的位置在距離上相差很遠(yuǎn),因此要發(fā)現(xiàn)這類錯誤比較困難。 § 靜態(tài)數(shù)據(jù)錯誤:靜態(tài)數(shù)據(jù)在內(nèi)容和格式上都是固定的。它們直接或間接地出現(xiàn)在程序或數(shù)據(jù)庫中。由編譯程序或其它專門程序?qū)λ鼈冏鲱A(yù)處理。這是在程序執(zhí)行前防止靜態(tài)錯誤的好辦法,但預(yù)處理也會出錯。 § 數(shù)據(jù)內(nèi)容錯誤:數(shù)據(jù)內(nèi)容是指存儲于存儲單元或數(shù)據(jù)結(jié)構(gòu)中的位串、字符串或數(shù)字。數(shù)據(jù)內(nèi)容本身沒有特定的含義,除非通過硬件或軟件給予解釋。數(shù)據(jù)內(nèi)容錯誤就是由于內(nèi)容被破壞或被錯誤地解釋而造成的錯誤。 § 數(shù)據(jù)結(jié)構(gòu)錯誤:數(shù)據(jù)結(jié)構(gòu)是指數(shù)據(jù)元素的大小和組織形式。在同一存儲區(qū)域中可以定義不同的數(shù)據(jù)結(jié)構(gòu)。數(shù)據(jù)結(jié)構(gòu)錯誤主要包括結(jié)構(gòu)說明錯誤及把一個數(shù)據(jù)結(jié)構(gòu)誤當(dāng)做另一類數(shù)據(jù)結(jié)構(gòu)使用的錯誤。這是更危險的錯誤。 § 數(shù)據(jù)屬性錯誤:數(shù)據(jù)屬性是指數(shù)據(jù)內(nèi)容的含義或語義。例如,整數(shù)、字符串、子程序等等。數(shù)據(jù)屬性錯誤主要包括:對數(shù)據(jù)屬性不正確地解釋,比如錯把整數(shù)當(dāng)實數(shù),允許不同類型數(shù)據(jù)混合運算而導(dǎo)致的錯誤等。 ⑤ 代碼錯誤 主要包括:語法錯誤;打字錯誤;對語句或指令不正確理解所產(chǎn)生的錯誤。 Good enough-Gerhart分類方法把軟件的邏輯錯誤按生存期不同階段分為4類。 ① 問題定義(需求分析)錯誤 它們是在軟件定義階段,分析員研究用戶的要求后所編寫的文檔中出現(xiàn)的錯誤。換句話說,這類錯誤是由于問題定義不滿足用戶的要求而導(dǎo)致的錯誤。 ② 規(guī)格說明錯誤 這類錯誤是指規(guī)格說明與問題定義不一致所產(chǎn)生的錯誤。它們又可以細(xì)分成: § 不一致性錯誤:規(guī)格說明中功能說明與問題定義發(fā)生矛盾。 § 冗余性錯誤:規(guī)格說明中某些功能說明與問題定義相比是多余的。 § 不完整性錯誤:規(guī)格說明中缺少某些必要的功能說明。 § 不可行錯誤:規(guī)格說明中有些功能要求是不可行的。 § 不可測試錯誤:有些功能的測試要求是不現(xiàn)實的。 3設(shè)計錯誤 這是在設(shè)計階段產(chǎn)生的錯誤,它使系統(tǒng)的設(shè)計與需求規(guī)格說明中的功能說明不相符。它們又可以細(xì)分為: § 設(shè)計不完全錯誤:某些功能沒有被設(shè)計,或設(shè)計得不完全。 § 算法錯誤:算法選擇不合適。主要表現(xiàn)為算法的基本功能不滿足功能要求、算法不可行或者算法的效率不符合要求。 § 模塊接口錯誤:模塊結(jié)構(gòu)不合理;模塊與外部數(shù)據(jù)庫的接口不一致,模塊之間的接口不一致。 § 控制邏輯錯誤:控制流程與規(guī)格說明不一致;控制結(jié)構(gòu)不合理。 § 數(shù)據(jù)結(jié)構(gòu)錯誤:數(shù)據(jù)設(shè)計不合理;與算法不匹配;數(shù)據(jù)結(jié)構(gòu)不滿足規(guī)格說明要求。 ④ 編碼錯誤 編碼過程中的錯誤是多種多樣的,大體可歸為以下幾種:數(shù)據(jù)說明錯、數(shù)據(jù)使用錯、計算錯、比較錯、控制流錯、接口錯、輸入/輸出錯,及其它的錯誤。 在不同的開發(fā)階段,錯誤的類型和表現(xiàn)形式是不同的,故應(yīng)當(dāng)采用不同的方法和策略來進(jìn)行檢測。 測試過程按4個步驟進(jìn)行,即單元測試、組裝測試、確認(rèn)測試和系統(tǒng)測試。圖2.1顯示出軟件測試經(jīng)歷的4個步驟。單元測試集中對用源代碼實現(xiàn)的每一個程序單元進(jìn)行測試,檢查各個程序模塊是否正確地實現(xiàn)了規(guī)定的功能。然后,進(jìn)行集成測試,根據(jù)設(shè)計規(guī)定的軟件體系結(jié)構(gòu),把已測試過的模塊組裝起來,在組裝過程中,檢查程序結(jié)構(gòu)組裝的正確性。確認(rèn)測試則是要檢查已實現(xiàn)的軟件是否滿足了需求規(guī)格說明中確定了的各種需求,以及軟件配置是否完全、正確。最后是系統(tǒng)測試,把已經(jīng)經(jīng)過確認(rèn)的軟件納入實際運行環(huán)境中,與其它系統(tǒng)成份組合在一起進(jìn)行測試。嚴(yán)格地說,系統(tǒng)測試已超出了軟件工程的范圍。 圖3 軟件測試的過程 單元測試的對象是軟件設(shè)計的最小單位——模塊。單元測試的依據(jù)是詳細(xì)設(shè)計描述,單元測試應(yīng)對模塊內(nèi)所有重要的控制路徑設(shè)計測試用例,以便發(fā)現(xiàn)模塊內(nèi)部的錯誤。單元測試多采用白盒測試技術(shù),系統(tǒng)內(nèi)多個模塊可以并行地進(jìn)行測試。 單元測試任務(wù): 在單元測試的基礎(chǔ)上,需要將所有模塊按照設(shè)計要求組裝成為系統(tǒng)。這時需要考慮: § 在把各個模塊連接起來的時侯,穿越模塊接口的數(shù)據(jù)是否會丟失; § 一個模塊的功能是否會對另一個模塊的功能產(chǎn)生不利的影響; § 各個子功能組合起來,能否達(dá)到預(yù)期要求的父功能; § 全局?jǐn)?shù)據(jù)結(jié)構(gòu)是否有問題; § 單個模塊的誤差累積起來,是否會放大,從而達(dá)到不能接受的程度。 § 單個模塊的錯誤是否會導(dǎo)致數(shù)據(jù)庫錯誤。 選擇什么方式把模塊組裝起來形成一個可運行的系統(tǒng),直接影響到模塊測試用例的形式、所用測試工具的類型、模塊編號的次序和測試的次序、以及生成測試用例的費用和調(diào)試的費用。通常,把模塊組裝成為系統(tǒng)的方式有兩種方式: ① 一次性集成方式 它是一種非增殖式集成方式。也叫做整體拼裝。使用這種方式,首先對每個模塊分別進(jìn)行模塊測試,然后再把所有模塊組裝在一起進(jìn)行測試,最終得到要求的軟件系統(tǒng)。 由于程序中不可避免地存在涉及模塊間接口、全局?jǐn)?shù)據(jù)結(jié)構(gòu)等方面的問題,所以一次試運行成功的可能性并不很大。 ② 增殖式集成方式 又稱漸增式集成方式。首先對一個個模塊進(jìn)行模塊測試,然后將這些模塊逐步組裝成較大的系統(tǒng),在組裝的過程中邊連接邊測試,以發(fā)現(xiàn)連接過程中產(chǎn)生的問題。最后通過增殖逐步組裝成為要求的軟件系統(tǒng)。 § 自頂向下的增殖方式:將模塊按系統(tǒng)程序結(jié)構(gòu),沿控制層次自頂向下進(jìn)行集成。由于這種增殖方式在測試過程中較早地驗證了主要的控制和判斷點。在一個功能劃分合理的程序結(jié)構(gòu)中,判斷常出現(xiàn)在較高的層次,較早就能遇到。如果主要控制有問題,盡早發(fā)現(xiàn)它能夠減少以后的返工。 § 自底向上的增殖方式:從程序結(jié)構(gòu)的最底層模塊開始組裝和測試。因為模塊是自底向上進(jìn)行組裝,對于一個給定層次的模塊,它的子模塊(包括子模塊的所有下屬模塊)已經(jīng)組裝并測試完成,所以不再需要樁模塊。在模塊的測試過程中需要從子模塊得到的信息可以直接運行子模塊得到。 ③ 混合增殖式測試:自頂向下增殖的方式和自底向上增殖的方式各有優(yōu)缺點。自頂向下增殖方式的缺點是需要建立樁模塊。要使樁模塊能夠模擬實際子模塊的功能將是十分困難的。同時涉及復(fù)雜算法和真正輸入/輸出的模塊一般在底層,它們是最容易出問題的模塊,到組裝和測試的后期才遇到這些模塊,一旦發(fā)現(xiàn)問題,導(dǎo)致過多的回歸測試。而自頂向下增殖方式的優(yōu)點是能夠較早地發(fā)現(xiàn)在主要控制方面的問題。自底向上增殖方式的缺點是“程序一直未能做為一個實體存在,直到最后一個模塊加上去后才形成一個實體”。就是說,在自底向上組裝和測試的過程中,對主要的控制直到最后才接觸到。但這種方式的優(yōu)點是不需要樁模塊,而建立驅(qū)動模塊一般比建立樁模塊容易,同時由于涉及到復(fù)雜算法和真正輸入/輸出的模塊最先得到組裝和測試,可以把最容易出問題的部分在早期解決。此外自底向上增殖的方式可以實施多個模塊的并行測試。 有鑒于此,通常是把以上兩種方式結(jié)合起來進(jìn)行組裝和測試。 § 衍變的自頂向下的增殖測試:它的基本思想是強(qiáng)化對輸入/輸出模塊和引入新算法模塊的測試,并自底向上組裝成為功能相當(dāng)完整且相對獨立的子系統(tǒng),然后由主模塊開始自頂向下進(jìn)行增殖測試。 § 自底向上-自頂向下的增殖測試:它首先對含讀操作的子系統(tǒng)自底向上直至根結(jié)點模塊進(jìn)行組裝和測試,然后對含寫操作的子系統(tǒng)做自頂向下的組裝與測試。 § 回歸測試:這種方式采取自頂向下的方式測試被修改的模塊及其子模塊,然后將這一部分視為子系統(tǒng),再自底向上測試,以檢查該子系統(tǒng)與其上級模塊的接口是否適配。 確認(rèn)測試又稱有效性測試。它的任務(wù)是驗證軟件的有效性,即驗證軟件的功能和性能及其它特性是否與用戶的要求一致。在軟件需求規(guī)格說明書描述了全部用戶可見的軟件屬性,其中有一節(jié)叫做有效性準(zhǔn)則,它包含的信息就是軟件確認(rèn)測試的基礎(chǔ)。 在確認(rèn)測試階段需要做的工作如圖5.5所示。首先要進(jìn)行有效性測試以及軟件配置復(fù)審,然后進(jìn)行驗收測試和安裝測試,在通過了專家鑒定之后,才能成為可交付的軟件。 圖4 確認(rèn)測試的步驟 ① 進(jìn)行有效性測試(功能測試) 有效性測試是在模擬的環(huán)境(可能就是開發(fā)的環(huán)境)下,運用黑盒測試的方法,驗證被測軟件是否滿足需求規(guī)格說明書列出的需求。為此,需要首先制定測試計劃,規(guī)定要做測試的種類。還需要制定一組測試步驟,描述具體的測試用例。通過實施預(yù)定的測試計劃和測試步驟,確定軟件的特性是否與需求相符,確保所有的軟件功能需求都能得到滿足,所有的軟件性能需求都能達(dá)到,所有的文檔都是正確且便于使用。同時,對其他軟件需求,例如可移植性、兼容性、出錯自動恢復(fù)、可維護(hù)性等,也都要進(jìn)行測試,確認(rèn)是否滿足。 ② 軟件配置復(fù)查 軟件配置復(fù)查的目的是保證軟件配置的所有成分都齊全,各方面的質(zhì)量都符合要求,具有維護(hù)階段所必需的細(xì)節(jié),而且已經(jīng)編排好分類的目錄。 除了按合同規(guī)定的內(nèi)容和要求,由人工審查軟件配置之外,在確認(rèn)測試的過程中,應(yīng)當(dāng)嚴(yán)格遵守用戶手冊和操作手冊中規(guī)定的使用步驟,以便檢查這些文文件數(shù)據(jù)的完整性和正確性。必須仔細(xì)記錄發(fā)現(xiàn)的遺漏和錯誤,并且適當(dāng)?shù)匮a充和改正。 ③ 驗收測試 在通過了系統(tǒng)的有效性測試及軟件配置審查之后,就應(yīng)開始系統(tǒng)的驗收測試。驗收測試是以用戶為主的測試。軟件開發(fā)人員和QA(質(zhì)量保證)人員也應(yīng)參加。由用戶參加設(shè)計測試用例,使用用戶接口輸入測試數(shù)據(jù),并分析測試的輸出結(jié)果。一般使用生產(chǎn)中的實際數(shù)據(jù)進(jìn)行測試。在測試過程中,除了考慮軟件的功能和性能外,還應(yīng)對軟件的可移植性、兼容性、可維護(hù)性、錯誤的恢復(fù)功能等進(jìn)行確認(rèn)。 ④ α測試和β測試 在軟件交付使用之后,用戶將如何實際使用程序,對于開發(fā)者來說是無法預(yù)測的。因為用戶在使用過程中常常會發(fā)生對使用方法的誤解、異常的數(shù)據(jù)組合、以及產(chǎn)生對某些用戶來說似乎是清晰的但對另一些用戶來說卻難以理解的輸出等等。 如果軟件是為多個用戶開發(fā)的產(chǎn)品的時侯,讓每個用戶逐個執(zhí)行正式的驗收測試是不切實際的。很多軟件產(chǎn)品生產(chǎn)者采用一種稱之為α測試和β測試的測試方法,以發(fā)現(xiàn)可能只有最終用戶才能發(fā)現(xiàn)的錯誤。 α測試是由一個用戶在開發(fā)環(huán)境下進(jìn)行的測試,也可以是公司內(nèi)部的用戶在仿真實際操作環(huán)境下進(jìn)行的測試。這是在受控制的環(huán)境下進(jìn)行的測試。α測試的目的是評價軟件產(chǎn)品的FURPS(即功能、可使用性、可靠性、性能和支持)。尤其注重產(chǎn)品的接口和特色。α測試人員是除開產(chǎn)品開發(fā)人員之外首先見到產(chǎn)品的人,他們提出的功能和修改意見是特別有價值的。α測試可以從軟件產(chǎn)品編碼結(jié)束之時開始,或在模塊(子系統(tǒng))測試完成之后開始,也可以在確認(rèn)測試過程中產(chǎn)品達(dá)到一定的穩(wěn)定和可靠程度之后再開始。有關(guān)的手冊(草稿)等應(yīng)事先準(zhǔn)備好。 β測試是由軟件的多個用戶在一個或多個用戶的實際使用環(huán)境下進(jìn)行的測試。與α測試不同的是,開發(fā)者通常不在測試現(xiàn)場。因而,β測試是在開發(fā)者無法控制的環(huán)境下進(jìn)行的軟件現(xiàn)場應(yīng)用。在β測試中,由用戶記下遇到的所有問題,包括真實的以及主觀認(rèn)定的,定期向開發(fā)者報告,開發(fā)者在綜合用戶的報告之后,做出修改,最后將軟件產(chǎn)品交付給全體用戶使用。β測試主要衡量產(chǎn)品的FURPS。著重于產(chǎn)品的支持性,包括文檔、客戶培訓(xùn)和支持產(chǎn)品生產(chǎn)能力。只有當(dāng)α測試達(dá)到一定的可靠程度時,才能開始β測試。由于它處在整個測試的最后階段,不能指望這時發(fā)現(xiàn)主要問題。同時,產(chǎn)品的所有手冊文本也應(yīng)該在此階段完全定稿。由于β測試的主要目標(biāo)是測試可支持性,所以β測試應(yīng)盡可能由主持產(chǎn)品發(fā)行的人員來管理。 所謂系統(tǒng)測試,是將通過確認(rèn)測試的軟件,作為整個基于計算機(jī)系統(tǒng)的一個元素,與計算機(jī)硬件、外設(shè)、某些支持軟件、數(shù)據(jù)和人員等其它系統(tǒng)元素結(jié)合在一起,在實際運行(使用)環(huán)境下,對計算機(jī)系統(tǒng)進(jìn)行一系列的組裝測試和確認(rèn)測試。 系統(tǒng)測試的目的在于通過與系統(tǒng)的需求定義作比較,發(fā)現(xiàn)軟件與系統(tǒng)定義不符合或與之矛盾的地方。系統(tǒng)測試的測試用例應(yīng)根據(jù)需求分析規(guī)格說明來設(shè)計,并在實際使用環(huán)境下來運行。 ① 黑盒測試 根據(jù)軟件產(chǎn)品的功能設(shè)計規(guī)格,在計算機(jī)上進(jìn)行測試,以證實每個實現(xiàn)了的功能是否符合要求。這種測試方法就是黑盒測試。黑盒測試意味著測試要在軟件的接口處進(jìn)行。就是說,這種方法是把測試對象看做一個黑盒子,測試人員完全不考慮程序內(nèi)部的邏輯結(jié)構(gòu)和內(nèi)部特性,只依據(jù)程序的需求分析規(guī)格說明,檢查程序的功能是否符合它的功能說明。 用黑盒測試發(fā)現(xiàn)程序中的錯誤,必須在所有可能的輸入條件和輸出條件中確定測試數(shù)據(jù),來檢查程序是否都能產(chǎn)生正確的輸出。 ② 白盒測試 根據(jù)軟件產(chǎn)品的內(nèi)部工作過程,在計算機(jī)上進(jìn)行測試,以證實每種內(nèi)部操作是否符合設(shè)計規(guī)格要求,所有內(nèi)部成分是否已經(jīng)過檢查。這種測試方法就是白盒測試。白盒測試把測試對象看做一個打開的盒子,允許測試人員利用程序內(nèi)部的邏輯結(jié)構(gòu)及有關(guān)信息,設(shè)計或選擇測試用例,對程序所有邏輯路徑進(jìn)行測試。通過在不同點檢查程序的狀態(tài),確定實際的狀態(tài)是否與預(yù)期的狀態(tài)一致。 不論黑盒測試,還是白盒測試,都不可能進(jìn)行所謂的窮舉測試。任何軟件開發(fā)項目都要受到期限、費用、人力和機(jī)時等條件的限制,為了節(jié)省時間和資源,提高測試效率,就必須要從數(shù)量極大的可用測試用例中精心地挑選少量的測試數(shù)據(jù),使得采用這些測試數(shù)據(jù)能夠達(dá)到最佳的測試效果,能夠高效率地把隱藏的錯誤揭露出來。 3 基于風(fēng)險的測試 基于風(fēng)險的測試是指評估測試的優(yōu)先級,先做高優(yōu)先級的測試,如果時間或精力不夠,低優(yōu)先級的測試可以暫時先不做。如圖5 ,橫軸代表影響,豎軸代表概率,根據(jù)一個軟件的特點來確定:如果一個功能出了問題,它對整個產(chǎn)品的影響有多大,這個功能出問題的概率有多大?如果出問題的概率很大,出了問題對整個產(chǎn)品的影響也很大,那么在測試時就一定要覆蓋到。對于一個用戶很少用到的功能,出問題的概率很小,就算出了問題的影響也不是很大,那么如果時間比較緊的話,就可以考慮不測試。 圖5 基于風(fēng)險測試的兩個決定因素就是:該功能出問題對用戶的影響有多大,出問題的概率有多大。其它一些影響因素還有復(fù)雜性、可用性、依賴性、可修改性等。測試人員主要根據(jù)事情的輕重緩急來決定測試工作的重點。 4基于模型的測試 模型實際上就是用語言把一個系統(tǒng)的行為描述出來,定義出它可能的各種狀態(tài),以及它們之間的轉(zhuǎn)換關(guān)系,即狀態(tài)轉(zhuǎn)換圖。模型是系統(tǒng)的抽象?;谀P偷臏y試是利用模型來生成相應(yīng)的測試用例,然后根據(jù)實際結(jié)果和原先預(yù)想的結(jié)果的差異來測試系統(tǒng),過程如圖6所示。 圖6 邏輯覆蓋是以程序內(nèi)部邏輯結(jié)構(gòu)為基礎(chǔ)來設(shè)計測試用例的技術(shù),屬白盒測試。這一方法要求測試人員對程序的邏輯結(jié)構(gòu)有清楚的了解,甚至要能掌握源程序的所有細(xì)節(jié)。由于覆蓋測試的目標(biāo)不同,邏輯覆蓋又可分為:語句覆蓋、判定覆蓋、判定-條件覆蓋、條件組合覆蓋及路徑覆蓋。 ① 語句覆蓋 :語句覆蓋就是設(shè)計若干個測試用例,運行被測程序,使得每一可執(zhí)行語句至少執(zhí)行一次。這種覆蓋又稱為點覆蓋,它使得程序中每個可執(zhí)行語句都得到執(zhí)行,但它是最弱的邏輯覆蓋,效果有限,必須與其它方法交互使用。 ② 判定覆蓋 :判定覆蓋就是設(shè)計若干個測試用例,運行被測程序,使得程序中每個判斷的取真分支和取假分支至少經(jīng)歷一次。判定覆蓋又稱為分支覆蓋。 判定覆蓋只比語句覆蓋稍強(qiáng)一些,但實際效果表明,只是判定覆蓋,還不能保證一定能查出在判斷的條件中存在的錯誤。因此,還需要更強(qiáng)的邏輯覆蓋準(zhǔn)則去檢驗判斷內(nèi)部條件。 ③ 條件覆蓋 :條件覆蓋就是設(shè)計若干個測試用例,運行被測程序,使得程序中每個判斷的每個條件的可能取值至少執(zhí)行一次。 條件覆蓋深入到判定中的每個條件,但可能不能滿足判定覆蓋的要求。 ④ 判定-條件覆蓋 :判定-條件覆蓋就是設(shè)計足夠的測試用例,使得判斷中每個條件的所有可能取值至少執(zhí)行一次,同時每個判斷本身的所有可能判斷結(jié)果至少執(zhí)行一次。換言之,即是要求各個判斷的所有可能的條件取值組合至少執(zhí)行一次。 判定-條件覆蓋有缺陷。從表面上來看,它測試了所有條件的取值。但是事實并非如此。往往某些條件掩蓋了另一些條件。會遺漏某些條件取值錯誤的情況。為徹底地檢查所有條件的取值,需要將判定語句中給出的復(fù)合條件表達(dá)式進(jìn)行分解,形成由多個基本判定嵌套的流程圖。這樣就可以有效地檢查所有的條件是否正確了。 ⑤ 多重條件覆蓋 :多重條件覆蓋就是設(shè)計足夠的測試用例,運行被測程序,使得每個判斷的所有可能的條件取值組合至少執(zhí)行一次。 這是一種相當(dāng)強(qiáng)的覆蓋準(zhǔn)則,可以有效地檢查各種可能的條件取值的組合是否正確。它不但可覆蓋所有條件的可能取值的組合,還可覆蓋所有判斷的可取分支,但可能有的路徑會遺漏掉。測試還不完全。 6 路徑測試 :路徑測試就是設(shè)計足夠的測試用例,覆蓋程序中所有可能的路徑。這是最強(qiáng)的覆蓋準(zhǔn)則。但在路徑數(shù)目很大時,真正做到完全覆蓋是很困難的,必須把覆蓋路徑數(shù)目壓縮到一定限度。 (2) 判定覆蓋 所謂判定覆蓋就是設(shè)計若干個測試用例,運行被測程序,使得程序中每個判斷的取真分支和取假分支至少經(jīng)歷一次。判定覆蓋又稱為分支覆蓋。 (3) 條件覆蓋 所謂條件覆蓋就是設(shè)計若干個測試用例,運行被測程序,使得程序中每個判斷的每個條件的可能取值至少執(zhí)行一次。例如在本題所給出的例子中,我們事先可對所有條件的取值加以標(biāo)記。 (4) 判定-條件覆蓋 所謂判定-條件覆蓋就是設(shè)計足夠的測試用例,使得判斷中每個條件的所有可能取值至少執(zhí)行一次,同時每個判斷本身的所有可能判斷結(jié)果至少執(zhí)行一次。換言之,即是要求各個判斷的所有可能的條件取值組合至少執(zhí)行一次 (5) 條件組合覆蓋 所謂條件組合覆蓋就是設(shè)計足夠的測試用例,運行被測程序,使得每個判斷的所有可能的條件取值組合至少執(zhí)行一次。 (6) 路徑測試 路徑測試就是設(shè)計足夠的測試用例,覆蓋程序中所有可能的路徑。 等價類劃分是一種典型的黑盒測試方法。使用這一方法時,完全不考慮程序的內(nèi)部結(jié)構(gòu),只依據(jù)程序的規(guī)格說明來設(shè)計測試用例。由于不可能用所有可以輸入的數(shù)據(jù)來測試程序,而只能從全部可供輸入的數(shù)據(jù)中選擇一個子集進(jìn)行測試。如何選擇適當(dāng)?shù)淖蛹?,使其盡可能多地發(fā)現(xiàn)錯誤。解決的辦法之一就是等價類劃分。 1 把數(shù)目極多的輸入數(shù)據(jù)(有效的和無效的)劃分為若干等價類。所謂等價類是指某個輸入域的子集合,在該子集合中,各個輸入數(shù)據(jù)對于揭露程序中的錯誤都是等效的。并合理地假定:測試某等價類的代表值就等價于對這一類其它值的測試。因此,我們可以把全部輸入資料合理劃分為若干等價類,在每一個等價類中取一個數(shù)據(jù)做為測試的輸入條件,就可用少量代表性測試數(shù)據(jù),取得較好的測試效果。 等價類的劃分有兩種不同的情況: § 有效等價類:是指對于程序規(guī)格說明來說,是合理的,有意義的輸入數(shù)據(jù)構(gòu)成的集合。利用它,可以檢驗程序是否實現(xiàn)了規(guī)格說明預(yù)先規(guī)定的功能和性能。 § 無效等價類:是指對于程序規(guī)格說明來說,是不合理的,無意義的輸入數(shù)據(jù)構(gòu)成的集合。利用它,可以檢查程序中功能和性能的實現(xiàn)是否有不符合規(guī)格說明要求的地方。 在設(shè)計測試用例時,要同時考慮有效等價類和無效等價類的設(shè)計。軟件不能都只接收合理的數(shù)據(jù),還要經(jīng)受意外的考驗,接受無效的或不合理的數(shù)據(jù),這樣獲得的軟件才能具有較高的可靠性。劃分等價類的原則如下: § 按區(qū)間劃分:如果可能的輸入數(shù)據(jù)屬于一個取值范圍或值的個數(shù)限制范圍,則可以確立一個有效等價類和兩個無效等價類。 § 按數(shù)值劃分:如果規(guī)定了輸入數(shù)據(jù)的一組值,而且程序要對每個輸入值分別進(jìn)行處理。則可為每一個輸入值確立一個有效等價類,此外針對這組值確立一個無效等價類,它是所有不允許的輸入值的集合。 § 按數(shù)值集合劃分:如果可能的輸入數(shù)據(jù)屬于一個值的集合,或者須滿足“必須如何”的條件,這時可確立一個有效等價類和一個無效等價類。 § 按限制條件或規(guī)則劃分:如果規(guī)定了輸入數(shù)據(jù)必須遵守的規(guī)則或限制條件,則可以確立一個有效等價類(符合規(guī)則)和若干個無效等價類(從不同角度違反規(guī)則)。 ② 確立測試用例 在確立了等價類之后,建立等價類表,列出所有劃分出的等價類: 再從劃分出的等價類中按以下原則選擇測試用例: § 設(shè)計盡可能少的測試用例,覆蓋所有的有效等價類; § 針對每一個無效等價類,設(shè)計一個測試用例來覆蓋它。 邊界值的分析是利用了一個規(guī)律,即程序最容易發(fā)生錯誤的地方就是在邊界值的附近,它取決于變量的類型,以及變量的取值范圍。比如,在做三角形計算時,要輸入三角形的三個邊長:A、B和C。 我們應(yīng)注意到這三個數(shù)值應(yīng)當(dāng)滿足A>0、B>0、C>0、A+B>C、A+C>B、B+C>A,才能構(gòu)成三角形。但如果把六個不等式中的任何一個大于號“>”錯寫成大于等于號“≥”,那就不能構(gòu)成三角形。問題恰出現(xiàn)在容易被疏忽的邊界附近。這里所說的邊界是指,相當(dāng)于輸入等價類和輸出等價類而言,稍高于其邊界值及稍低于其邊界值的一些特定情況。 使用邊界值分析方法設(shè)計測試用例,首先應(yīng)確定邊界情況。通常輸入等價類與輸出等價類的邊界,就是應(yīng)著重測試的邊界情況。應(yīng)當(dāng)選取正好等于,剛剛大于,或剛剛小于邊界的值做為測試數(shù)據(jù),而不是選取等價類中的典型值或任意值做為測試資料。一般對于有n個變量時,會有6n+1個測試用例,取值分別是min-1, min, min+1, normal, max-1, max,max+1的組合。 邊界值分析方法是最有效的黑盒測試方法,但當(dāng)邊界情況很復(fù)雜的時候,要找出適當(dāng)?shù)臏y試用例還需針對問題的輸入域、輸出域邊界,耐心細(xì)致地逐個考慮。 人們也可以靠經(jīng)驗和直覺推測程序中可能存在的各種錯誤,從而有針對性地編寫檢查這些錯誤的例子。這就是錯誤推測法。 錯誤推測法的基本想法是:列舉出程序中所有可能有的錯誤和容易發(fā)生錯誤的特殊情況,根據(jù)它們選擇測試用例。例如,在介紹單元測試時曾列出許多在模塊中常見的錯誤,這些是單元測試經(jīng)驗的總結(jié)。此外,對于在程序中容易出錯的情況,也有一些經(jīng)驗總結(jié)出來。例如,輸入數(shù)據(jù)為0,或輸出數(shù)據(jù)為0是容易發(fā)生錯誤的情形,因此可選擇輸入數(shù)據(jù)為0,或使輸出數(shù)據(jù)為0的例子作為測試用例。又例如,輸入表格為空或輸入表格只有一行,也是容易發(fā)生錯誤的情況??蛇x擇表示這種情況的例子作為測試用例。再例如,可以針對一個排序程序,輸入空的值(沒有數(shù)據(jù))、輸入一個數(shù)據(jù)、讓所有的輸入數(shù)據(jù)都相等、讓所有輸入數(shù)據(jù)有序排列、讓所有輸入數(shù)據(jù)逆序排列等,進(jìn)行錯誤推測。 前面介紹的等價類劃分方法和邊界值分析方法,都是著重考慮輸入條件,但未考慮輸入條件之間的聯(lián)系。如果在測試時必須考慮輸入條件的各種組合,可能的組合數(shù)將是天文數(shù)字。因此必須考慮使用一種適合于描述對于多種條件的組合,相應(yīng)產(chǎn)生多個動作的形式來考慮設(shè)計測試用例,這就需要利用因果圖。 因果圖方法最終生成的就是判定表。它適合于檢查程序輸入條件的各種組合情況。 利用因果圖生成測試用例的基本步驟是: § 分析軟件規(guī)格說明描述中,哪些是原因(即輸入條件或輸入條件的等價類),哪些是結(jié)果(即輸出條件),并給每個原因和結(jié)果賦予一個標(biāo)識符。 § 分析軟件規(guī)格說明描述中的語義,找出原因與結(jié)果之間,原因與原因之間對應(yīng)的是什么關(guān)系? 根據(jù)這些關(guān)系,畫出因果圖。 § 由于語法或環(huán)境限制,有些原因與原因之間,原因與結(jié)果之間的組合情況不可能出現(xiàn)。為表明這些特殊情況,在因果圖上用一些記號標(biāo)明約束或限制條件。 § 把因果圖轉(zhuǎn)換成判定表。 § 把判定表的每一列拿出來作為依據(jù),設(shè)計測試用例。 通常,在因果圖中,用Ci表示原因,Ei表示結(jié)果,其基本符號如圖7所示。各結(jié)點表示狀態(tài),可取值“0”或“1”。“0”表示某狀態(tài)不出現(xiàn),“1”表示某狀態(tài)出現(xiàn)。 § 恒等:若原因出現(xiàn),則結(jié)果出現(xiàn)。若原因不出現(xiàn),則結(jié)果也不出現(xiàn)。 § 非:若原因出現(xiàn),則結(jié)果不出現(xiàn)。若原因不出現(xiàn),反而結(jié)果出現(xiàn)。 § 或(∨):若幾個原因中有一個出現(xiàn),則結(jié)果出現(xiàn),幾個原因都不出現(xiàn),結(jié)果不出現(xiàn)。 § 與(∧):若幾個原因都出現(xiàn),結(jié)果才出現(xiàn)。若其中有一個原因不出現(xiàn),結(jié)果不出現(xiàn)。 圖7 因果圖的圖形符號 為了表示原因與原因之間,結(jié)果與結(jié)果之間可能存在的約束條件,在因果圖中可以附加一些表示約束條件的符號。從輸入(原因)考慮,有四種約束;從輸出(結(jié)果)考慮,還有一種約束,參看圖8: § E(互斥):表示a,b兩個原因不會同時成立,兩個中最多有一個可能成立。 § M(屏蔽):表示當(dāng)a是1時,b必須是0。而當(dāng)a為0時,b的值不定。 圖8 因果圖的約束符號 因果圖方法是一個非常有效的黑盒測試方法,它能夠生成沒有重復(fù)性的且發(fā)現(xiàn)錯誤能力強(qiáng)的測試用例,而且對輸入、輸出同時進(jìn)行了分析。 Myers提出了使用各種測試方法的綜合策略: § 在任何情況下都必須使用邊界值分析方法。經(jīng)驗表明用這種方法設(shè)計出測試用例發(fā)現(xiàn)程序錯誤的能力最強(qiáng)。 § 必要時用等價類劃分方法補充一些測試用例。 § 用錯誤推測法再追加一些測試用例。 § 對照程序邏輯,檢查已設(shè)計出的測試用例的邏輯覆蓋程度。如果沒有達(dá)到要求的覆蓋標(biāo)準(zhǔn),應(yīng)當(dāng)再補充足夠的測試用例。 § 如果程序的功能說明中含有輸入條件的組合情況,則一開始就可選用因果圖法。 通常采用以下一些方法進(jìn)行源程序的靜態(tài)分析。 ① 生成各種引用表 § 直接從表中查出說明/使用錯誤等。如,循環(huán)層次表、變量交叉引用表、標(biāo)號交叉引用表等。 § 為用戶提供輔助信息。如,子程序(宏、函數(shù))引用表、等價(變量、標(biāo)號)表、常數(shù)表等。 § 用來做錯誤預(yù)測和程序復(fù)雜度計算。如,操作符和操作數(shù)的統(tǒng)計表等。 ② 靜態(tài)錯誤分析 靜態(tài)錯誤分析主要用于確定在源程序中是否有某類錯誤或“危險”結(jié)構(gòu)。 § 類型和單位分析 :為了強(qiáng)化對源程序中數(shù)據(jù)類型的檢查,發(fā)現(xiàn)在數(shù)據(jù)類型上的錯誤和單位上的不一致性,在程序設(shè)計語言中擴(kuò)充了一些結(jié)構(gòu)。如單位分析要求使用一種預(yù)處理器,它能夠通過使用一般的組合/消去規(guī)則,確定表達(dá)式的單位。 § 引用分析 :最廣泛使用的靜態(tài)錯誤分析方法就是發(fā)現(xiàn)引用異常。如果沿著程序的控制路徑,變量在賦值以前被引用,或變數(shù)在賦值以后未被引用,這時就發(fā)生了引用異常。為了檢測引用異常,需要檢查通過程序的每一條路徑。也可以建立引用異常的探測工具。 § 表達(dá)式分析 :對表達(dá)式進(jìn)行分析,以發(fā)現(xiàn)和糾正在表達(dá)式中出現(xiàn)的錯誤。包括:在表達(dá)式中不正確地使用了括號造成錯誤。數(shù)組下標(biāo)越界造成錯誤。除式為零造成錯誤。對負(fù)數(shù)開平方,或?qū)?#960;求正切值造成錯誤。以及對浮點數(shù)計算的誤差進(jìn)行檢查。1.5. 測試與軟件開發(fā)各階段的關(guān)系
2. 程序錯誤分類
2.1 按錯誤的影響和后果分類
2.2 按錯誤的性質(zhì)和范圍分類
2.3按軟件生存期階段分類
3. 軟件測試的過程與策略
3.1單元測試
單元測試任務(wù)包括:1 模塊接口測試;2 模塊局部數(shù)據(jù)結(jié)構(gòu)測試;3 模塊邊界條件測試;4 模塊中所有獨立執(zhí)行通路測試;5 模塊的各條錯誤處理通路測試。
模塊接口測試是單元測試的基礎(chǔ)。只有在數(shù)據(jù)能正確流入、流出模塊的前提下,其它測試才有意義。測試接口正確與否應(yīng)該考慮下列因素:
§ 輸入的實際參數(shù)與形式參數(shù)的個數(shù)是否相同;
§ 輸入的實際參數(shù)與形式參數(shù)的屬性是否匹配;
§ 輸入的實際參數(shù)與形式參數(shù)的量綱是否一致;
§ 調(diào)用其它模塊時所給實際參數(shù)的個數(shù)是否與被調(diào)模塊的形參個數(shù)相同;
§ 調(diào)用其它模塊時所給實際參數(shù)的屬性是否與被調(diào)模塊的形參屬性匹配;
§調(diào)用其它模塊時所給實際參數(shù)的量綱是否與被調(diào)模塊的形參量綱一致;
§ 調(diào)用預(yù)定義函數(shù)時所用參數(shù)的個數(shù)、屬性和次序是否正確;
§ 是否存在與當(dāng)前入口點無關(guān)的參數(shù)引用;
§ 是否修改了只讀型參數(shù);
§ 對全程變量的定義各模塊是否一致;
§ 是否把某些約束作為參數(shù)傳遞。
如果模塊內(nèi)包括外部輸入輸出,還應(yīng)該考慮下列因素:
§ 文件屬性是否正確;
§ OPEN/CLOSE語句是否正確;
§ 格式說明與輸入輸出語句是否匹配;
§ 緩沖區(qū)大小與記錄長度是否匹配;
§ 檔使用前是否已經(jīng)打開;
§ 是否處理了檔尾;
§ 是否處理了輸入/輸出錯誤;
§ 輸出信息中是否有文字性錯誤;
檢查局部數(shù)據(jù)結(jié)構(gòu)是為了保證臨時存儲在模塊內(nèi)的數(shù)據(jù)在程序執(zhí)行過程中完整、正確。局部數(shù)據(jù)結(jié)構(gòu)往往是錯誤的根源,應(yīng)仔細(xì)設(shè)計測試用例,力求發(fā)現(xiàn)下面幾類錯誤:
§ 不合適或不相容的類型說明;
§ 變數(shù)無初值;
§ 變數(shù)初始化或省缺值有錯;
§ 不正確的變量名(拼錯或不正確地截斷);
§ 出現(xiàn)上溢、下溢和地址異常。
除了局部數(shù)據(jù)結(jié)構(gòu)外,如果可能,單元測試時還應(yīng)該查清全局?jǐn)?shù)據(jù)(例如FORTRAN的公用區(qū))對模塊的影響。
在模塊中應(yīng)對每一條獨立執(zhí)行路徑進(jìn)行測試,單元測試的基本任務(wù)是保證模塊中每條語句至少執(zhí)行一次。此時設(shè)計測試用例是為了發(fā)現(xiàn)因錯誤計算、不正確的比較和不適當(dāng)?shù)目刂屏髟斐傻腻e誤。此時基本路徑測試和循環(huán)測試是最常用且最有效的測試技術(shù)。計算中常見的錯誤包括:
§ 誤解或用錯了算符優(yōu)先級;
§ 混合類型運算;
§ 變數(shù)初值錯;
§ 精度不夠;
§ 表達(dá)式符號錯。
比較判斷與控制流常常緊密相關(guān),測試用例還應(yīng)致力于發(fā)現(xiàn)下列錯誤:
§ 不同數(shù)據(jù)類型的對象之間進(jìn)行比較;
§ 錯誤地使用邏輯運算符或優(yōu)先級;
§ 因計算機(jī)表示的局限性,期望理論上相等而實際上不相等的兩個量相等;
§ 比較運算或變量出錯;
§ 循環(huán)終止條件或不可能出現(xiàn);
§ 迭代發(fā)散時不能退出;
§ 錯誤地修改了循環(huán)變量。
一個好的設(shè)計應(yīng)能預(yù)見各種出錯條件,并預(yù)設(shè)各種出錯處理通路,出錯處理通路同樣需要認(rèn)真測試,測試應(yīng)著重檢查下列問題:
§ 輸出的出錯信息難以理解;
§ 記錄的錯誤與實際遇到的錯誤不相符;
§ 在程序自定義的出錯處理段運行之前,系統(tǒng)已介入;
§ 異常處理不當(dāng);
§ 錯誤陳述中未能提供足夠的定位出錯信息。
邊界條件測試是單元測試中最后,也是最重要的一項任務(wù)。眾的周知,軟件經(jīng)常在邊界上失效,采用邊界值分析技術(shù),針對邊界值及其左、右設(shè)計測試用例,很有可能發(fā)現(xiàn)新的錯誤。
單元測試過程
一般認(rèn)為單元測試應(yīng)緊接在編碼之后,當(dāng)源程序編制完成并通過復(fù)審和編譯檢查,便可開始單元測試。測試用例的設(shè)計應(yīng)與復(fù)審工作相結(jié)合,根據(jù)設(shè)計信息選取測試數(shù)據(jù),將增大發(fā)現(xiàn)上述各類錯誤的可能性。在確定測試用例的同時,應(yīng)給出期望結(jié)果。
應(yīng)為測試模塊開發(fā)一個驅(qū)動模塊(driver)和(或)若干個樁模塊(stub),下圖顯示了一般單元測試的環(huán)境。驅(qū)動模塊在大多數(shù)場合稱為“主程序”,它接收測試數(shù)據(jù)并將這些數(shù)據(jù)傳遞到被測試模塊,被測試模塊被調(diào)用后,“主程序”打印“進(jìn)入-退出”消息。
驅(qū)動模塊和樁模塊是測試使用的軟件,而不是軟件產(chǎn)品的組成部分,但它需要一定的開發(fā)費用。若驅(qū)動和樁模塊比較簡單,實際開銷相對低些。遺憾的是,僅用簡單的驅(qū)動模塊和樁模塊不能完成某些模塊的測試任務(wù),這些模塊的單元測試只能采用下面討論的綜合測試方法。
提高模塊的內(nèi)聚度可簡化單元測試,如果每個模塊只能完成一個,所需測試用例數(shù)目將顯著減少,模塊中的錯誤也更容易發(fā)現(xiàn)。3.2 集成測試
3.3確認(rèn)測試
3.4系統(tǒng)測試
4. 測試用例設(shè)計
4.1測試方法概述
4.2邏輯覆蓋
4.3 等價類劃分
4.4邊界值分析
4.5錯誤推測法
4.6因果圖
§ I(包含):表示a,b,c三個原因中至少有一個必須成立。
§ O(唯一):表示a和b當(dāng)中必須有一個,且僅有一個成立。
§ R(要求):表示當(dāng)a出現(xiàn)時,b必須也出現(xiàn)。不可能a出現(xiàn),b不出現(xiàn)。 4.7測試方法選擇的綜合策略
5. 程序的靜態(tài)測試
5.1源程序靜態(tài)分析