




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第12章
面向?qū)ο髮崿F(xiàn)12.1實現(xiàn)在軟件生命周期中的作用12.2實現(xiàn)工作流12.3集成12.4測試工作流12.5用于實現(xiàn)的CASE工具12.6小結(jié)習(xí)題12
知識點
需求工作流,領(lǐng)域模型,業(yè)務(wù)模型,建模技術(shù)。
難點
如何將理論與實踐結(jié)合。
基于工作過程的教學(xué)任務(wù)
通過本章學(xué)習(xí),了解什么是實現(xiàn);搞清楚實現(xiàn)在軟件生命周期中的作用;了解黑盒測試、白盒測試和基于非執(zhí)行的單元測試;掌握集成測試、驗收測試策略;掌握實現(xiàn)工作流、實現(xiàn)類、子系統(tǒng),進行相關(guān)的構(gòu)架實現(xiàn)。通過考勤系統(tǒng)實例研究,學(xué)習(xí)實現(xiàn)工作流,理解實現(xiàn)過程;認(rèn)識到良好的編程實踐和編程標(biāo)準(zhǔn)的必要性。
實現(xiàn)是將詳細(xì)設(shè)計變成代碼的過程。如果只有一個人來做,該過程比較容易理解,但是,現(xiàn)實生活中的產(chǎn)品多數(shù)都很龐大,以至于不可能由一個程序員在給定的時限內(nèi)完成。實現(xiàn)產(chǎn)品的通常是一個團隊,團隊成員同時實現(xiàn)不同的組件,這種方式稱為多方編程。
在編碼實現(xiàn)階段,開發(fā)者根據(jù)設(shè)計模型中對數(shù)據(jù)結(jié)構(gòu)、算法分析和模塊實現(xiàn)等方面的設(shè)計要求,編寫具體的程序,分別實現(xiàn)各模塊的功能,從而實現(xiàn)對目標(biāo)系統(tǒng)的功能、性能、接口、界面等方面的要求。設(shè)計過程完成得好,編碼效率就會極大提高,編碼時不同模塊之間的進度協(xié)調(diào)和協(xié)作是最需要小心的,也許一個小模塊的問題就可能影響了整體進度,讓很多程序員因此被迫停下工作等待,這種問題在很多研發(fā)過程中都出現(xiàn)過。編碼時的相互溝通和應(yīng)急的解決手段都是相當(dāng)重要的,對于程序員而言,bug永遠(yuǎn)存在,你必須永遠(yuǎn)面對這個問題,大名鼎鼎的微軟,可曾有連續(xù)三個月不發(fā)補丁的時候嗎?從來沒有!
12.1實現(xiàn)在軟件生命周期中的作用
在實現(xiàn)階段,基于設(shè)計的結(jié)果,研究如何用源代碼、腳本、二進制代碼、可執(zhí)行體等構(gòu)件來實現(xiàn)系統(tǒng)。
系統(tǒng)構(gòu)架的絕大部分都是在設(shè)計過程中捕獲完成的,實現(xiàn)的主要目的是從總體上充實構(gòu)架和系統(tǒng)。實現(xiàn)的明確目標(biāo)主要有以下幾點:
規(guī)劃每次迭代中所要求的系統(tǒng)集成。采用增量式開發(fā)方法,即采取一系列細(xì)小且易于管理的步驟來實現(xiàn)一個系統(tǒng)。
通過把可執(zhí)行構(gòu)件映射到實施模型中的節(jié)點的方式來分布系統(tǒng)。主要基于設(shè)計過程中發(fā)現(xiàn)的主動類。
實現(xiàn)設(shè)計過程中發(fā)現(xiàn)的設(shè)計類和子系統(tǒng)。特別是要將設(shè)計類實現(xiàn)為包含源代碼的文件構(gòu)件。
對構(gòu)件進行單元測試,然后通過編譯和連接把它們集成為一個或多個可執(zhí)行程序,之后再進行集成和系統(tǒng)測試。
如圖12-1所示,闡明了如何開展實現(xiàn)工作以及有哪些工作人員和制品會參與其中。
圖12-1實現(xiàn)階段中的工作人員和制品
實現(xiàn)主要集中在構(gòu)造迭代階段。細(xì)化階段也要進行實現(xiàn)活動,目的是創(chuàng)建可執(zhí)行的構(gòu)架基線;而移交階段的實現(xiàn)活動是處理那些在系統(tǒng)beta版發(fā)布時發(fā)現(xiàn)的最新缺陷(如圖12-2所示,處于移交區(qū)域中的尖峰)。
實現(xiàn)模型闡述了如何用構(gòu)件和子系統(tǒng)來表示系統(tǒng)的實際實現(xiàn),因此在整個軟件生命周期中很自然地要維護實現(xiàn)模型。
12.2實
現(xiàn)
工
作
流
實現(xiàn)階段的主要目標(biāo)是實現(xiàn)系統(tǒng),由構(gòu)架設(shè)計師通過勾畫實現(xiàn)模型的關(guān)鍵構(gòu)件啟動。然后,系統(tǒng)集成人員規(guī)劃當(dāng)前作為一個構(gòu)造序列的迭代所需的系統(tǒng)集成。對每次構(gòu)造,系統(tǒng)集成人員描述要實現(xiàn)的功能和將影響到實現(xiàn)模型的哪些部分(如子系統(tǒng)和構(gòu)件)。接著,由構(gòu)件工程師來實現(xiàn)構(gòu)造中要求的子系統(tǒng)和構(gòu)件;得到的構(gòu)件經(jīng)過單元測試,提交給集成人員進行集成。
然后,系統(tǒng)集成人員將新的構(gòu)件集成到某個構(gòu)造中,并交給集成測試人員人進行集成測試。之后,開發(fā)人員開始啟動后續(xù)構(gòu)造的實現(xiàn),并考慮以前構(gòu)造中的缺陷。現(xiàn)在,用活動圖來說明實現(xiàn)活動和工作過程,如圖12-3所示。
圖12-3實現(xiàn)中的工作流包括參與的工作人員及其活動
12.2.1構(gòu)架實現(xiàn)
構(gòu)架實現(xiàn)的目的是通過如下途徑勾畫實現(xiàn)模型及其構(gòu)架:
識別對構(gòu)架有重要意義的構(gòu)件,例如可執(zhí)行構(gòu)件;
在相關(guān)的網(wǎng)絡(luò)配置中將構(gòu)件映射到節(jié)點上。
在構(gòu)架設(shè)計過程中,要勾畫設(shè)計子系統(tǒng)及其內(nèi)容和接口。在實現(xiàn)過程中,使用與設(shè)計子系統(tǒng)一一對應(yīng)的實現(xiàn)子系統(tǒng),并提供相同的接口。因此,對實現(xiàn)子系統(tǒng)及其接口的識別就顯得價值不大,在此就不作討論。相反,在實現(xiàn)階段,主要的任務(wù)是在實現(xiàn)子系統(tǒng)范圍內(nèi)創(chuàng)建實現(xiàn)相應(yīng)的設(shè)計子系統(tǒng)的構(gòu)件。在該活動中,構(gòu)架設(shè)計師維護、精化并更新構(gòu)架描述以及實現(xiàn)模型和實施模型的構(gòu)架視圖。
1.確定對構(gòu)架有重要意義的構(gòu)件
通常的實際做法是在軟件生命周期的早期確定對構(gòu)架有重要意義的構(gòu)件,以便啟動實現(xiàn)工作(如圖12-4所示)。
然而,在實現(xiàn)類時,許多構(gòu)件(特別是文件構(gòu)件)的初始創(chuàng)建工作相當(dāng)瑣碎,這些構(gòu)件基本上只是提供將實現(xiàn)類包裝成源代碼文件的一種方法。由于這個原因,開發(fā)人員必須注意在這一階段不能確定太多的構(gòu)件或作過分詳細(xì)的設(shè)計。否則,在實現(xiàn)類時,許多工作不得不重做。事實上,只要勾畫出一個對構(gòu)架有重要意義的構(gòu)件的初始的輪廓就足夠了。
圖12-4構(gòu)架實現(xiàn)的輸入和結(jié)果
2.確定可執(zhí)行構(gòu)件并把它們映射到節(jié)點上
為了識別能夠部署到節(jié)點上的可執(zhí)行構(gòu)件,要考慮在設(shè)計階段得到的主動類,為每個主動類分配一個可執(zhí)行構(gòu)件,并將它標(biāo)記為一個任務(wù)繁重的進程,也許還要確定為創(chuàng)建該可執(zhí)行構(gòu)件所需的其他文件或二進制構(gòu)件。
接著考慮設(shè)計模型和實施模型,檢查是否存在可分配給節(jié)點的主動對象。如果有,那么對應(yīng)于該主動類的相應(yīng)構(gòu)件必須實施到相同的節(jié)點上。
構(gòu)件到節(jié)點的映射對于構(gòu)架來說非常重要,應(yīng)該在實施模型的構(gòu)架視圖中加以描述。
12.2.2系統(tǒng)集成
如圖12-5所示,系統(tǒng)集成的目的是為了:
創(chuàng)建集成構(gòu)造計劃,描述迭代中所需的構(gòu)造和對每個構(gòu)造的需求;
在進行集成測試前集成每個構(gòu)造。
如圖12-5所示,設(shè)計模型中“用例實現(xiàn)—設(shè)計”是該活動的基本輸入。
圖12-5系統(tǒng)集成的輸入和結(jié)果
1.規(guī)劃后續(xù)的構(gòu)造
下面是用于后續(xù)構(gòu)造的一些原則:
后續(xù)的構(gòu)造應(yīng)該通過實現(xiàn)完整的用例或場景來向以前的構(gòu)造添加功能。構(gòu)造的集成測試要基于這些用例,測試完整的用例比測試其片段要容易;
構(gòu)造不能包括太多新增的或精化的構(gòu)件。否則,很難集成這樣的構(gòu)造并執(zhí)行集成測試。如果必要,可以采用構(gòu)造中介紹的方法,即可以用樁來實現(xiàn)一些構(gòu)件,從而將新構(gòu)件的數(shù)量最少化;
構(gòu)造應(yīng)該以先前的構(gòu)造為基礎(chǔ),向上擴展到子系統(tǒng)層次結(jié)構(gòu)的邊界。就是說,初始的構(gòu)造應(yīng)該在較低層次開始(例如中間件層和系統(tǒng)軟件層)。然后,后續(xù)的構(gòu)造向上擴展到通用應(yīng)用層和專用應(yīng)用層。因為,在較低層次上的構(gòu)件已經(jīng)存在且具有正確的功能之前,很難實現(xiàn)更高層次上的構(gòu)件,這是典型的分層系統(tǒng)的特征。
牢記這些原則,就可以評估要實現(xiàn)的需求,比如要實現(xiàn)的用例(或場景)。注意,在按照一種方法并遵循這些原則的過程中,很可能需要一定的折衷。例如,實現(xiàn)一個完整的用例可能需要很多新的構(gòu)件,但是如果該用例對當(dāng)前的構(gòu)造來說很重要,則無論如何也要實現(xiàn)。
對于每個要實現(xiàn)的潛在用例,要按照以下步驟去做:
(1)通過識別設(shè)計模型中相應(yīng)的用例實現(xiàn)—設(shè)計來考慮該用例的設(shè)計。通過跟蹤依賴關(guān)系,用例實現(xiàn)—設(shè)計可以跟蹤到用例;
(2)識別參與用例實現(xiàn)—設(shè)計中的設(shè)計子系統(tǒng)和類;
(3)識別出實現(xiàn)模型中可跟蹤到設(shè)計子系統(tǒng)和類的實現(xiàn)子系統(tǒng)和構(gòu)件,這就是在實現(xiàn)用例時所需要的實現(xiàn)子系統(tǒng)和構(gòu)件;
(4)要考慮實現(xiàn)這些需求對當(dāng)前構(gòu)造頂層的實現(xiàn)子系統(tǒng)和構(gòu)件所帶來的影響。注意,這些需求是從設(shè)計子系統(tǒng)和類的角度進行描述的。按照前面描述的原則來評估這樣的影響是否可以接受。如果可以,就把這個用例的實現(xiàn)安排到下一個構(gòu)造中;否則,就把它遺留給將來的某個構(gòu)造。
這些結(jié)果應(yīng)該在制定集成構(gòu)造計劃時捕獲,并與具體負(fù)責(zé)的構(gòu)件工程師保持良好的溝通。然后,構(gòu)件工程師就可在當(dāng)前的構(gòu)造中著手實現(xiàn)這些子系統(tǒng)和構(gòu)件,并進行單元測試。之后,將實現(xiàn)子系統(tǒng)和構(gòu)件移交給系統(tǒng)集成人員進行集成。
2.集成
如上所述,如果對構(gòu)造做了仔細(xì)的規(guī)劃,構(gòu)造集成就相當(dāng)容易。通過匯集合適版本的實現(xiàn)子系統(tǒng)和構(gòu)件,進行編譯,然后連接,就可得到一個構(gòu)造。注意,在層次結(jié)構(gòu)的系統(tǒng)里,編譯工作可能需要自下而上地進行,因為較高層次和較低層次之間可能存在編譯依賴關(guān)系。
得到的構(gòu)造如果通過了集成測試,而且是一個迭代最后創(chuàng)建的構(gòu)造時,就可以進行產(chǎn)品測試和系統(tǒng)測試了。
12.2.3實現(xiàn)子系統(tǒng)
實現(xiàn)子系統(tǒng)的目的是確保一個子系統(tǒng)履行它在每個構(gòu)造中的角色,這意味著要保證在構(gòu)造中要實現(xiàn)的需求(如場景或用例)以及那些影響子系統(tǒng)的需求能通過子系統(tǒng)內(nèi)部的構(gòu)件和其他子系統(tǒng)正確地加以實現(xiàn),如圖12-6所示。
圖12-6子系統(tǒng)實現(xiàn)的輸入和結(jié)果
當(dāng)子系統(tǒng)內(nèi)部的構(gòu)件和其他子系統(tǒng)正確地實現(xiàn)了當(dāng)前構(gòu)造中要實現(xiàn)的需求以及那些影響子系統(tǒng)的需求時,一個子系統(tǒng)就實現(xiàn)了其目標(biāo)。
即使子系統(tǒng)的內(nèi)容(例如構(gòu)件)是由構(gòu)架設(shè)計師勾畫的,隨著實現(xiàn)模型的進一步完善,仍然需要由構(gòu)件工程師來精化。精化包括下面兩個方面。
如圖12-7所示,設(shè)計子系統(tǒng)內(nèi)的每個類應(yīng)該由實現(xiàn)子系統(tǒng)中的構(gòu)件來實現(xiàn)。
圖12-7通過構(gòu)件實現(xiàn)某個構(gòu)造中所需的設(shè)計類
當(dāng)前構(gòu)造所需的設(shè)計子系統(tǒng)所提供的每個接口也應(yīng)該由實現(xiàn)子系統(tǒng)提供。因此,實現(xiàn)子系統(tǒng)必須包含提供該接口的構(gòu)件或?qū)崿F(xiàn)子系統(tǒng),如圖12-8所示。
現(xiàn)在,構(gòu)件工程師就可以開始實現(xiàn)子系統(tǒng)內(nèi)所需要的構(gòu)件,并對它們進行單元測試。然后,將所得到的子系統(tǒng)交由系統(tǒng)集成人員進行集成。
圖12-8在某個構(gòu)造(α)中所需的接口也應(yīng)該由實現(xiàn)子系統(tǒng)提供
12.2.4實現(xiàn)類
實現(xiàn)類的目的是為了在文件構(gòu)件中實現(xiàn)設(shè)計類,如圖12-9所示,它主要完成勾畫出包含源代碼的文件構(gòu)件,從設(shè)計類及其所參與的關(guān)系中生成源代碼,按照方法實現(xiàn)設(shè)計類的操作,確保構(gòu)件提供與設(shè)計類相同的接口4項任務(wù)。
實現(xiàn)活動還應(yīng)包括處理已實現(xiàn)類的各方面的維護問題,例如對類進行測試后要進行缺陷修復(fù)。
圖12-9實現(xiàn)類的輸入和結(jié)果
1.勾畫文件構(gòu)件
實現(xiàn)設(shè)計類的源代碼存放在文件構(gòu)件中,因此必須勾畫出文件構(gòu)件并考慮其作用域。在一個文件中實現(xiàn)幾個設(shè)計類是很常見的,但是,注意,正在使用的文件模塊化方法和編程語言約定將對如何勾畫文件構(gòu)件產(chǎn)生限制。例如,當(dāng)使用Java時,要為每個類的實現(xiàn)創(chuàng)建一個“.java”格式的文件構(gòu)件。通常,文件構(gòu)件應(yīng)該支持系統(tǒng)的編譯、安裝和維護。
2.從設(shè)計類中生成源代碼
在設(shè)計過程中,設(shè)計類及其關(guān)系的許多細(xì)節(jié)都是用編程語言的語法描述的,這就可以生成部分源代碼,從而使實現(xiàn)類的工作簡單明了,尤其是,這種方法還支持類的操作和屬性以及類所參與的關(guān)系的實現(xiàn)。但是,通常只能生成操作的特征標(biāo)記,而操作本身仍須由程序員來實現(xiàn)。
注意,可以從關(guān)聯(lián)和聚合中產(chǎn)生代碼,其實現(xiàn)方法在很大程度上取決于所用的編程語言。例如,具有單向?qū)Ш教匦缘年P(guān)聯(lián)可用對象間的“引用”來實現(xiàn),這個引用將作為引用對象的一個屬性,而屬性名就是關(guān)聯(lián)另一端的角色名;關(guān)聯(lián)另一端的多重性決定屬性類型應(yīng)該是一個簡單指針(如果多重性小于等于1)或是一個指針集合(如果多重性大于1)。
3.實現(xiàn)操作
在設(shè)計類中定義的每個操作都必須實現(xiàn),除非該操作是“抽象的”(或“虛擬的”)且由該類的子類實現(xiàn),這里用“方法”來表示操作的實現(xiàn)。在實際存在的文件構(gòu)件中,方法的實例有Java中的方法、VisualBasic的方法和C++中的成員函數(shù)。
實現(xiàn)一個操作包括選擇合適的算法和支持的數(shù)據(jù)結(jié)構(gòu),然后對算法所需的動作進行編碼。在設(shè)計類的過程中,方法可能已經(jīng)用自然語言或偽代碼描述(這很少見,經(jīng)常浪費時間),但是,任何“設(shè)計方法”都應(yīng)該作為這里的輸入。同時,任何為設(shè)計類描述的狀態(tài)會影響到實現(xiàn)操作的方式,因為在收到消息時,設(shè)計類的狀態(tài)決定其行為。
4.使構(gòu)件提供正確的接口
所得到的構(gòu)件應(yīng)該提供和設(shè)計類相同的接口。
12.2.5執(zhí)行單元測試
執(zhí)行單元測試的目的是為了把已實現(xiàn)的構(gòu)件作為個體單元進行測試,如圖12-10所示。主要有下面幾類單元測試。
規(guī)格說明測試或“黑盒測試”(或功能測試)為驗證單元外觀上可觀察的行為,結(jié)構(gòu)測試或“白盒測試”(或邏輯測試)為驗證單元的內(nèi)部實現(xiàn)。
注意,對于某些單元,可能還要執(zhí)行許多其他類型的測試,比如性能、內(nèi)存使用情況、負(fù)載和容量等方面的測試。同時,還必須執(zhí)行集成和系統(tǒng)測試,以保證將幾個構(gòu)件集成在一起后可以正確地工作。
圖12-10單元測試的輸入和結(jié)果
1.執(zhí)行規(guī)格說明測試
規(guī)格說明測試是在不考慮構(gòu)件內(nèi)部如何實現(xiàn)的情況下驗證構(gòu)件的行為。因此,規(guī)格說明測試是某個構(gòu)件處在特定狀態(tài)下,給定輸入,觀察返回結(jié)果(輸出)??赡艿妮斎搿⒊跏紶顟B(tài)和輸出的組合范圍通常很大,要測試所有的組合是不可能的,因此,可將輸入、輸出和狀態(tài)劃分為等價類。一個等價類是一組輸入、狀態(tài)和輸出值,可以推測要測試的對象在等價類上具有相似的行為。通過測試構(gòu)件的每個等價類組合的輸入、輸出和狀態(tài),幾乎可以取得與測試所有獨立值組合時相同的和有效的測試覆蓋,從而極大地減少了測試工作量。
舉例:等價類
一個賬戶的狀態(tài)有三個等價類:余額為零、余額為負(fù)(或許是透支)、余額為正。同樣地,輸入變量可以分為兩個等價類:零和正數(shù)。輸出變量也可分為兩個等價類:取款額為正或取款額為零。
構(gòu)件工程師可以基于試探法選擇出下列的測試值:
每個等價類允許的范圍內(nèi)的正常值,例如,從賬戶中支出4、3.14、5923元;
等價類的邊界值,例如,取款為0、最小正值(如0.00000001)和最大的可能值;
等價類合法邊界之外的值,例如,取出比合法值更大或更小的數(shù)目;
非法值,例如,取款值為-14和A。
選擇測試時,構(gòu)件工程師應(yīng)該力求覆蓋輸入狀態(tài)和輸出的所有組合,例如從下列狀況中提取14元:
賬戶中有-234.13元,結(jié)果為取出0元;
賬戶中有0元,結(jié)果為取出0元;
賬戶中有12.125元,結(jié)果為取出0元;
賬戶中有15元,結(jié)果為取出14元。
這四個測試用例的結(jié)果是在所有合法的狀態(tài)(余額為正和余額為負(fù))和輸出(取款額為正和取款額為零)等價類組合中,從每個等價類中取出一個值進行測試。然后,構(gòu)件工程師應(yīng)該選擇具有類似狀態(tài)(可能是-234.13、0、13.125和15元)和輸出值(0和14元),但從同一個輸入等價類中取出不同值(如3.14元)的組合所組成的測試用例進行測試。
然后,構(gòu)件工程師準(zhǔn)備從輸入值的其他等價類取值,組成類似值域的測試用例進行測試。例如,可以試圖從輸入值域中取出0、4、3.14、5923、0.00000001、37000000000000000000000(如果這是最大的可能值)、37000000000000000000001、-14和A元等值進行測試。
2.執(zhí)行結(jié)構(gòu)測試
結(jié)構(gòu)測試是有意識地驗證構(gòu)件的內(nèi)部工作。在結(jié)構(gòu)測試過程中,構(gòu)件工程師一定要測試所有代碼,這意味著每條語句至少要執(zhí)行一次。構(gòu)件工程師還應(yīng)保證測試代碼中絕大部分感興趣的路徑,包括最常執(zhí)行的路徑、最關(guān)鍵的路徑、某算法中最少了解的路徑以及高風(fēng)險的路徑等。
圖12-11為“賬戶”類定義的一個簡單的取款方法
綜上所述,實現(xiàn)階段的主要結(jié)果是實現(xiàn)包含以下元素的實現(xiàn)模型:
實現(xiàn)子系統(tǒng)及其依賴關(guān)系、接口和內(nèi)容;
構(gòu)件(包括文件構(gòu)件和可執(zhí)行構(gòu)件)以及它們之間的依賴,構(gòu)件經(jīng)過了單元測試;
實現(xiàn)模型的構(gòu)架視圖,包括對構(gòu)架有重要意義的元素。
當(dāng)可執(zhí)行構(gòu)件被映射到節(jié)點時,實現(xiàn)還對實施模型的構(gòu)架視圖進行了細(xì)致的精化和改進。實現(xiàn)模型對于以后的測試活動來說是主要的輸入,在測試期間,每個特定的來自實現(xiàn)的構(gòu)造都需要進行集成測試,也有可能需要系統(tǒng)測試。
12.3集
成
考慮圖12-12中描繪的產(chǎn)品,產(chǎn)品集成的一種方法是單獨編寫和測試每個代碼制品,然后連接13個代碼制品,最后對產(chǎn)品的整體進行測試。圖12-12一種反映模塊間調(diào)用關(guān)系的典型系統(tǒng)集成結(jié)構(gòu)
這樣的集成方法,有兩個困難。
首先,模塊A不能依靠自身進行測試,它調(diào)用了模塊B、C和D,要測試模塊A,模塊B、C、D必須有存根程序。最簡單的存根就是一個空模塊,有效的存根是打印一條消息,例如“這里是模塊B。”,最好的存根返回與預(yù)先計劃好的測試用例相吻合的值。要測試模塊H,就需要一個能調(diào)用模塊H一次或多次的代碼,即驅(qū)動程序,如果可能,要檢查被測試代碼的返回值。類似的,測試模塊D需要一個驅(qū)動與兩個存根。因此,隨著實現(xiàn)和集成,第一個問題出現(xiàn)了:需要花大量的精力在構(gòu)建存根與驅(qū)動上,但是,這些程序在單元測試完成后都會被拋棄。
在實現(xiàn)完成之后,集成工作開始之前,出現(xiàn)的第二個更大的困難是缺乏錯誤隔離的手段。如果產(chǎn)品作為整體測試,在某個特定的測試用例下產(chǎn)品失敗了,該錯誤可能存在于13個代碼模塊或13個接口的任何地方,在有103個代碼模塊和108個接口的大型軟件中,可能隱藏錯誤的地方不會少于211個。
解決這兩個困難的方案是將單元測試與集成測試結(jié)合起來。
1.自頂向下的集成
在自頂向下集成中,有寬度和深度優(yōu)先集成。假設(shè)圖12-12中的產(chǎn)品是自頂向下實現(xiàn)與集成的,自頂向下的一種可能順序是A、B、C、D、E、F、G、H、I、J、K、L和M。首先,編寫存根B、C、D來測試A,接下來存根B擴展為代碼B,與代碼A連接,同時用存根E對B進行測試,實現(xiàn)與集成按照這種方式進行下去,直到所有代碼都集成到產(chǎn)品中。自頂向下的另一種可能順序是A、B、E、H、C、D、F、I、G、J、K、L和M。在這種順序下,集成的部分工作可以并行進行,方式如下:在A編碼和測試結(jié)束后,一個程序員可以利用代碼A來實現(xiàn)與集成B、E、H,而另一個程序員可以利用代碼A并行地工作于C、D、F和I,一旦D與F完成,第三個程序員可以開始對G、J、K、L和M進行集成。
假定代碼制品A在某個特定的測試用例上執(zhí)行是正確的,而當(dāng)B編碼完成并集成后,提交同樣的測試數(shù)據(jù)時,測試結(jié)果失敗了。錯誤可能在兩個地方之一:代碼制品B或代碼制品A與B之間的接口。這樣,自頂向下集成支持錯誤隔離。
自頂向下集成的另一個優(yōu)勢是設(shè)計錯誤的早期顯現(xiàn)。軟件的代碼制品可以分為兩組:邏輯制品和操作制品。邏輯制品本質(zhì)上表現(xiàn)為軟件產(chǎn)品控制方面的決策流,例如,在圖12-12中,認(rèn)為代碼制品A、B、C、D或許還有G、J是邏輯制品是合理的。另一方面是軟件產(chǎn)品中進行實際操作的操作制品,操作制品一般位于圖的較低層,例如,在圖12-12中,制品E、F、H、I、K、L和M是操作制品。
在對操作制品進行編碼和測試前,對邏輯制品的編碼與測試通常是非常重要的,這可以確保主要的設(shè)計錯誤較早顯現(xiàn)。如果整個產(chǎn)品完成后才發(fā)現(xiàn)一個嚴(yán)重錯誤,那么產(chǎn)品的大部分代碼都要重寫,特別是包含控制流程的邏輯制品。許多操作制品在產(chǎn)品的重構(gòu)過程中可以復(fù)用,不管產(chǎn)品如何重構(gòu),操作制品與其他代碼制品之間的連接方式可能需要發(fā)生變化。因此,設(shè)計錯誤越早發(fā)現(xiàn),修正產(chǎn)品錯誤并使軟件開發(fā)回到計劃中的花費就越小,而且時間也就越短。采用自頂向下的策略進行制品實現(xiàn)與集成,確保了邏輯制品在操作制品之前實現(xiàn)與集成,因為在模塊關(guān)系圖中,邏輯制品幾乎總是操作制品的祖先,這是自頂向下集成的一個主要優(yōu)勢。
但是,自頂向下集成的也有一個缺點:可復(fù)用代碼制品可能測試不充分。復(fù)用那些誤認(rèn)為已經(jīng)經(jīng)過充分測試的代碼制品,很可能比重寫代碼更沒效率,因為當(dāng)產(chǎn)品失敗時,那些復(fù)用代碼制品正確的假象會造成錯誤的結(jié)論。測試者可能不會懷疑復(fù)用代碼沒有經(jīng)過充分的測試,而是認(rèn)為錯誤隱藏在其他的地方,這樣就會造成精力的浪費。
2.自底向上的集成
在自底向上集成中,先對低層制品進行實現(xiàn)和集成,然后,實現(xiàn)和集成高層的制品。在圖12-12中,一種可能的自底向上的順序是L、M、H、I、J、K、E、F、G、B、C、D、A。從團隊角度出發(fā),下面的自底向上的順序更好:H、E、B交給一個程序員,I、F、C交給另一個,第3個程序員從L、M、J、K、G開始,然后實現(xiàn)D,并將他的工作和第2個程序員集成,最后,B、C、D成功的集成以后,就可以實現(xiàn)和集成A了。
當(dāng)采用自底向上策略時,操作制品可以得到充分的測試。另外,測試通過驅(qū)動的協(xié)助完成,而不是通過錯誤保護、保守編程的制品來完成。盡管自底向上的集成解決了自頂向下集成的主要難題,并且與自頂向下的集成一樣具有錯誤隔離的優(yōu)勢,但是,還是有自己的難題。特別是重大設(shè)計錯誤要到實現(xiàn)工作流后期才發(fā)現(xiàn),邏輯制品最后集成,因此,如果有重大設(shè)計錯誤,將需要花費巨大的精力來重新設(shè)計和編寫大部分的產(chǎn)品代碼。
因此,自頂向下與自底向上的集成各有優(yōu)劣。產(chǎn)品開發(fā)的解決方案通常結(jié)合這兩種策略,揚長避短,于是就有了三明治集成。
3.三明治集成(也稱混合集成)
考慮圖12-13所示的模塊關(guān)系圖。邏輯制品是A、B、C、D、G、J這6個代碼制品,因此采用自頂向下集成。操作制品是E、F、H、I、K、L、M這7個代碼制品,應(yīng)該采用自底向上集成。如前所述,無論是自頂向下還是自底向上集成都不能滿足所有的制品,所以將它們分開處理。6個邏輯制品采用自頂向下集成,那么,重大設(shè)計錯誤就能夠及早發(fā)現(xiàn)。7個操作制品采用自底向上集成,得不到保守編程制品的保護,從而得到充分的測試,因此可以在其他產(chǎn)品中放心復(fù)用。所有制品都正確的集成后,再一個個的測試兩組制品之間的接口,整個過程都有錯誤隔離,稱為三明治集成或混合集成。
圖12-13采用三明治集成策略集成圖12-12的產(chǎn)品
圖12-14總結(jié)了三明治集成的優(yōu)缺點,以及前面討論的集成技術(shù)。
圖12-14集成方法匯總
“如何實現(xiàn)三明治集成”總結(jié)了三明治集成的方法,如圖12-15所示。
圖12-15如何實現(xiàn)三明治集成
4.集成技術(shù)
對象既可以自底向上集成,也可以自頂向下集成。如果選用自頂向下的集成方法,每個方法都可以使用存根。如果用自底向上的集成,那些不發(fā)送消息給其他對象的對象首先實現(xiàn)和集成,然后實現(xiàn)和集成那些發(fā)送消息的對象。如此下去,直到實現(xiàn)和集成完產(chǎn)品中的所有對象。
因為同時支持自頂向下和自底向上,所以三明治集成也可以使用。如果產(chǎn)品是用C++這樣的混合型面向?qū)ο笳Z言實現(xiàn)的,通常類都是操作制品,因此自底向上集成。許多不是類的制品都是邏輯制品,因此自頂向下的實現(xiàn)與集成。剩下的制品都是操作性的,可以自底向上的實現(xiàn)與集成。最后,所有的非對象制品都集成到對象中。
采用Java語言來實現(xiàn),類方法(有時也稱為靜態(tài)方法),如main以及實用程序方法通常與邏輯模塊在結(jié)構(gòu)上相似。因此,類方法也是自頂向下的實現(xiàn),然后集成到其他對象中去。換句話說,實現(xiàn)和集成面向?qū)ο螽a(chǎn)品,也會用到三明治集成的變種。
5.集成管理
集成階段發(fā)現(xiàn)的管理問題是,代碼制品不能簡單的連接在一起。
舉例:溝通不及時可能造成接口問題
程序員1編寫了對象o1,程序員2編寫了對象o2。在程序員1使用的設(shè)計文檔中,對象o1發(fā)送消息給對象o2,傳遞4個變量,但是程序員2使用的設(shè)計文檔卻只有3個變量傳給o2。如果沒有通知開發(fā)小組的全體成員,僅僅對設(shè)計文檔的一份拷貝進行修改,就會出現(xiàn)這樣的問題。兩個程序員都認(rèn)為自己是正確的,誰也不愿意妥協(xié),因為做出讓步的程序員必須重寫產(chǎn)品的大部分代碼。
要解決這類不兼容問題,整個集成過程必須由SQA小組實行,并且在其他階段的測試中,如果集成測試執(zhí)行不成功,那么SQA小組要負(fù)主要責(zé)任。因此,SQA小組會確保測試徹底的執(zhí)行。SQA小組負(fù)責(zé)人要對集成測試的各方面負(fù)責(zé),他決定哪些制品采用自頂向下的實現(xiàn)和集成,哪些制品采用自底向上的實現(xiàn)和集成,并把集成測試任務(wù)分配給正確的人選。SQA小組在軟件項目管理計劃中制定了集成測試計劃,同樣要負(fù)責(zé)執(zhí)行該計劃。
集成過程的最后階段是,所有的代碼制品都已經(jīng)經(jīng)過測試并集成為單一的產(chǎn)品。
12.4測
試
工
作
流
實現(xiàn)工作流要執(zhí)行許多不同種類的測試,包括單元測試、集成測試、產(chǎn)品測試和驗收測試等。這些類型的測試前面已有詳細(xì)的介紹。
代碼要經(jīng)歷兩種類型的測試:程序員在開發(fā)代碼段時進行非正規(guī)的單元測試,當(dāng)程序員認(rèn)為代碼段的功能正常以后,由SQA小組進行系統(tǒng)的單元測試。有兩類基本的測試方法:基于非執(zhí)行的測試,代碼段由一個小組評審,主要用于編碼之前所得到的制品;基于執(zhí)行的測試,對照測試用例運行代碼段,主要用于編碼時得到的代碼。
在測試工作流中,通過測試每個構(gòu)造(包括內(nèi)部構(gòu)造、中間構(gòu)造以及將要向外部發(fā)布的系統(tǒng)最終版本)來驗證實現(xiàn)的結(jié)果。明確地講,測試的目的如下:
規(guī)劃每次迭代需要的測試工作,包括集成測試和系統(tǒng)測試。迭代中的每個構(gòu)造都需要進行集成測試,而系統(tǒng)測試僅需在迭代結(jié)束時進行;
設(shè)計和實現(xiàn)測試,采取的方法是創(chuàng)建用來詳細(xì)說明要測試什么的測試用例,并創(chuàng)建用來詳細(xì)說明如何執(zhí)行測試的測試規(guī)程,若可能,還要創(chuàng)建測試自動化可執(zhí)行的測試構(gòu)件;
執(zhí)行各種測試并系統(tǒng)地處理每個測試的結(jié)果。發(fā)現(xiàn)有缺陷的構(gòu)造要重新測試,甚至可能要送回給其他核心工作流(如設(shè)計和實現(xiàn)),這樣才能修復(fù)嚴(yán)重的缺陷。
下面將闡明如何開展測試工作以及哪些工作人員和制品會參與到其中,如圖12-16所示,測試工作流與實現(xiàn)工作流幾乎相同。
圖12-16參與測試的工作人員和制品
1.測試在軟件生命周期中的作用
當(dāng)確定系統(tǒng)范圍后,就可在初始階段制定初始的測試計劃,但是,測試主要應(yīng)用在對每個構(gòu)造(作為實現(xiàn)結(jié)果)進行集成測試和系統(tǒng)測試時,這意味著測試既是細(xì)化階段(測試可執(zhí)行的構(gòu)架基線)的焦點,也是構(gòu)造階段(實現(xiàn)了系統(tǒng)的絕大部分)的焦點。在移交階段,焦點轉(zhuǎn)向修復(fù)在早期使用中發(fā)現(xiàn)的缺陷,并進行回歸測試,如圖12-17所示。
圖12-17測試的焦點
由于開發(fā)工作的迭代性,一些說明如何測試早期構(gòu)造的測試用例也可用作說明如何測試后續(xù)構(gòu)造的回歸測試用例。在迭代中對回歸測試的需要逐步增長,這意味著后期迭代將包括大量的回歸測試。所以,雖然測試模型會不斷演化,但是,在整個軟件生命周期中仍然需要維護測試模型。測試模型的演化方式包括以下幾種:
移走過期的測試用例(以及相應(yīng)的測試規(guī)程和測試構(gòu)件);
把一些測試用例改造成回歸測試用例;
為每個后續(xù)構(gòu)造創(chuàng)建新的測試用例。
2.測試工作流
現(xiàn)在用活動圖來說明測試工作的行為,如圖12-18所示。
圖12-18測試期間的工作流
測試的主要目的是為了執(zhí)行并評估測試模型所描述的測試,由在每次迭代中規(guī)劃測試事宜的測試工程師發(fā)起;接著,測試工程師描述所需的測試用例以及執(zhí)行這些測試用例的測試規(guī)程;然后,如果可能,構(gòu)件工程師要建立起使某些測試規(guī)程自動化的測試構(gòu)件。當(dāng)每個構(gòu)件從實現(xiàn)工作流中發(fā)布時,就會按上面的步驟進行測試。
用這些測試用例、測試規(guī)程及測試構(gòu)件作為輸入,集成測試人員和系統(tǒng)測試人員測試每個構(gòu)件并捕獲發(fā)現(xiàn)的所有缺陷,然后,將這些缺陷反饋給其他工作流(如設(shè)計和實現(xiàn)),還要反饋給測試工程師,以對測試結(jié)果進行系統(tǒng)的評估。
3.測試用例的選擇
使用隨意的測試數(shù)據(jù)測試代碼制品是最差的方法。測試者坐在鍵盤前,只要制品要求輸入,測試者以任意數(shù)據(jù)響應(yīng)。將會看到,這樣只能測試所有可能的測試用例的極小部分,時間不允許測試更多的數(shù)據(jù),因為數(shù)據(jù)組合輕易就可以達(dá)到比10100還多。能夠運行的少數(shù)測試用例(可能在1000這個量級上)非常寶貴,不能浪費在隨意的數(shù)據(jù)上。更糟糕的是,如果機器對同樣的輸入數(shù)據(jù)響應(yīng)多次,就會浪費更多的測試用例,顯然,測試用例選擇必須系統(tǒng)化進行,具體的技術(shù)不再贅述。
4.黑盒單元測試技術(shù)
徹底的黑盒測試一般要求數(shù)10億的測試用例,測試的藝術(shù)在于設(shè)計一個較小的容易管理的測試用例集,使發(fā)現(xiàn)錯誤的概率最大化,同時使多個測試用例發(fā)現(xiàn)同一個錯誤而浪費測試用例的概率最小化,所選的每個測試用例必須能發(fā)現(xiàn)前面沒有找到的錯誤。通常采用的黑盒測試技術(shù)是等價類劃分結(jié)合邊界值分析,這里不再贅述。
5.白盒單元測試技術(shù)
在白盒測試技術(shù)中,測試用例的選擇是基于對代碼而不是規(guī)格說明的檢查。有許多不同形式的白盒測試,包括語句、分支和路徑覆蓋等,請參考具體的白盒測試技術(shù)。
6.代碼走查和審查
代碼審查是由若干程序員和測試員組成一個審查小組,通過閱讀、討論和爭論,對程序進行靜態(tài)分析的過程。代碼審查分兩步。第一步,小組負(fù)責(zé)人提前把設(shè)計規(guī)格說明書、控制流程圖、程序文本及有關(guān)要求、規(guī)范等分發(fā)給小組成員,作為審查的依據(jù)。小組成員在充分閱讀這些材料后,進入審查的第二步,召開程序?qū)彶闀?/p>
走查與代碼審查基本相同,其過程分為兩步。第一步把材料先發(fā)給走查小組每個成員,讓他們認(rèn)真研究程序,然后再開會。開會的程序與代碼審查不同,不是簡單地讀程序和對照錯誤檢查表進行檢查,而是讓與會者“充當(dāng)計算機”,即首先由測試組成員為被測程序準(zhǔn)備一批有代表性的測試用例,提交給走查小組。走查小組開會,集體扮演計算機角色,讓測試用例沿程序的邏輯運行一遍,隨時記錄程序的蹤跡,供分析和討論用。
代碼走查和代碼審查的觀點是一致的,這兩項靜態(tài)技術(shù)的錯誤發(fā)現(xiàn)能力將錯誤檢測引向快速、徹底和提前。這樣,由于在集成階段出現(xiàn)的錯誤較少而提高了生產(chǎn)率,用于代碼走查和審查的額外時間得到了巨大的回報,而且,代碼審查可降低高達(dá)95%的改正性維護成本。
進行代碼審查的另一個原因是,基于執(zhí)行的測試(測試用例)在以下兩個方面代價非常大。第一,耗費時間。第二,與基于執(zhí)行的測試相比,審查可使錯誤在軟件生命周期的更早期得到檢測和糾正。經(jīng)驗表明,越早發(fā)現(xiàn)和糾正一個錯誤,花費的成本就越少。
7.何時重寫而不是調(diào)試代碼制品
當(dāng)SQA小組的成員發(fā)現(xiàn)故障(錯誤的輸出)時,代碼制品必須返回給原來的程序員進行調(diào)試,即檢測錯誤,改正代碼。在有些情況下,扔掉該代碼段從頭開始重新設(shè)計和重新編寫可能更可取,可以由最初的程序員完成,也可以由另一個更資深的小組成員來完成。
為什么要這樣?圖12-19展示了一個與直覺相反的概念,代碼制品中存在更多錯誤的概率與代碼制品中目前發(fā)現(xiàn)的錯誤數(shù)成正比。
圖12-19發(fā)現(xiàn)錯誤的可能性與已檢測出的錯誤數(shù)成正比
現(xiàn)在,有兩個代碼制品a1和a2。假定這兩個代碼制品長度相近,經(jīng)過相同時間的測試。進一步假設(shè)在a1中只發(fā)現(xiàn)2個錯誤,而在a2中發(fā)現(xiàn)48個錯誤,那么在a2中比a1中很可能仍然存在更多的錯誤,并且對a2進行額外的測試和調(diào)試的過程可能更長,甚至?xí)岩蒩2仍不完善。無論短期還是長期來看,最好的辦法是放棄a2,重新設(shè)計和編寫。
舉例:錯誤分布的不均勻性
錯誤在模塊中的分布是不均勻的。Myers引用了用戶在OS/370中發(fā)現(xiàn)的錯誤的例子,結(jié)果表明47%的錯誤只與4%的模塊有關(guān)。更早一些,Endres在德國Boblingen的IBM實驗室所做的關(guān)于DOS/VS(28版)的內(nèi)部測試顯示了類似的不均勻性。202個模塊總共發(fā)現(xiàn)512個錯誤,有112個模塊只發(fā)現(xiàn)1個錯誤;另一方面,某些模塊分別發(fā)現(xiàn)了14、15、19和28個錯誤。Endres指出,后3個模塊是產(chǎn)品中最大的3個模塊,每個都由超過3000行的DOS宏匯編語言組成,而發(fā)現(xiàn)14個錯誤的模塊是一個已知的、非常不穩(wěn)定的小模塊,這類模塊可以考慮丟棄或重寫。
管理者處理這種情況的辦法是,預(yù)先確定一個給定代碼制品在開發(fā)期間所允許的最大錯誤數(shù),一旦達(dá)到該值,就必須丟棄,然后由有經(jīng)驗的軟件設(shè)計人員重新設(shè)計和編寫。最大值會隨著應(yīng)用領(lǐng)域的不同而不同,還會隨著代碼制品的不同而不同。確定允許的最大錯誤數(shù)可以參考某個類似的已得到糾錯性維護的代碼制品的錯誤情況。但是,不管采用什么估計技術(shù),一旦超出預(yù)定的錯誤數(shù),管理者必須保證放棄該代碼制品。
8.集成測試
每個新的代碼制品在加入到已集成的模塊中時都必須進行集成測試。關(guān)鍵是首先采用單元測試技術(shù)測試新的代碼制品,然后采用自頂向下或自底向上或三明治的集成策略來進行集成并完成測試。
集成過程完成后,軟件產(chǎn)品作為整體進行測試,叫產(chǎn)品測試。當(dāng)開發(fā)者對軟件產(chǎn)品各方面的正確性都能保證時,就把它交給客戶進行驗收測試。
9.驗收測試
客戶進行驗收測試的目的是確定產(chǎn)品是否確實滿足規(guī)格說明。驗收測試可以由客戶組織實施,也可以在有客戶代表在場的情況下由SQA小組實施,或由客戶雇用的獨立SQA小組實施。驗收測試包括正確性測試,但除此之外,還需要進行性能和健壯性測試。驗收測試的4個主要組成部分,即正確性測試、健壯性測試、性能測試、文檔測試。
驗收測試的關(guān)鍵在于必須在真實數(shù)據(jù)上而不是在測試數(shù)據(jù)上實施測試。產(chǎn)品通過驗收測試后,開發(fā)者的任務(wù)就完成了,現(xiàn)在起對產(chǎn)品所做的任何更改都屬于交付后維護。
10.測試工作流:考勤系統(tǒng)案例研究
考勤系統(tǒng)的Java實現(xiàn)必須經(jīng)過白盒和黑盒測試,由于每次迭代都要實現(xiàn)系統(tǒng)的一部分,測試工作流在每次迭代都要執(zhí)行,這里就不再詳細(xì)介紹。
12.5用于實現(xiàn)的CASE工具
在CASE工具中,支持代碼制品實現(xiàn)的CASE工具是最成熟的,也是最早出現(xiàn)的,現(xiàn)在通常有集成版本控制工具、創(chuàng)建工具和配置管理工具。
1.軟件開發(fā)全過程的CASE工具
CASE工具本身有個自然發(fā)展的過程。最簡單的CASE是個單獨的工具,比如在線接口檢查器或創(chuàng)建工具。接下來,可以對工具進行組合,由此產(chǎn)生支持一個或兩個軟件開發(fā)過程活動的工作平臺,比如配置控制或編碼。但是,這樣的工作平臺甚至不能為軟件開發(fā)過程提供有用的管理信息,更不用說為整個項目了。最終,形成了為開發(fā)過程提供大部分(即使不是全部)計算機輔助支持環(huán)境的CASE工具。
理想狀態(tài)下,每個軟件開發(fā)組織應(yīng)當(dāng)使用一種環(huán)境。使用環(huán)境的成本可能會非常大,不僅僅是軟件包本身,還包括該軟件運行的硬件設(shè)備。對于小公司來說,一個工作平臺或一套工具也就足夠了。但如果可能的話,應(yīng)該采用集成開發(fā)環(huán)境來進行軟件開發(fā)和維護。
2.集成開發(fā)環(huán)境
集成在CASE環(huán)境中的最普遍的含義是用戶接口集成,即所有工具在環(huán)境中共享通用的用戶接口,這句話的內(nèi)在含義是,如果所有工具都有一樣的可視界面,那么使用環(huán)境中某個工具的用戶可以沒有任何困難地學(xué)習(xí)和使用其中的另一種工具。這種思想在Macintosh中獲得了成功,Macintosh中的大部分應(yīng)用軟件都有相似的“外觀和感受”。當(dāng)然這只是通常的含義,也有其他類型的集成。
工具集成是指所有的工具采用相同的數(shù)據(jù)格式進行通信。這樣,一個工具的輸出流指向另一工具的輸入流就可以實現(xiàn)兩個工具的組合。Eclipse是用于工具集成的開源環(huán)境。
過程集成指支持一個特定軟件過程的環(huán)境。基于技術(shù)的環(huán)境是這類環(huán)境的子集,這類環(huán)境只支持開發(fā)軟件的某一特定技術(shù),而不是全過程。這些環(huán)境采用圖形化界面為分析和設(shè)計提供支持,并集成了數(shù)據(jù)字典,此外,還提供了一致性檢驗,環(huán)境中往往還集成了對開發(fā)過程管理的支持。目前有許多商業(yè)環(huán)境,包括支持狀態(tài)圖的Rhapsody和支持統(tǒng)一過程的IBMRationalRose。
3.商業(yè)應(yīng)用環(huán)境
另一類環(huán)境是用于開發(fā)面向商業(yè)產(chǎn)品的重要環(huán)境,強調(diào)易用性,采用多
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 基本知識培訓(xùn)課件學(xué)校
- 從數(shù)據(jù)到洞察:DEA與Bootstrap-DEA方法在技術(shù)效率估計中的比較剖析
- 八年級數(shù)學(xué)一次函數(shù)綜合測試試卷及答案
- 三維高密度集成系統(tǒng)下多物理場耦合算法的深度探索與創(chuàng)新發(fā)展
- HLA-G表達(dá):解鎖結(jié)直腸癌診療密碼的新視角
- 八年級數(shù)學(xué)三元一次方程組試卷及答案
- 基層醫(yī)院高血壓病課件
- 新解讀《GB-T 39713-2020精細(xì)陶瓷粉體比表面積試驗方法 氣體吸附BET法》
- 新解讀《GB-T 24981.2-2020稀土長余輝熒光粉試驗方法 第2部分:余輝亮度的測定》
- uml面試題及答案
- 超詳細(xì)展覽會、展會期間事項推進表
- 杭州三花微通道換熱器有限公司環(huán)境影響報告
- 無人機飛行原理-空氣動力學(xué)基礎(chǔ)
- 河道保潔服務(wù)投標(biāo)方案
- 新概念英語第二冊單詞(帶音標(biāo))電子完整版
- 腹腔鏡下胰十二指腸切除術(shù)手術(shù)記錄
- 特氣系統(tǒng)安全操作規(guī)范方案
- mel04版修訂當(dāng)前有效允許1個完全或部分丟失
- 工作場所空氣中粉塵測定
- 防靜電培訓(xùn)知識
- 新疆建設(shè)工程質(zhì)量監(jiān)督管理工作手冊
評論
0/150
提交評論