軟件工程與項(xiàng)目管理(第2版) 課件 (王素芬)第7、8章 軟件編碼、軟件測試與調(diào)試_第1頁
軟件工程與項(xiàng)目管理(第2版) 課件 (王素芬)第7、8章 軟件編碼、軟件測試與調(diào)試_第2頁
軟件工程與項(xiàng)目管理(第2版) 課件 (王素芬)第7、8章 軟件編碼、軟件測試與調(diào)試_第3頁
軟件工程與項(xiàng)目管理(第2版) 課件 (王素芬)第7、8章 軟件編碼、軟件測試與調(diào)試_第4頁
軟件工程與項(xiàng)目管理(第2版) 課件 (王素芬)第7、8章 軟件編碼、軟件測試與調(diào)試_第5頁
已閱讀5頁,還剩115頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

7.1軟件編碼的目的

7.2程序設(shè)計語言

7.3結(jié)構(gòu)化程序設(shè)計

7.4編碼風(fēng)格

7.5程序編碼優(yōu)化技術(shù)

7.6代碼評審和版本控制7.1軟件編碼的目的作為軟件工程的一個步驟,軟件編碼是軟件設(shè)計的自然結(jié)果。編碼階段的主要任務(wù)是根據(jù)軟件詳細(xì)設(shè)計階段產(chǎn)生的每個模塊的詳細(xì)設(shè)計說明書,編寫成某種程序設(shè)計語言的源程序。為了提高系統(tǒng)的可維護(hù)性,除要求源程序的語法正確外,還要求源程序有較好的可讀性、可靠性和可測試性。同時,編程語言的特性以及編寫程序的風(fēng)格也將深刻地影響到軟件的質(zhì)量及可維護(hù)性。7.2程序設(shè)計語言7.2.1程序設(shè)計語言的分類目前,用于軟件開發(fā)的程序設(shè)計語言已經(jīng)有數(shù)百種之多,對這些程序設(shè)計語言的分類有不少爭議。同一種語言可以歸到不同的類中。從軟件工程的角度,根據(jù)程序設(shè)計語言發(fā)展的歷程,可以把它們大致分為以下5類:(1)機(jī)器語言(第一代語言)。機(jī)器語言是由機(jī)器指令代碼組成的語言。對于不同的機(jī)器就有相應(yīng)的一套機(jī)器語言。用這種語言編寫的程序,都是二進(jìn)制代碼的形式,且所有的地址分配都是以絕對地址的形式處理。存儲空間的安排,寄存器、變址的使用都由程序員自己計劃。因此使用機(jī)器語言編寫的程序很不直觀,在計算機(jī)內(nèi)的運(yùn)行效率很高,但出錯率也高。(2)匯編語言(第二代語言)。匯編語言比機(jī)器語言直觀,它的每一條符號指令與相應(yīng)的機(jī)器指令有對應(yīng)關(guān)系,同時又增加了一些諸如宏、符號地址等功能。存儲空間的安排可由機(jī)器解決。不同指令集的處理器系統(tǒng)就有自己相應(yīng)的匯編語言。從軟件工程的角度來看,匯編語言只是在高級語言無法滿足設(shè)計要求時,或者不具備支持某種特定功能的技術(shù)性能時,才被使用。(3)高級程序設(shè)計語言(第三代語言)。高級程序設(shè)計語言是算法語言。為了解決編程人員的困難,20世紀(jì)50年代中期出現(xiàn)了第一個算法語言——FORTRAN語言。后來又相繼出現(xiàn)了COBOL、ALGOL60、BASIC、PL/1、PASCAL、MODULA-2、C、Ada等語言,這些算法語言的特點(diǎn)是用一種接近于自然語言和數(shù)學(xué)的專用語言來表示算法,算法語言不依賴于計算機(jī)硬件,是面向過程的語言。(4)第四代語言(4GL)。4GL用不同的文法表示程序結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),但是它是在更高一級抽象的層次上表示這些結(jié)構(gòu),它不再需要規(guī)定算法的細(xì)節(jié)。4GL兼有過程性和非過程性的兩重特性。程序員規(guī)定“條件和相應(yīng)的動作”是過程性的部分,而“指出想要的結(jié)果”是非過程性的部分。然后由4GL語言系統(tǒng)運(yùn)用它的專門領(lǐng)域的知識來填充過程細(xì)節(jié)。(4)第四代語言(4GL)。4GL用不同的文法表示程序結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),但是它是在更高一級抽象的層次上表示這些結(jié)構(gòu),它不再需要規(guī)定算法的細(xì)節(jié)。4GL兼有過程性和非過程性的兩重特性。程序員規(guī)定“條件和相應(yīng)的動作”是過程性的部分,而“指出想要的結(jié)果”是非過程性的部分。然后由4GL語言系統(tǒng)運(yùn)用它的專門領(lǐng)域的知識來填充過程細(xì)節(jié)。第四代語言可以分為以下幾種類型:①查詢語言:用戶可利用查詢語言對預(yù)先定義在數(shù)據(jù)庫中的信息進(jìn)行較復(fù)雜的操作。②程序生成器:只需很少的語句就能生成完整的第三代語言程序,它不必依賴預(yù)先定義的數(shù)據(jù)庫作為它的著手點(diǎn)。③其他4GL:如判定支持語言、原型語言、形式化規(guī)格說明語言等。(5)第五代程序設(shè)計語言(第五代語言)。第五代語言是一種新型程序設(shè)計語言。進(jìn)入20世紀(jì)60年代后,擺脫馮·諾依曼概念的束縛已成為眾多語言學(xué)家為之奮斗的目標(biāo),為此目標(biāo)而研制的語言被稱為新型程序設(shè)計語言,也稱為知識型程序設(shè)計語言。新型程序設(shè)計語言力求擺脫傳統(tǒng)語言那種狀態(tài)轉(zhuǎn)換語義的模式,以適應(yīng)現(xiàn)代計算機(jī)系統(tǒng)知識化、智能化的發(fā)展趨勢。新型程序設(shè)計語言基本上可以分為邏輯型語言和面向?qū)ο笮驼Z言。7.2.2程序設(shè)計語言特性的比較我們從以下3種角度來比較程序設(shè)計語言的特性:(1)心理學(xué)的觀點(diǎn)。從設(shè)計到編碼的轉(zhuǎn)換基本上是人的活動,因此語言的性能對程序員的心理影響將對轉(zhuǎn)換產(chǎn)生重大作用。程序員總是希望選擇簡單易學(xué)、使用方便的語言,以減少程序出錯率,提高軟件可靠性。從心理學(xué)的觀點(diǎn),影響程序員心理的語言特性有一致性、二義性、簡潔性(緊湊性)、局部性、線性、傳統(tǒng)六種。(2)軟件工程觀點(diǎn)。從軟件工程觀點(diǎn),程序設(shè)計語言的特性應(yīng)著重考慮軟件開發(fā)項(xiàng)目的需要。為此,對于程序編碼,有如下一些工程上的性能要求:①詳細(xì)設(shè)計應(yīng)能直接地、容易地翻譯成代碼程序。②源程序應(yīng)具有可移植性。③編譯程序應(yīng)具有較高的效率。④盡可能應(yīng)用代碼生成的自動工具。⑤可維護(hù)性。(3)程序設(shè)計語言的技術(shù)性能。在計劃階段,極少考慮程序語言的技術(shù)特性。但在選定資源時,要規(guī)劃將要使用的支撐工具,就要確定一個具體的編譯器或者確定一個程序設(shè)計環(huán)境。如果軟件開發(fā)組的成員對所要使用的語言不熟悉,那么在成本及進(jìn)度估算時必須把學(xué)習(xí)的工作量估算在內(nèi)。一旦確定了軟件需求,待選用的程序語言的技術(shù)特性就顯得非常重要了。如果需要復(fù)雜的數(shù)據(jù)結(jié)構(gòu),就要仔細(xì)衡量有哪些語言能提供這些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。如果首要的是高性能及實(shí)時處理的能力,就可選用適合于實(shí)時應(yīng)用的語言或效率高的語言。如果該應(yīng)用有許多輸出報告或繁雜的文件處理,則最好是根據(jù)軟件的要求,選定一種適合于該項(xiàng)工作的語言。軟件的設(shè)計質(zhì)量與程序設(shè)計語言的技術(shù)性能無關(guān)(面向?qū)ο笤O(shè)計例外)。但在實(shí)現(xiàn)軟件設(shè)計轉(zhuǎn)化為程序代碼時,轉(zhuǎn)化的質(zhì)量往往受語言性能的影響。因而也會影響到設(shè)計方法。語言的技術(shù)性能對測試和維護(hù)的影響是多種多樣的。但是,語言的某些技術(shù)特性卻會妨礙測試。此外,只要語言程序的可讀性強(qiáng),而且可以減少程序的復(fù)雜性,這樣的程序設(shè)計語言對于軟件的維護(hù)就是有利的??傊?,通過仔細(xì)地分析和比較,選擇一種功能強(qiáng)而又適用的語言,對成功地實(shí)現(xiàn)從軟件設(shè)計到編碼的轉(zhuǎn)換,提高軟件的質(zhì)量,改善軟件的可測試性和可維護(hù)性是至關(guān)重要的。7.2.3程序設(shè)計語言的選擇為某個特定開發(fā)項(xiàng)目選擇程序設(shè)計語言時,既要從技術(shù)角度、工程角度、心理學(xué)角度評價和比較各種語言的適用程度,又必須考慮現(xiàn)實(shí)可能性所需做出的某種合理折中。有實(shí)際經(jīng)驗(yàn)的軟件開發(fā)人員往往有這樣的體會,在他們進(jìn)行決策時經(jīng)常面臨的是矛盾的選擇。在選擇和評價語言時,首先要從問題入手,確定它的要求是什么?這些要求的相對重要性如何?再根據(jù)這些要求和相對重要性來衡量能采用的語言。通??紤]的原因有:(1)項(xiàng)目的應(yīng)用范圍(最關(guān)鍵);(2)算法和計算復(fù)雜性;(3)軟件執(zhí)行的環(huán)境;(4)性能上的考慮和實(shí)現(xiàn)的條件;(5)數(shù)據(jù)結(jié)構(gòu)的復(fù)雜性;(6)軟件開發(fā)人員的知識水平、心理原因等。新的更強(qiáng)有力的語言,雖然對于應(yīng)用有很強(qiáng)的吸引力,但是因?yàn)橐延械恼Z言已經(jīng)積累了大量的久經(jīng)使用的程序,具有完整的資料、支撐軟件和軟件開發(fā)工具,程序設(shè)計人員比較熟悉,而且有過類似項(xiàng)目的開發(fā)經(jīng)驗(yàn)和成功的先例,所以出于心理原因,人們往往寧愿選用原有的語種。所以應(yīng)當(dāng)徹底地分析、評價、介紹新的語言,以便從原有語言過渡到新的語言。7.3結(jié)構(gòu)化程序設(shè)計7.3.1結(jié)構(gòu)化程序設(shè)計的原則結(jié)構(gòu)化程序設(shè)計應(yīng)遵循以下原則:(1)使用語言中的順序、選擇、重復(fù)等有限的基本控制結(jié)構(gòu)表示程序邏輯。(2)選用的控制結(jié)構(gòu)只準(zhǔn)許有一個入口和一個出口。(3)程序語句組成容易識別的塊,每塊只有一個入口和一個出口。(4)復(fù)雜結(jié)構(gòu)應(yīng)該用基本控制結(jié)構(gòu)進(jìn)行組合嵌套來實(shí)現(xiàn)。(5)語言中沒有的控制結(jié)構(gòu),可用一段等價的程序段模擬,但要求該程序段在整個系統(tǒng)中應(yīng)前后一致。(6)嚴(yán)格控制GOTO語句,僅在用一個非結(jié)構(gòu)化的程序設(shè)計語言去實(shí)現(xiàn)一個結(jié)構(gòu)化的構(gòu)造,或者在某種可以改善而不是損害程序可讀性的情況下才可以使用GOTO語句。大量采用GOTO語句實(shí)現(xiàn)控制路徑,會使程序路徑變得復(fù)雜而且混亂,因此要控制GOTO語句的使用。但有時完全不用GOTO語句進(jìn)行程序編碼,比用GOTO語句編出的程序可讀性差。對于常用的高級程序設(shè)計語言,一般都具備前述的幾種基本控制結(jié)構(gòu)。即使不具備等同的結(jié)構(gòu),也可以采用等價的程序段來模擬。下面以C語言為例進(jìn)行說明,參看圖7.1。7.3.2程序設(shè)計——自頂向下、逐步求精在詳細(xì)設(shè)計和編碼階段,應(yīng)當(dāng)采取自頂向下、逐步求精的方法,把一個模塊的功能逐步分解,細(xì)化為一系列具體的步驟,進(jìn)而翻譯成一系列用某種程序設(shè)計語言寫成的程序。自頂向下、逐步求精方法的優(yōu)點(diǎn):(1)自頂向下、逐步求精方法符合人們解決復(fù)雜問題的普遍規(guī)律,可提高軟件開發(fā)的成功率和生產(chǎn)率。(2)用先全局后局部,先整體后細(xì)節(jié),先抽象后具體的逐步求精的過程開發(fā)出來的程序具有清晰的層次結(jié)構(gòu),因此程序容易閱讀和理解。(3)程序自頂向下、逐步細(xì)化,分解成一個樹形結(jié)構(gòu)(如圖7.2所示)。在同一層的結(jié)點(diǎn)上做的細(xì)化工作相互獨(dú)立。在任何一步發(fā)生錯誤,一般只影響它下層的結(jié)點(diǎn),同一層其他結(jié)點(diǎn)不受影響。在以后的測試過程中,也可以先獨(dú)立地一個結(jié)點(diǎn)、一個結(jié)點(diǎn)地測試,最后再集成。(4)程序清晰和模塊化,使得在修改和重新設(shè)計一個軟件時,可復(fù)用的代碼量最大。(5)每一步工作僅在上層結(jié)點(diǎn)的基礎(chǔ)上做不多的設(shè)計擴(kuò)展,便于檢查。(6)有利于設(shè)計的分工和組織工作。7.3.3數(shù)據(jù)結(jié)構(gòu)的合理化結(jié)構(gòu)化程序設(shè)計主要是想從程序的控制結(jié)構(gòu)入手,消除不適應(yīng)的、容易引起混亂的GOTO語句。然而這只是問題的一個方面,在問題的另一方面,過去沒有注意到的是數(shù)據(jù)結(jié)構(gòu)的合理化問題,即數(shù)據(jù)結(jié)構(gòu)訪問的規(guī)范化、標(biāo)準(zhǔn)化問題。假如數(shù)據(jù)結(jié)構(gòu)中常使用數(shù)組、指針等數(shù)據(jù)類型,則對它們必須采取隨機(jī)訪問,這樣勢必產(chǎn)生訪問上的混亂。解決這一問題的辦法是用棧和隊(duì)列去代替數(shù)組和指針。棧與隊(duì)列分別是按后進(jìn)先出(LIFO)和先進(jìn)先出(FIFO)的原則進(jìn)行存取的。在程序中用棧和隊(duì)列代替數(shù)組和指針,用合理的規(guī)范的順序存取代替隨機(jī)存取,將克服隨機(jī)存取帶來的麻煩。而且經(jīng)實(shí)踐證明,所有使用數(shù)組和指針的程序,都可以等價替換為使用棧和隊(duì)列的程序。7.4編碼風(fēng)格7.4.1程序的內(nèi)部文檔為實(shí)現(xiàn)源程序的文檔化,使得源程序更具有可讀性,應(yīng)采用清晰明了、風(fēng)格統(tǒng)一的標(biāo)識符命名規(guī)范,同時在程序中添加必要的注釋,并利用空格、空行提高程序的可視化程度。1.標(biāo)識符的命名標(biāo)識符包括模塊名、變量名、常量名、子程序名、數(shù)據(jù)區(qū)名、緩沖區(qū)名等。對于標(biāo)識符的命名一般有以下要求:(1)標(biāo)識符的命名要清晰、明了,有一定實(shí)際意義,可使用完整的單詞或大家基本可以理解的縮寫,避免使人產(chǎn)生誤解。較短的單詞可通過去掉“元音”形成縮寫;較長的單詞可取單詞的頭幾個字母形成縮寫;一些單詞有大家公認(rèn)的縮寫。(2)命名中若使用特殊約定或縮寫,則要有注釋說明。應(yīng)該在源文件的開始,對文件中所使用的縮寫或約定,特別是特殊的縮寫進(jìn)行必要的注釋說明。(3)自己特有的命名風(fēng)格,要自始至終保持一致,不可來回變化。個人的命名風(fēng)格,在符合所在項(xiàng)目組或產(chǎn)品組的命名規(guī)則的前提下,才可使用(即命名規(guī)則中沒有規(guī)定到的地方才可有個人命名風(fēng)格)。(4)對于變量命名,盡量不要取單個字符(如i、j、k…),建議除了要有具體含義外,還能表明其變量類型、數(shù)據(jù)類型等,但i、j、k作局部循環(huán)變量是允許的。變量,尤其是局部變量,如果用單個字符表示,則很容易敲錯(如i寫成j),而編譯時又檢查不出來,有可能為了這個小小的錯誤而花費(fèi)大量的查錯時間。(5)命名規(guī)范必須與所使用的系統(tǒng)風(fēng)格保持一致,并在同一項(xiàng)目中統(tǒng)一。比如采用UNIX的全小寫加下畫線的風(fēng)格或大小寫混排的方式,不要使用大小寫與下畫線混排的方式。用作特殊標(biāo)識如標(biāo)識成員變量或全局變量的m_和g_,其后加上大小寫混排的方式是允許的。(6)名字不是越長越好,過長的名字會使程序的邏輯流程變得模糊,給修改帶來困難。所以應(yīng)當(dāng)選擇精煉的、意義明確的名字,以改善對程序功能的理解。(7)在一個程序中,一個變量只應(yīng)用于一種用途。就是說,在同一個程序中一個變量不能身兼幾種工作。(8)除非必要,不要用數(shù)字或較奇怪的字符來定義標(biāo)識符。(9)在同一軟件產(chǎn)品內(nèi),應(yīng)規(guī)劃好接口部分標(biāo)識符(變量、結(jié)構(gòu)、函數(shù)及常量)的命名,防止編譯、鏈接時產(chǎn)生沖突。對接口部分的標(biāo)識符應(yīng)該有更嚴(yán)格的限制,以防止沖突。如可規(guī)定接口部分的變量與常量之前加上“模塊”標(biāo)識等。(10)用正確的反義詞組命名具有互斥意義的變量或相反動作的函數(shù)等。2.程序的注釋夾在程序中的注釋是程序員與日后的程序讀者之間通信的重要手段。正確的注釋能夠幫助讀者理解程序,可為后續(xù)階段進(jìn)行測試和維護(hù)提供明確的指導(dǎo)。因此,注釋絕不是可有可無的,大多數(shù)程序設(shè)計語言允許使用自然語言來寫注釋,這就給閱讀程序帶來很大的方便。程序的注釋有以下要求:(1)一般情況下,源程序有效注釋量必須在20%以上。注釋的原則是有助于對程序的閱讀理解,注釋不宜太多也不能太少,注釋語言必須準(zhǔn)確、易懂、簡潔。(2)說明性文件(如頭文件.h文件、.inc文件、.def文件、編譯說明文件.cfg等)頭部應(yīng)進(jìn)行注釋,注釋應(yīng)列出:版權(quán)說明、版本號、生成日期、作者、內(nèi)容、功能、與其他文件的關(guān)系、修改日志等,頭文件的注釋中還應(yīng)有函數(shù)功能簡要說明。(3)源文件頭部應(yīng)進(jìn)行注釋,列出:版權(quán)說明、版本號、生成日期、作者、模塊目的/功能、主要函數(shù)及其功能、修改日志等。(4)函數(shù)頭部應(yīng)進(jìn)行注釋,列出:函數(shù)的目的/功能、輸入?yún)?shù)、輸出參數(shù)、返回值、調(diào)用關(guān)系(函數(shù)、表)等。(5)邊寫代碼邊注釋,修改代碼同時修改相應(yīng)的注釋,以保證注釋與代碼的一致性。不再有用的注釋要刪除。(6)注釋的內(nèi)容要清楚、明了,含義準(zhǔn)確,防止注釋二義性。(7)避免在注釋中使用縮寫,特別是非常用的縮寫。在使用縮寫時或之前,應(yīng)對縮寫進(jìn)行必要的說明。(8)注釋應(yīng)與其描述的代碼相近,對代碼的注釋應(yīng)放在其上方或右方(對單條語句的注釋)相鄰位置,不可放在下面,如放于上方則需要與其上面的代碼用空行隔開。(9)對于所有有物理含義的變量、常量,如果其命名不是充分自注釋的,則在聲明時都必須加以注釋,說明其物理含義。變量、常量、宏的注釋應(yīng)放在其上方相鄰位置或右方。(10)數(shù)據(jù)結(jié)構(gòu)聲明(包括數(shù)組、結(jié)構(gòu)、類、枚舉等),如果其命名不是充分自注釋的,則必須加以注釋。對數(shù)據(jù)結(jié)構(gòu)的注釋應(yīng)放在其上方相鄰位置,不可放在下面;對結(jié)構(gòu)中的每個域的注釋放在此域的右方。(11)全局變量要有較詳細(xì)的注釋,包括對其功能、取值范圍、哪些函數(shù)或過程存取它以及存取時注意事項(xiàng)等的說明。(12)注釋與所描述內(nèi)容進(jìn)行同樣的縮排。(13)將注釋與其上面的代碼用空行隔開。(14)對變量的定義和分支語句(條件分支、循環(huán)語句等)必須編寫注釋。(15)避免在一行代碼或表達(dá)式的中間插入注釋。(16)通過對函數(shù)或過程、變量、結(jié)構(gòu)等正確的命名以及合理地組織代碼的結(jié)構(gòu),使代碼成為自注釋的。(17)在代碼的功能、意圖層次上進(jìn)行注釋,提供有用、額外的信息。(18)在程序塊的結(jié)束行右方加注釋標(biāo)記,以表明某程序塊的結(jié)束。(19)注釋應(yīng)考慮程序易讀及外觀排版的因素,使用的語言若是中、英兼有的,則建議多使用中文,除非能用非常流利準(zhǔn)確的英文表達(dá)。注釋語言不統(tǒng)一,影響程序易讀性和外觀排版,出于對維護(hù)人員的考慮,建議使用中文。3.視覺組織利用空格、空行和移行,提高程序的可視化程度。(1)恰當(dāng)?shù)乩每崭?,可以突出運(yùn)算的優(yōu)先性,避免發(fā)生運(yùn)算的錯誤。(2)自然的程序段之間可用空行隔開。(3)對于選擇語句和循環(huán)語句,把其中的程序段語句向右做階梯式移行。這樣可使程序的邏輯結(jié)構(gòu)更加清晰,層次更加分明。7.4.2數(shù)據(jù)說明在編寫程序時,需要注意數(shù)據(jù)說明的風(fēng)格。為了使程序中數(shù)據(jù)說明更易于理解和維護(hù),必須注意以下幾點(diǎn):(1)數(shù)據(jù)說明的次序應(yīng)當(dāng)規(guī)范化,使數(shù)據(jù)屬性容易查找。(2)當(dāng)多個變量名用一個語句說明時,應(yīng)當(dāng)對這些變量按字母的順序排列。(3)如果設(shè)計了一個復(fù)雜的數(shù)據(jù)結(jié)構(gòu),則應(yīng)當(dāng)使用注釋來說明在程序?qū)崿F(xiàn)時這個數(shù)據(jù)結(jié)構(gòu)的固有特點(diǎn)。7.4.3語句結(jié)構(gòu)在設(shè)計階段確定了軟件的邏輯結(jié)構(gòu),但構(gòu)造單個語句則是編碼階段的任務(wù)。語句構(gòu)造應(yīng)力求簡單、直接,不能為了片面追求效率而使語句復(fù)雜化。因此,編碼中對語句的編寫應(yīng)遵循以下的原則:(1)在一行內(nèi)只寫一條語句,并且采取適當(dāng)?shù)囊菩懈袷?,使程序的邏輯和功能變得更加明確。(2)盡量用公共過程或子程序去代替重復(fù)的功能代碼段。(3)使用括號來清晰地表達(dá)算術(shù)表達(dá)式和邏輯表達(dá)式的運(yùn)算順序。(4)避免不必要的轉(zhuǎn)移。同時如果能保持程序的可讀性,則不必用GOTO語句。(5)盡量只采用3種基本的控制結(jié)構(gòu)來編寫程序。(6)避免采用過于復(fù)雜的判定條件。(7)盡量減少使用“否定”條件的條件語句。(8)避免過多的循環(huán)嵌套和條件嵌套。(9)不要使GOTO語句相互交叉。(10)避免循環(huán)的多個出口。(11)使用數(shù)組,以避免重復(fù)的控制序列。(12)對遞歸定義的數(shù)據(jù)結(jié)構(gòu)盡量使用遞歸過程。(13)注意計算機(jī)浮點(diǎn)數(shù)運(yùn)算的特點(diǎn),例如,浮點(diǎn)數(shù)運(yùn)算10.0*0.1,通常不等于1.0。(14)不要單獨(dú)進(jìn)行浮點(diǎn)數(shù)的比較。用它們做比較,其結(jié)果常常發(fā)生異常情況。(15)在程序中應(yīng)有出錯處理功能,一旦出現(xiàn)故障時不要讓操作系統(tǒng)進(jìn)行干預(yù),這樣會導(dǎo)致停工。7.4.4輸入和輸出輸入和輸出(I/O)信息是與用戶的使用直接相關(guān)的。輸入和輸出的方式和格式應(yīng)當(dāng)盡可能方便用戶的使用。因此,在軟件需求分析階段和設(shè)計階段,就應(yīng)基本確定輸入和輸出的風(fēng)格。系統(tǒng)能否被用戶接受,有時就取決于輸入和輸出的風(fēng)格。不論是批處理的輸入/輸出方式,還是交互式的輸入/輸出方式,在設(shè)計和程序編碼時都應(yīng)考慮下列原則:(1)對所有的輸入數(shù)據(jù)都進(jìn)行檢驗(yàn),從而識別錯誤的輸入,以保證每個數(shù)據(jù)的有效性。(2)檢查輸入項(xiàng)的各種重要組合的合理性,必要時報告輸入狀態(tài)信息。(3)輸入的步驟和操作盡可能簡單,并保持簡單的輸入格式。(4)輸入數(shù)據(jù)時,應(yīng)允許使用自由格式輸入。(5)應(yīng)允許缺省值。(6)輸入一批數(shù)據(jù)時,最好使用輸入結(jié)束標(biāo)志,而不要由用戶指定輸入數(shù)據(jù)數(shù)目。(7)在以交互式輸入/輸出方式進(jìn)行輸入時,要在屏幕上明確提示交互輸入的請求,指明可使用選擇項(xiàng)的種類和取值范圍。同時,在數(shù)據(jù)輸入的過程中和輸入結(jié)束時,也要在屏幕上給出狀態(tài)信息。(8)當(dāng)程序設(shè)計語言對輸入/輸出格式有嚴(yán)格要求時,應(yīng)保持輸入格式與輸入語句的要求的一致性。(9)給所有的輸出加注解,并設(shè)計輸出報表格式。輸入/輸出風(fēng)格還受到許多其他因素的影響。如輸入/輸出設(shè)備、用戶的熟練程度以及通信環(huán)境等。Wasserman為“用戶軟件工程及交互系統(tǒng)的設(shè)計”提供了以下一組指導(dǎo)性原則,可供軟件設(shè)計和編程參考。(1)把計算機(jī)系統(tǒng)的內(nèi)部特性隱蔽起來不讓用戶看到。(2)有完備的輸入出錯檢查和出錯恢復(fù)措施,在程序執(zhí)行過程中盡量排除由于用戶的原因而造成程序出錯的可能性。(3)如果用戶的請求有了結(jié)果,則應(yīng)隨時通知用戶。(4)充分利用聯(lián)機(jī)幫助手段,對于不熟練的用戶,提供對話式服務(wù),對于熟練的用戶,提供較高級的系統(tǒng)服務(wù),改善輸入/輸出的能力。(5)使輸入格式和操作要求與用戶的技術(shù)水平相適應(yīng)。對于不熟練的用戶,充分利用菜單系統(tǒng)逐步引導(dǎo)用戶操作;對于熟練的用戶,允許繞過菜單,直接使用命令方式進(jìn)行操作。(6)按照輸出設(shè)備的速度設(shè)計信息輸出過程。(7)區(qū)別不同類型的用戶,分別進(jìn)行設(shè)計和編碼。(8)保持始終如一的響應(yīng)時間。(9)在出現(xiàn)錯誤時應(yīng)盡量減少用戶的額外工作。在交互式系統(tǒng)中,這些要求應(yīng)成為軟件需求的一部分,并通過設(shè)計和編碼,在用戶和系統(tǒng)之間建立良好的通信接口。7.5程序編碼優(yōu)化技術(shù)7.5.1程序優(yōu)化更快的執(zhí)行效率會給用戶帶來更好的使用體驗(yàn)。要想讓程序運(yùn)行得更快,可以選擇效率更高的算法、計算能力更強(qiáng)的運(yùn)行平臺。此外,好的編程習(xí)慣也可以進(jìn)一步提高程序的性能。1.討論效率的準(zhǔn)則程序的效率是指程序的執(zhí)行速度及程序所需占用的內(nèi)存的存儲空間。討論程序效率的幾條準(zhǔn)則如下:(1)效率是一個性能要求,應(yīng)當(dāng)在需求分析階段給出。軟件效率以需求為準(zhǔn),不應(yīng)以人力所及為準(zhǔn)。(2)好的設(shè)計可以提高效率。(3)程序的效率與程序的簡單性相關(guān)。一般說來,任何對效率無重要改善,且對程序的簡單性、可讀性和正確性不利的程序設(shè)計方法都是不可取的。2.算法對效率的影響源程序的效率與詳細(xì)設(shè)計階段確定的算法的效率直接相關(guān)。在詳細(xì)設(shè)計轉(zhuǎn)換成源程序代碼后,算法效率反映為程序的執(zhí)行速度和存儲容量的要求。由詳細(xì)設(shè)計到源程序的轉(zhuǎn)換過程中的指導(dǎo)原則如下:(1)在編程序前,盡可能簡化有關(guān)的算術(shù)表達(dá)式和邏輯表達(dá)式。(2)仔細(xì)檢查算法中嵌套的循環(huán),盡可能將某些語句或表達(dá)式移到循環(huán)外面。(3)盡量避免使用多維數(shù)組。(4)盡量避免使用復(fù)雜的鏈表。(5)采用“快速”的算術(shù)運(yùn)算。(6)不要混淆數(shù)據(jù)類型,避免在表達(dá)式中出現(xiàn)類型混雜。(7)盡量采用整數(shù)算術(shù)表達(dá)式和布爾表達(dá)式。(8)選用等效的高效率算法。許多編譯程序具有“優(yōu)化”功能,可以自動生成高效率的目標(biāo)代碼。它可剔除重復(fù)的表達(dá)式計算,采用循環(huán)求值法、快速的算術(shù)運(yùn)算,以及采用一些能夠提高目標(biāo)代碼運(yùn)行效率的算法來提高效率。對于效率至上的應(yīng)用來說,這樣的編譯程序是很有效的。3.影響存儲效率的因素在大中型計算機(jī)系統(tǒng)中,存儲限制不再是主要問題。在這種環(huán)境下,對內(nèi)存采取基于操作系統(tǒng)的分頁功能的虛擬存儲管理,給軟件提供了巨大的邏輯地址空間。這時,存儲效率與操作系統(tǒng)的分頁功能直接相關(guān),并不是要使所占用的存儲空間達(dá)到最少。采用結(jié)構(gòu)化程序設(shè)計,將程序功能合理分塊,使每個模塊或一組密切相關(guān)模塊的程序體積大小與每頁的容量相匹配,可減少頁面調(diào)度,減少內(nèi)外存交換,提高存儲效率。在微型計算機(jī)系統(tǒng)中,存儲容量對軟件設(shè)計和編碼的制約很大。因此要選擇可生成較短目標(biāo)代碼且存儲壓縮性能優(yōu)良的編譯程序,有時需采用匯編程序。通過程序員富有創(chuàng)造性的努力,提高軟件時間與空間效率。提高存儲效率的關(guān)鍵是程序的簡單性。4.影響輸入/輸出的因素輸入/輸出可分為兩種類型:一種是面向人(操作員)的輸入/輸出;一種是面向設(shè)備的輸入/輸出。如果操作員能夠十分方便、簡單地錄入輸入數(shù)據(jù),或者能夠十分直觀、一目了然地了解輸出信息,則可以說面向人的輸入/輸出是高效的。至于面向設(shè)備的輸入/輸出,分析起來比較復(fù)雜。從詳細(xì)設(shè)計和程序編碼的角度來說,可以提出一些提高輸入/輸出效率的指導(dǎo)原則:(1)輸入/輸出的請求應(yīng)當(dāng)最小化。(2)對于所有的輸入/輸出操作,安排適當(dāng)?shù)木彌_區(qū),以減少頻繁的信息交換。(3)對輔助存儲(例如磁盤),選擇盡可能簡單的、可接受的存取方法。(4)對輔助存儲的輸入/輸出,應(yīng)當(dāng)成塊傳送。(5)對終端或打印機(jī)的輸入/輸出,應(yīng)考慮設(shè)備特性,盡可能改善輸入/輸出的質(zhì)量和速度。(6)任何不易理解的,對改善輸入/輸出效果關(guān)系不大的措施都是不可取的。(7)任何不易理解的,所謂“超高效”的輸入/輸出是毫無價值的。(8)好的輸入/輸出程序設(shè)計風(fēng)格對提高輸入/輸出效率會有明顯的效果。7.5.2程序優(yōu)化方法程序優(yōu)化方法有以下幾種。1.選擇合適的數(shù)據(jù)結(jié)構(gòu)選擇一種合適的數(shù)據(jù)結(jié)構(gòu)很重要。數(shù)組與指針語句具有十分密切的關(guān)系,一般來說,指針比較靈活簡潔,而數(shù)組則比較直觀,容易理解。對于大部分的編譯器,使用指針比使用數(shù)組生成的代碼更短,執(zhí)行效率更高。在許多情況下,可以用指針運(yùn)算代替數(shù)組索引,這樣做常常能產(chǎn)生又快又短的代碼。與數(shù)組索引相比,指針一般能使代碼速度更快,占用空間更少。使用多維數(shù)組時差異更明顯。下面的代碼作用是相同的,但是效率不一樣。指針方法的優(yōu)點(diǎn)是,array的地址每次裝入地址p后,在每次循環(huán)中只需對p增量操作。在數(shù)組索引方法中,每次循環(huán)中都必須先計算t的值,再進(jìn)行求數(shù)組下標(biāo)的運(yùn)算。2.對變量的優(yōu)化1)按數(shù)據(jù)類型的長度排序本地變量當(dāng)編譯器分配給本地變量空間時,它們的順序和它們在源代碼中聲明的順序一樣,應(yīng)該把長的變量放在短的變量前面。編譯器要求把長型數(shù)據(jù)類型存放在偶數(shù)地址邊界。在申明一個復(fù)雜的數(shù)據(jù)類型(既有多字節(jié)數(shù)據(jù),又有單字節(jié)數(shù)據(jù))時,應(yīng)該首先存放多字節(jié)數(shù)據(jù),然后再存放單字節(jié)數(shù)據(jù),這樣可以避免內(nèi)存的空洞。如果第一個變量對齊了,則其他變量就會連續(xù)地存放,而且不用填充字節(jié)自然就會對齊。有些編譯器在分配變量時不會自動改變變量順序,有些編譯器不能產(chǎn)生4字節(jié)對齊的棧,所以4字節(jié)可能不對齊。下面這個例子演示了本地變量聲明的重新排序:2)把頻繁使用的指針型參數(shù)拷貝到本地變量避免在函數(shù)中頻繁使用指針型參數(shù)指向的值。因?yàn)榫幾g器不知道指針之間是否存在沖突,所以指針型參數(shù)往往不能被編譯器優(yōu)化。這樣數(shù)據(jù)不能被存放在寄存器中,而且明顯地占用了內(nèi)存帶寬。請在函數(shù)一開始把指針指向的數(shù)據(jù)保存到本地變量。如果需要,則在函數(shù)結(jié)束前拷貝回去。3.結(jié)構(gòu)體成員的布局結(jié)構(gòu)體變量在存儲時需要使其成員雙字或四字對齊。很多編譯器有“使結(jié)構(gòu)體字,雙字或四字對齊”的選項(xiàng),但是,還是需要改善結(jié)構(gòu)體成員的對齊,有些編譯器可能分配給結(jié)構(gòu)體成員空間的順序與它們聲明的不同。但是,有些編譯器并不提供這些功能,或者效果不好。所以,要在付出最少代價的情況下實(shí)現(xiàn)最好的結(jié)構(gòu)體和結(jié)構(gòu)體成員對齊,建議采取下列方法。1)按數(shù)據(jù)類型的長度排序把結(jié)構(gòu)體的成員按照它們的類型長度排序,聲明成員時把長的類型放在短的前面。編譯器要求把長型數(shù)據(jù)類型存放在偶數(shù)地址邊界。在申明一個復(fù)雜的數(shù)據(jù)類型(既有多字節(jié)數(shù)據(jù),又有單字節(jié)數(shù)據(jù))時,應(yīng)該首先存放多字節(jié)數(shù)據(jù),然后再存放單字節(jié)數(shù)據(jù),這樣可以避免內(nèi)存的空洞。2)把結(jié)構(gòu)體填充成最長類型長度的整倍數(shù)這樣,如果結(jié)構(gòu)體的第一個成員對齊了,則所有整個結(jié)構(gòu)體自然也就對齊了。下面的例子演示了如何對結(jié)構(gòu)體成員進(jìn)行重新排序。4.分支結(jié)構(gòu)的優(yōu)化在if結(jié)構(gòu)中,如果要判斷的并列條件較多,則最好將它們拆分成多個if結(jié)構(gòu),然后嵌套在一起,這樣可以避免無謂的判斷。5.減少運(yùn)算的強(qiáng)度計算量越小,程序的效率越高。減少程序的計算量可以從選擇效率更高的運(yùn)算、優(yōu)化計算順序入手,同時還可以采用將可能結(jié)果提前保存起來的“空間”換“時間”的策略來減少運(yùn)算次數(shù)。1)查表對于在程序中頻繁計算的數(shù)據(jù),可以使用查表的方法來得到,即先計算出可能使用到的數(shù)據(jù),將其保存在一個數(shù)據(jù)表中,待以后使用時再查找。2)求余運(yùn)算位操作只需一個指令周期即可完成,而大部分編譯器的“%”運(yùn)算均是調(diào)用子程序來完成,代碼長、執(zhí)行速度慢。通常,只要是求2n的余數(shù),均可使用位操作的方法來代替。3)平方運(yùn)算在有內(nèi)置硬件乘法器的處理器中,乘法運(yùn)算比求平方運(yùn)算快得多,因?yàn)楦↑c(diǎn)數(shù)的求平方是通過調(diào)用子程序來實(shí)現(xiàn)的,在具有硬件乘法器的處理器中,乘法運(yùn)算只需2個時鐘周期就可以完成。即使沒有內(nèi)置硬件乘法器,乘法運(yùn)算的子程序也比平方運(yùn)算的子程序代碼短,執(zhí)行速度更快。4)用移位實(shí)現(xiàn)乘除法運(yùn)算通常如果需要乘以或除以2n,都可以用移位的方法代替。用移位的方法得到的代碼比使用乘除法生成的代碼效率高。實(shí)際上,只要是乘以或除以一個整數(shù),均可以用移位的方法得到結(jié)果。5)避免不必要的整數(shù)除法整數(shù)除法是整數(shù)運(yùn)算中最慢的,所以應(yīng)該盡可能避免。一種可能減少整數(shù)除法的地方是連除,這里除法可以由乘法代替。這個替換的副作用是有可能在算乘積時會溢出,所以只能在一定范圍的除法中使用。6)使用增量和減量操作符在使用到加一和減一操作時盡量使用增量和減量操作符,因?yàn)樵隽坎僮鞣Z句比賦值語句更快,原因在于對大多數(shù)CPU來說,對內(nèi)存字的增、減量操作不必明顯地使用取內(nèi)存和寫內(nèi)存的指令。7)使用復(fù)合賦值表達(dá)式復(fù)合賦值表達(dá)式(如a-=1及a+=1等)都能夠生成高質(zhì)量的程序代碼。8)提取公共的子表達(dá)式在某些情況下,編譯器不能從浮點(diǎn)表達(dá)式中提出公共的子表達(dá)式,因?yàn)檫@意味著相當(dāng)于對表達(dá)式重新排序。需要特別指出的是,編譯器在提取公共子表達(dá)式前不能按照代數(shù)的等價關(guān)系重新安排表達(dá)式。這時,程序員要手動地提出公共的子表達(dá)式。6.循環(huán)優(yōu)化由于循環(huán)需要多次重復(fù)執(zhí)行,往往是程序中運(yùn)行時間最長的部分,因此提高循環(huán)執(zhí)行的效率就可以直接提升程序的效率。要提高循環(huán)執(zhí)行的效率,往往可以從減少循環(huán)次數(shù)和合并類似循環(huán)入手。1)充分分解小的循環(huán)想要充分利用CPU的指令緩存,就要充分分解小的循環(huán)。特別是當(dāng)循環(huán)體本身很小的時候,分解循環(huán)可以提高性能。2)循環(huán)嵌套把相關(guān)循環(huán)放到一個循環(huán)里,也會加快速度。7.函數(shù)優(yōu)化函數(shù)是程序中使用最多的基本單元,因此優(yōu)化函數(shù)的調(diào)用效率也可以提高程序性能。優(yōu)化函數(shù)的調(diào)用效率可以從優(yōu)化函數(shù)的返回值以及函數(shù)的參數(shù)入手。1)不定義不使用的返回值函數(shù)定義并不知道函數(shù)返回值是否被使用,假如返回值從來不會被用到,則應(yīng)該使用void來明確聲明函數(shù)不返回任何值。2)減少函數(shù)調(diào)用參數(shù)使用全局變量比函數(shù)傳遞參數(shù)更加有效率。這樣做去除了函數(shù)調(diào)用參數(shù)入棧和函數(shù)完成后參數(shù)出棧所需要的時間。然而使用全局變量會影響程序的模塊化和重入,故要慎重使用。3)所有函數(shù)都應(yīng)該有原型定義一般來說,所有函數(shù)都應(yīng)該有原型定義。原型定義可以傳達(dá)給編譯器更多的可能用于優(yōu)化的信息。綜上,通過代碼優(yōu)化,可以提高代碼的執(zhí)行效率,從而提升程序的品質(zhì)。因而優(yōu)化代碼是程序員提高自身水平,提高技能的一個很重要的途徑。不同的代碼有不同的分析方法,有不同的優(yōu)化方法,而這全憑程序員的經(jīng)驗(yàn)積累和自身水平。同時,優(yōu)化是一門平衡的藝術(shù),它往往要以犧牲程序的可讀性或者增加代碼長度為代價。7.5.3網(wǎng)絡(luò)優(yōu)化在現(xiàn)有的網(wǎng)絡(luò)狀態(tài)下,使用者經(jīng)常會遇到帶寬擁塞、應(yīng)用性能低下、蠕蟲病毒、DDoS肆虐、惡意入侵等對網(wǎng)絡(luò)使用及資源有負(fù)面影響的問題及困擾,網(wǎng)絡(luò)優(yōu)化功能是針對現(xiàn)有的防火墻、安防及入侵檢測、負(fù)載均衡、頻寬管理、網(wǎng)絡(luò)防毒等設(shè)備及網(wǎng)絡(luò)問題的補(bǔ)充,能夠通過接入硬件及軟件操作的方式進(jìn)行參數(shù)采集、數(shù)據(jù)分析,找出影響網(wǎng)絡(luò)質(zhì)量的原因,通過技術(shù)手段或增加相應(yīng)的硬件設(shè)備使網(wǎng)絡(luò)達(dá)到最佳運(yùn)行狀態(tài)的方法,使網(wǎng)絡(luò)資源獲得最佳效益,同時了解網(wǎng)絡(luò)的增長趨勢并提供更好的解決方案。實(shí)現(xiàn)網(wǎng)絡(luò)應(yīng)用性能加速,安全內(nèi)容管理,安全事件管理,用戶管理,網(wǎng)絡(luò)資源管理與優(yōu)化,桌面系統(tǒng)管理,流量模式監(jiān)控、測量、追蹤、分析和管理,提高在廣域網(wǎng)上應(yīng)用傳輸?shù)男阅艿墓δ苄援a(chǎn)品,主要包括網(wǎng)絡(luò)資源管理器、應(yīng)用性能加速器、網(wǎng)頁性能加速器3大類。應(yīng)針對不同的需求及功能要求進(jìn)行網(wǎng)絡(luò)的優(yōu)化。7.6代碼評審和版本控制7.6.1代碼評審代碼評審是項(xiàng)目開發(fā)過程中的重要環(huán)節(jié),有效的代碼評審,可以在測試前靜態(tài)地發(fā)現(xiàn)缺陷。實(shí)踐證明,缺陷發(fā)現(xiàn)的時機(jī)越早,越利于缺陷的解決和降低解決成本。代碼評審能夠有效地督促編碼規(guī)范的實(shí)施,提高代碼的可讀性和可維護(hù)性。在代碼的評審過程中,項(xiàng)目組成員互相交流,取長補(bǔ)短,促進(jìn)項(xiàng)目組整體技能的提升。總之,項(xiàng)目開發(fā)過程中的代碼評審和其他各項(xiàng)評審工作對提高項(xiàng)目產(chǎn)品質(zhì)量有重要貢獻(xiàn)。代碼評審一般在代碼已具雛形,并且已通過單元測試,未提交進(jìn)行集成測試之前進(jìn)行。評審的粒度要看代碼的規(guī)模,當(dāng)然評審的代碼覆蓋面越大,代碼的質(zhì)量越有保證。對于涉及業(yè)務(wù)流程較復(fù)雜的模塊一定要和熟悉業(yè)務(wù)的人一起完成代碼的評審,對這類模塊應(yīng)給予重點(diǎn)關(guān)注,因?yàn)橥鶚I(yè)務(wù)流程邏輯的錯誤多于語言使用的錯誤。還有一個時機(jī)建議作代碼評審,即在系統(tǒng)第一版發(fā)布后,如果有需求變動需要增加新功能,則記住這時代碼評審的效果可能好于簡單的測試,當(dāng)然兩者都要有才能保證代碼質(zhì)量更高。代碼評審應(yīng)按照一定的流程作業(yè),這樣可以降低評審成本,提高評審效率。代碼評審流程介紹如下:(1)代碼評審發(fā)起。代碼評審發(fā)起要有專人負(fù)責(zé),負(fù)責(zé)人要控制整個評審過程。負(fù)責(zé)人負(fù)責(zé)確定評審范圍、評審人、評審結(jié)果交付日期和組織召開評審會議。負(fù)責(zé)人還要編寫《代碼評審評審點(diǎn)列表》,《代碼評審評審點(diǎn)列表》列舉出代碼評審過程重點(diǎn)檢查的項(xiàng)目供評審人逐一檢查代碼。(2)負(fù)責(zé)人發(fā)起代碼評審。告知評審人代碼的評審范圍,確定被評審代碼的版本號,告知評審人評審結(jié)果的交付時間。負(fù)責(zé)人還應(yīng)該為評審人提供相關(guān)的資料。(3)評審人評審代碼。評審人按照負(fù)責(zé)人告知的評審范圍,認(rèn)真評審代碼,填寫評審報告,在規(guī)定的時間內(nèi)完成評審。填寫評審報告要明確描述問題發(fā)現(xiàn)點(diǎn)的位置,要寫清代碼文件的版本號及問題點(diǎn)的行號。(4)負(fù)責(zé)人將評審結(jié)果轉(zhuǎn)交給代碼編寫人,編寫人認(rèn)真核對評審報告,修正代碼。編寫人要認(rèn)真填寫評審報告,要寫清修正后代碼文件的版本號,修正點(diǎn)的行號。(5)召開評審會議。會上逐一對評審報告認(rèn)真分析,評審人和代碼編寫人要對每一項(xiàng)評審結(jié)果達(dá)成共識。(6)負(fù)責(zé)人編寫評審總結(jié),將評審中總結(jié)出的問題和經(jīng)驗(yàn)通知給項(xiàng)目組成員。7.6.2版本控制在軟件開發(fā)中經(jīng)常出現(xiàn)以下一些與版本控制密切相關(guān)的典型問題。1.軟件代碼的一致性軟件的開發(fā)、維護(hù)和升級,往往是多個人共同協(xié)作的過程。不同人對同一個軟件的不同部分同時做著修改,這種行為有時會出現(xiàn)彼此交叉的情況。由于同一軟件在各自開發(fā)人員的機(jī)器上都有拷貝,因此軟件的全部代碼都暴露在每個開發(fā)人員面前,原則上他有權(quán)限可以不加限制地更改軟件的任何部分。而當(dāng)他們修改的內(nèi)容屬于公共部分,或者需要被其他人員所負(fù)責(zé)的部分調(diào)用時,這種修改就屬于交叉情況。此時,就有可能出現(xiàn)代碼的不一致現(xiàn)象。比如,修改者在改動了某個公共函數(shù)的同時也修改了其調(diào)用接口,若其他人員沒有得知此事,而在各自機(jī)器上仍調(diào)用原來版本的函數(shù),則當(dāng)整合時,就會出現(xiàn)錯誤。另一種更為嚴(yán)重的情況是,修改者決定廢棄原有函數(shù)而另外編寫一個新的函數(shù),但他并未刪除原有函數(shù),這種情況在最后的整合中也可能不會被察覺,如果將這種一致性錯誤的糾正延遲到測試階段,則會增加調(diào)試的難度,從而降低開發(fā)效率。為了始終保證代碼的一致性,一種解決辦法是,要求修改者每次修改后都通過某種方式告知同組其他人員,或者隨時對軟件做整合。但是這樣,一方面會增加開發(fā)人員的負(fù)擔(dān),另一方面也降低了軟件的開發(fā)效率。2.軟件內(nèi)容的冗余問題軟件在各自開發(fā)人員的機(jī)器上都有拷貝,并且同一個開發(fā)人員在不同時期也會在本機(jī)保留當(dāng)時的軟件版本,也就是說,一臺機(jī)器上還可能不止一個版本。這類似于一種信息的冗余。對于不同版本而言,其差別有時可能并不是很大。隨著時間的推移,開發(fā)人員可能對自己機(jī)器上的不同版本之間具體差異的了解變得模糊不清,甚至忘記了當(dāng)時為什么區(qū)分這些版本,這就會給整合帶來麻煩。而且,如果需要同時維護(hù)多個版本,則對某個版本的改動可能需要反映到其余版本的對應(yīng)處,很難保證這一過程不會出差錯。還有一點(diǎn),作為開發(fā)人員,有時即使知道自己機(jī)器上軟件的某個版本可能不會再使用了,他也不會去刪除,但是通常也不會再去維護(hù)或查看它,因此久而久之,這種“僵死之物”會在多臺機(jī)器上“蔓延”。3.軟件過程的“事務(wù)性”對于軟件的某個版本,如果開發(fā)人員想要為其增添新的功能,或改善原有功能,而又擔(dān)心會攪亂原來運(yùn)行良好的軟件,那么一種常用的辦法就是保留現(xiàn)有版本,另復(fù)制一個新的拷貝,并在新的副本上進(jìn)行修改。這類似于一種事務(wù)處理,當(dāng)將一系列操作作為一個事務(wù)時,如果中間某個操作出現(xiàn)偏差,則希望恢復(fù)到執(zhí)行事務(wù)之前的狀況。而當(dāng)完成修改之后,開發(fā)人員該如何處理這兩個副本呢?是在新的副本上繼續(xù)新的開發(fā),將之作為最新版本;還是將新的改動加入原有版本,刪除新的副本?無論怎樣,都可能會出現(xiàn)如下情況:如果軟件運(yùn)行正常,則出現(xiàn)冗余情況;當(dāng)刪除修改前的版本后,又發(fā)現(xiàn)改動中有問題,但已無法恢復(fù)了;若改動無誤,將改動加入原有版本時,也可能出現(xiàn)人為錯誤,導(dǎo)致軟件運(yùn)行出錯;即使沒有人為錯誤,這種做法也會給開發(fā)人員增加額外負(fù)擔(dān),一定程度地降低開發(fā)效率。重復(fù)上述過程則會出現(xiàn)多個類似的副本,此時,如何對待這些不同版本,將是開發(fā)人員需要面對的問題。而如果調(diào)試的過程中,發(fā)現(xiàn)確實(shí)有必要恢復(fù)到上一個版本,甚至上上個版本……,此時就不得不保留所有版本了。4.軟件開發(fā)的“并發(fā)性”由于是多人共同開發(fā)一個軟件,其間出現(xiàn)多人修改軟件的同一部分,尤其是同時修改,有時是不可避免的。對于前者,具有良好編程習(xí)慣的人員的一種通常做法是,對他人的源程序進(jìn)行修改時添加必要的注釋,寫明修改人、修改原因、修改日期等。但實(shí)際情況是,當(dāng)修改內(nèi)容很零散或修改過程很復(fù)雜時,注釋很難寫,或者代碼被注釋分割得支離破碎影響正常閱讀,或者注釋無法詳細(xì)說明實(shí)際情況。而且,這種做法也增加了開發(fā)人員的負(fù)擔(dān):他需要在考慮代碼邏輯的同時,兼顧如何寫注釋;而對于注釋和代碼的一致性也是他需要隨時留意的問題,不能疏忽。因此,這種措施在實(shí)際開發(fā)中,并未取得實(shí)質(zhì)效果,是不必要的,事實(shí)上代碼本身(而非注釋)是最能說明問題的,而修改的記錄應(yīng)該置于代碼之外的某處。而且,不論是不是同時修改,都需要考慮一致性問題,需要及時進(jìn)行人工的差異比較和整合以便形成一個統(tǒng)一的新版本。5.軟件代碼的安全性由于代碼完全暴露于所有開發(fā)人員面前,任何人都可以對其增、刪、改。除了會造成不一致問題外,從安全的角度來看,也是存在隱患的,這一點(diǎn)對于一個自主產(chǎn)權(quán)的長期開發(fā)的產(chǎn)品而言更是如此。即使是一般的項(xiàng)目開發(fā),不同的人員其分工不同,允許別人可以不加限制地任意修改自己負(fù)責(zé)模塊的代碼(相當(dāng)于所有人員都具有管理員身份),總是容易產(chǎn)生問題。對于共有模塊更是如此,所有人都可以修改,一旦修改,則波及全體。6.軟件的整合在軟件的整合過程中,一般比較可靠的做法是使用文本比對工具來輔助完成。這種措施有以下缺點(diǎn):(1)可靠性,整合中的人為錯誤會影響軟件的可靠性,有時這種錯誤很難察覺,可能編譯沒有問題,而在測試時卻發(fā)現(xiàn)了問題。這種潛在的錯誤發(fā)現(xiàn)的時間越晚就越難以糾正。(2)效率,對于純手工的整合即使熟練操作的人也是需要時間來完成的,而有些整合只是將兩段代碼拼接在一起,這一過程完全可以借助于某些自動機(jī)制。這可以大大節(jié)省時間,使開發(fā)人員可以專注于后續(xù)的開發(fā)任務(wù)。以上這些問題都需要通過版本控制來加以解決。版本控制(RevisionControl)是一種軟件工程技巧,藉以在開發(fā)的過程中,確保由不同人所編輯的同一檔案都得到更新。版本控制系統(tǒng)用于維護(hù)文件的所有版本,隨著時間的推移,文件逐漸產(chǎn)生這些版本。使用版本控制系統(tǒng),人們可以返回到各個文件以前的修訂版本,還可以比較任意兩個版本以查看它們之間的變化。通過這種方式,版本控制可以保留一個文件修訂的可檢索的準(zhǔn)確歷史日志。更重要的是,版本控制系統(tǒng)有助于多個人(甚至位于完全不同的地理位置)通過Internet或?qū)S镁W(wǎng)絡(luò)將各自的更改合并到同一個源存儲庫,從而協(xié)同開發(fā)項(xiàng)目。版本控制包括兩個方面:保證人人得到的是最新的版本,記錄各個歷史版本。最簡單的版本控制方法是在每一個公布的版本中包括一個修正版本的歷史情況,即已做變更的內(nèi)容、變更日期、變更人的姓名以及變更的原因,并根據(jù)標(biāo)準(zhǔn)約定,標(biāo)記每一次修改。對于一個采用版本控制進(jìn)行軟件開發(fā)的多人開發(fā)團(tuán)隊(duì)而言,其一般的開發(fā)方式是:采用服務(wù)器/客戶端的形式,在上面分別安裝版本控制工具的服務(wù)器和客戶端版本,軟件放在服務(wù)器上為大家所共享,開發(fā)人員在客戶端從服務(wù)器上將軟件的相關(guān)部分下載到本地,進(jìn)行修改,改動結(jié)果最終提交到服務(wù)器上。對于軟件的版本控制而言,其主要特點(diǎn)如下:(1)空間上集中統(tǒng)一管理。由于采用服務(wù)器/客戶端方式,盡管開發(fā)人員可以在自己的本地留有備份,但最終唯一有效的只有服務(wù)器端的那個原始拷貝。這樣做一定程度可以解決一致性問題和冗余問題。(2)時間上全程跟蹤記錄。工具將會自動記錄每個更改細(xì)節(jié),和不同時期的不同版本。這樣做一定程度可以解決冗余問題、事務(wù)性問題和并發(fā)性問題。(3)操作權(quán)限控制。對于不同開發(fā)人員,對軟件的不同部分可以定義不同的訪問權(quán)限。這樣做一定程度可以解決安全性問題。(4)自動或半自動。由于有工具輔助控制,因此可以減輕開發(fā)人員的負(fù)擔(dān),節(jié)省時間,同時降低人為錯誤。像軟件整合這樣的工作,其工作量可以相對減輕。衡量軟件版本控制效果的標(biāo)準(zhǔn)歸根結(jié)底有兩點(diǎn):效率和質(zhì)量。如果版本控制最終使軟件開發(fā)效率得到提高、使軟件質(zhì)量得到提升,那就是成功的,反之則是失敗的。效率的提高比較容易理解,質(zhì)量的提升則體現(xiàn)在軟件的一致性、冗余程度等。需要指出的是,單就版本控制工具本身并不能保證這兩點(diǎn)。對工具不熟悉或錯誤使用,以及開發(fā)人員的不良習(xí)慣等都將導(dǎo)致失敗。有時可能反而降低效率。8.1概述

8.2軟件測試的定義和目的

8.3軟件測試的任務(wù)和目標(biāo)

8.4軟件測試的基本原則

8.5軟件測試的方法

8.6軟件測試的步驟

8.7回歸測試

8.8程序調(diào)試8.1概述8.1.1“BUG”一詞的由來1945年9月9日,GraceHopper正領(lǐng)導(dǎo)一個分小組夜以繼日地工作,研制一臺稱為“MARKII”的計算機(jī),這臺計算機(jī)使用了大量的繼電器,是一臺不純粹的電子計算機(jī)。突然,MARKII死機(jī)了。研究人員試了很多次還是無法啟動,然后就開始用各種方法找問題,看問題究竟出現(xiàn)在哪里,最后定位到板子F第70號繼電器出錯。Hopper觀察這個出錯的繼電器,驚奇地發(fā)現(xiàn)一只飛蛾躺在中間,已經(jīng)被繼電器打死。他小心地用鑷子將蛾子夾出來,用透明膠布貼到“事件記錄本”中,并注明“第一個發(fā)現(xiàn)蟲子的實(shí)例”,然后計算機(jī)又恢復(fù)了正常。從此以后,人們將計算機(jī)中出現(xiàn)的任何錯誤戲稱為“臭蟲”(Bug),而把找尋錯誤的工作稱為“找臭蟲”(Debug)。Hopper當(dāng)時所用的記錄本,連同那只飛蛾,一起被陳列在美國歷史博物館中,如圖8.1所示。這個故事告訴我們,在軟件運(yùn)行之前,要將計算機(jī)系統(tǒng)中存在的問題找出來,否則計算機(jī)系統(tǒng)可能會在某個時刻不能正常工作,造成更大的危害。8.1.2為什么會出現(xiàn)軟件缺陷提到軟件缺陷,人們通常會認(rèn)為軟件缺陷源自于編程錯誤。但有專家對眾多從小到大的項(xiàng)目進(jìn)行研究而得出的結(jié)論往往是一致的,即導(dǎo)致軟件缺陷最大的原因是產(chǎn)品說明書,如圖8.2所示。產(chǎn)品說明書成為造成軟件缺陷的罪魁禍?zhǔn)子胁簧僭?。在許多情況下,說明書沒有寫;其他原因可能是說明書不夠全面、經(jīng)常更改,或者整個開發(fā)小組沒有很好地溝通。軟件缺陷的第二大來源是設(shè)計。這是程序員規(guī)劃軟件的過程,好比是建筑師為建筑物繪制藍(lán)圖。這里產(chǎn)生軟件缺陷的原因與產(chǎn)品說明書是一樣的——隨意、易變、溝通不足。在許多人的印象中,軟件測試主要是找程序代碼中的錯誤,這是一個認(rèn)識的誤區(qū)。如果從軟件開發(fā)各個階段能夠發(fā)現(xiàn)軟件缺陷數(shù)目看,比較理想的情況也主要集中在需求分析、系統(tǒng)設(shè)計、編程階段(包括單元測試)等幾個階段中,而在系統(tǒng)測試階段,能夠發(fā)現(xiàn)的缺陷數(shù)目就比較少,這樣會大大降低企業(yè)成本。編程排在第3位。程序員對編碼錯誤太熟悉了。通常,代碼錯誤可以歸咎于軟件的復(fù)雜性、文檔不足、進(jìn)度壓力或者普通的低級錯誤。要注意的是,許多看上去是編程錯誤的軟件缺陷實(shí)際上是由產(chǎn)品說明書和設(shè)計方案造成的。經(jīng)常聽到程序員說:“這是按要求做的。如果有人早告訴我,我就不會這樣編寫程序了?!笔O碌脑蚩蓺w為一類。某些缺陷產(chǎn)生的原因是把誤解當(dāng)成缺陷。還有可能缺陷多處反復(fù)出現(xiàn),實(shí)際上是由一個原因引起的。一些缺陷可以歸咎于測試錯誤。不過,此類軟件缺陷只占極小的比例,不必?fù)?dān)心。8.1.3軟件缺陷定義按照一般的定義,只要符合下列5個規(guī)則中的任何一條,就叫做軟件缺陷。(1)軟件未實(shí)現(xiàn)產(chǎn)品說明書要求的功能。(2)軟件實(shí)現(xiàn)了產(chǎn)品說明書未提到的功能。(3)軟件出現(xiàn)了產(chǎn)品說明書指明不應(yīng)該出現(xiàn)的錯誤。(4)軟件未實(shí)現(xiàn)產(chǎn)品說明書雖未明確提及但應(yīng)該實(shí)現(xiàn)的目標(biāo)。(5)軟件難以理解、不易使用、運(yùn)行緩慢或者從測試員的角度看,最終用戶會認(rèn)為不好。8.1.4軟件缺陷的修復(fù)費(fèi)用軟件不僅僅是表面上的那些東西,通常要靠有計劃、有條理的開發(fā)過程來實(shí)現(xiàn)。從開始到計劃、編程、測試,再到公開使用的過程中,都有可能發(fā)現(xiàn)缺陷。圖8.3顯示了修復(fù)軟件缺陷的費(fèi)用是如何隨著時間的推移而增加的。費(fèi)用指數(shù)級地增長,也就是說,隨著時間的推移,費(fèi)用以十倍增長。在我們的例子中,當(dāng)早期編寫產(chǎn)品說明書時發(fā)現(xiàn)并修復(fù)缺陷,費(fèi)用只要1美元甚至更少。同樣的缺陷如果直到軟件編寫完成開始測試時才發(fā)現(xiàn),則費(fèi)用可能要10~100美元。如果是客戶發(fā)現(xiàn)的,則費(fèi)用可能達(dá)到數(shù)千甚至數(shù)百萬美元。8.1.5對測試人員的技術(shù)要求及測試人員的配備情況1.對測試人員的技術(shù)要求軟件測試是軟件開發(fā)的重要環(huán)節(jié),貫穿著整個軟件開發(fā)周期。軟件測試是一項(xiàng)非常嚴(yán)謹(jǐn)、復(fù)雜、艱苦和具有挑戰(zhàn)性的工作,隨著軟件技術(shù)的發(fā)展,進(jìn)行專業(yè)、高效率軟件測試的要求越來越迫切,對軟件測試人員所具備的知識結(jié)構(gòu)和基本素質(zhì)要求也越來越高。1)軟件測試人員必須具備的知識結(jié)構(gòu)(1)熟悉軟件工程的知識。(2)具有良好的計算機(jī)編程基礎(chǔ),并且了解軟件設(shè)計的過程及設(shè)計內(nèi)容。(3)精通軟件測試?yán)碚摷皽y試技術(shù),熟悉軟件測試每個階段的文檔編寫技巧,掌握測試用例的設(shè)計和編寫方法,掌握軟件測試的策略和各種測試方法,掌握測試過程中每個階段的測試技術(shù)。(4)會使用軟件測試工具。掌握或能快速掌握主流專業(yè)化測試工具的使用方法。2)軟件測試人員的素質(zhì)要求軟件測試人員應(yīng)具備以下素質(zhì)要求:(1)交流和溝通能力。(2)創(chuàng)新精神和洞察力。(3)良好的技術(shù)能力。(4)追求完美并且不斷努力。(5)自信心與幽默感。(6)團(tuán)隊(duì)合作精神。2.測試人員的配備情況一般情況下,軟件測試人員的配備如表8.1所示。3.軟件測試在軟件開發(fā)中的地位軟件測試在軟件開發(fā)中的地位是非常重要的,微軟公司經(jīng)過幾十年的軟件開發(fā)經(jīng)驗(yàn)得到一個結(jié)論:為那些出現(xiàn)問題的產(chǎn)品去修一個補(bǔ)丁程序所花費(fèi)的費(fèi)用,比在軟件上市之前多雇用幾個測試人員所花的費(fèi)用要多得多。8.2軟件測試的定義和目的8.2.1軟件測試的定義國家標(biāo)準(zhǔn)GB/T11457—2006《軟件工程術(shù)語》定義了“軟件測試(Testing)”:軟件測試是指“由人工或自動方法來執(zhí)行或評價系統(tǒng)或系統(tǒng)部件的過程,以驗(yàn)證它是否滿足規(guī)定的需求;或識別出期望的結(jié)果和實(shí)際結(jié)果之間有無差別”。與之相關(guān),所謂排錯、調(diào)試(Debugging),是指“查找、分析和糾正錯誤的過程”。8.2.2軟件測試的目的軟件測試的目的如下:(1)驗(yàn)證軟件是否滿足軟件開發(fā)合同或項(xiàng)目開發(fā)計劃、系統(tǒng)/子系統(tǒng)設(shè)計文檔、軟件需求規(guī)格說明、軟件設(shè)計說明、軟件產(chǎn)品說明等規(guī)定的軟件質(zhì)量要求。(2)通過測試,發(fā)現(xiàn)軟件缺陷。(3)為軟件產(chǎn)品的質(zhì)量測量和評價提供依據(jù)。8.3軟件測試的任務(wù)和目標(biāo)8.3.1軟件測試的任務(wù)測試階段的基本任務(wù)應(yīng)該是根據(jù)軟件開發(fā)各階段的文檔資料和程序的內(nèi)部結(jié)構(gòu),精心設(shè)計一組“高產(chǎn)”的測試用例,利用這些測試用例執(zhí)行程序,找出軟件潛在的缺陷。主觀上由于開發(fā)人員思維的局限性,客觀上由于目前開發(fā)的軟件系統(tǒng)都具有相當(dāng)?shù)膹?fù)雜性,因此,決定了在開發(fā)過程中出現(xiàn)軟件錯誤是不可避免的。若能及早排除開發(fā)中的錯誤,就可以排除給后期工作帶來的麻煩,也就避免了付出高昂的代價,從而大大地提高了系統(tǒng)開發(fā)過程的效率。因此,軟件測試在整個軟件開發(fā)生命周期各個環(huán)節(jié)中都是不可缺少的。8.3.2軟件測試的目標(biāo)軟件缺陷的產(chǎn)生主要是由軟件產(chǎn)品的特點(diǎn)和開發(fā)過程決定的,如軟件的需求經(jīng)常不夠明確,而且需求變化頻繁,開發(fā)人員不太了解軟件需求,不清楚應(yīng)該“做什么”,常常做出不符合需求的事情,產(chǎn)生的問題最多。同時,軟件競爭非常厲害,技術(shù)日新月異,使用新的技術(shù),也容易產(chǎn)生問題。而且對于很多軟件企業(yè),“爭取時間上取勝”常常是其主要市場競爭策略之一,實(shí)現(xiàn)新功能、使用新技術(shù),被認(rèn)為比質(zhì)量更為重要,導(dǎo)致日程安排很緊,需求分析、設(shè)計等投入的時間和精力遠(yuǎn)遠(yuǎn)不夠,也是產(chǎn)生軟件錯誤的主要原因之一。軟件錯誤的引入可歸為以下這7項(xiàng)主要原因:(1)項(xiàng)目期限的壓力。(2)產(chǎn)品的復(fù)雜度。(3)溝通不良。(4)開發(fā)人員的疲勞、壓力或受到干擾。(5)缺乏足夠的知識、技能和經(jīng)驗(yàn)。(6)不了解客戶的需求。(7)缺乏動力。這些原因,會引起下列主要領(lǐng)域的主要錯誤(缺陷):(1)需求規(guī)格說明書(RequirementSpecificationorFunctionalSpecification)包含錯誤的需求,或漏掉一些需求,或沒有準(zhǔn)確表達(dá)客戶所需要的內(nèi)容。(2)需求規(guī)格說明書中有些功能是不可能或無法實(shí)現(xiàn)的。(3)系統(tǒng)設(shè)計(SystemDesign)中的不合理性。(4)程序設(shè)計中的錯誤、程序代碼中的問題,包括錯誤的算法、復(fù)雜的邏輯等。若能及早排除軟件開發(fā)中的錯誤,有效地減少后期工作的麻煩,就可以盡可能地避免付出高昂的代價,從而大大提高系統(tǒng)開發(fā)過程的效率。軟件測試的目標(biāo)就是為了更快、更早地將軟件產(chǎn)品或軟件系統(tǒng)中所存在的各種問題找出來,并促進(jìn)開發(fā)各類人員盡快地解決問題,最終及時地向客戶提供一個高質(zhì)量的軟件產(chǎn)品,使軟件系統(tǒng)更好地滿足用戶的需求,同時滿足軟件組織自身的要求:(1)用戶的需求包括:①能正常使用全部所需要的功能。②功能強(qiáng)大,而且界面美觀、易用、好用。③內(nèi)容健康,有益于生活和工作。④用戶的數(shù)據(jù)安全、受保護(hù)和兼容。⑤及時得到新的產(chǎn)品或得到更完美的軟件服務(wù)。⑥軟件可靠性很高,使用軟件服務(wù)沒有時間障礙。(2)軟件企業(yè)的需求包括:①軟件質(zhì)量是市場競爭的需要,質(zhì)量好的軟件是留住客戶的最關(guān)鍵的手段之一,軟件企業(yè)也必須依靠質(zhì)量,才能立于不敗之地。②高質(zhì)量的軟件可以大大降低“質(zhì)量問題產(chǎn)生的成本”,增加公司的盈利。③軟件已是國際化的市場,質(zhì)量是進(jìn)入國際市場的一個關(guān)鍵門檻。④容易維護(hù)、移植和擴(kuò)充,以擴(kuò)大市場或適應(yīng)環(huán)境的變化。這些要求的滿足,最終體現(xiàn)在軟件產(chǎn)品的質(zhì)量上,主要表現(xiàn)在:(1)功能性。(2)可用性。(3)可靠性。(4)性能。(5)容量。(6)可測量性。(7)可維護(hù)性。(8)兼容性。(9)可擴(kuò)展性。8.3.3測試類別根據(jù)GB/T8566的要求,軟件測試可分為以下幾個類別:(1)單元測試;(2)集成測試;(3)配置項(xiàng)測試(也稱軟件合格性測試或確認(rèn)測試);(4)系統(tǒng)測試;(5)驗(yàn)收測試??筛鶕?jù)軟件的規(guī)模、類型、完整性級別選擇執(zhí)行測試類別。由于回歸測試可出現(xiàn)在上述每個測試類別中,并貫穿于整個軟件生存周期,故單獨(dú)分類進(jìn)行描述。8.4軟件測試的基本原則在設(shè)計有效的測試用例進(jìn)行測試之前,測試人員必須理解軟件測試的基本原則,以此作為測試工作的指導(dǎo)。軟件測試有以下基本原則:(1)所有的測試都應(yīng)可追溯到客戶需求。軟件測試的目標(biāo)是發(fā)現(xiàn)錯誤,而最嚴(yán)重的錯誤是那些導(dǎo)致程序無法滿足需求的錯誤。(2)應(yīng)該把盡早地和不斷地進(jìn)行軟件測試作為開發(fā)人員的座右銘。只有將軟件測試貫穿到軟件開發(fā)的各個階段中,堅持進(jìn)行軟件開發(fā)各個階段的技術(shù)評審,才能在開發(fā)過程中盡早發(fā)現(xiàn)和預(yù)防錯誤,把出現(xiàn)的錯誤克服在早期,杜絕更大的隱患。(3)在真正的測試開始之前必須盡可能地完善測試計劃,測試計劃原則上應(yīng)該在需求模型剛完成就開始,詳細(xì)的測試用例定義可以在設(shè)計模型被確定后立即開始。(4)?Pareto(柏拉圖)原則亦可用于軟件測試。Pareto原則通常也稱為80:20原則,按照這一原則軟件錯誤中的80%起源于20%的程序模塊,但問題在于如何去分離這有問題的20%的模塊。(5)從心理學(xué)的角度講,創(chuàng)建系統(tǒng)的開發(fā)人員并不是進(jìn)行軟件測試的最佳人選。程序員應(yīng)避免測試自己開發(fā)的程序,注意不要與程序調(diào)試的概念混淆。(6)測試應(yīng)該由小到大。最初的測試通常將焦點(diǎn)放在單個的程序模塊上,進(jìn)一步測試的焦點(diǎn)則轉(zhuǎn)向在集成的模塊簇中去尋找錯誤,最后在整個的系統(tǒng)中尋找錯誤。(7)完全的測試是不可能的,即使是最簡單的程序也不能做到完全的測試,這是因?yàn)椋孩佥斎肓刻?;②輸出結(jié)果太多;③實(shí)現(xiàn)的途徑或路徑太多;④判定軟件缺陷并沒有一個客觀的標(biāo)準(zhǔn)。但是,充分覆蓋程序邏輯并確保能夠使用程序設(shè)計中的所有條件倒是可能的。(8)嚴(yán)格執(zhí)行測試計劃,對每一個測試結(jié)果做全面的檢查,要仔細(xì)地分析檢查以暴露錯誤。(9)妥善保存測試計劃、測試用例、測試分析報告,并作為軟件文檔的組成部分,同時也可以為維護(hù)提供方便。8.5軟件測試的方法軟件測試的方法如圖8.4所示。8.5.1靜態(tài)測試方法1.代碼審查代碼審查的測試內(nèi)容:檢查代碼和設(shè)計的一致性;檢查代碼執(zhí)行標(biāo)準(zhǔn)的情況;檢查代碼邏輯表達(dá)的正確性;檢查代碼結(jié)構(gòu)的合理性;檢查代碼的可讀性。代碼審查的組織:由4人以上組成,分別為組長、資深程序員、程序編寫者與專職測試人員。組長不能是被測試程序的編寫者,組長負(fù)責(zé)分配資料、安排計劃、主持開會、記錄并保存被發(fā)現(xiàn)的差錯。代碼審查的過程如下:(1)準(zhǔn)備階段:組長分發(fā)有關(guān)材料,被測程序的設(shè)計和編碼人員向?qū)彶榻M詳細(xì)說明有關(guān)材料,并回答審查組成員所提出的有關(guān)問題。(2)程序閱讀:審查組人員仔細(xì)閱讀代碼和相關(guān)材料,對照代碼審查單,記錄問題及明顯缺陷。(3)會議審查:組長主持會議,程序員逐句闡明程序的邏輯,其他人員提出問題,利用代碼審查單進(jìn)行分析討論,對討論的各個問題形成結(jié)論性意見。(4)形成報告:會后將發(fā)現(xiàn)的差錯形成代碼審查問題表,并交給程序開發(fā)人員。對發(fā)現(xiàn)差錯較多或發(fā)現(xiàn)重大差錯的,在改正差錯之后再次進(jìn)行會議審查。這種靜態(tài)測試方法是一種多人一起進(jìn)行的測試活動,要求每個人盡量多提出問題,同時講述程序者也會突然發(fā)現(xiàn)一些問題,這時要放慢進(jìn)度,把問題分析出來。2.代碼走查1)代碼走查的測試內(nèi)容代碼走查的測試內(nèi)容與代碼審查的基本一樣。2)代碼走查的組織一般由4人以上組成,分別為組長、秘書、資深程序員與專職測試人員。被測試程序的編寫者可以作為走查組成員。組長負(fù)責(zé)分配資料、安排計劃、主持開會,秘書記錄被發(fā)現(xiàn)的差錯。3)代碼走查的過程代碼走查的過程如下:(1)準(zhǔn)備階段:組長分發(fā)有關(guān)材料,走查組詳細(xì)閱讀材料和認(rèn)真研究程序。(2)生成實(shí)例:走查小組人員提出一些有代表性的測試實(shí)例。(3)會議走查:組長主持會議,其他人員對測試實(shí)例用頭腦來執(zhí)行程序,也就是測試實(shí)例沿程序邏輯走一遍,并由測試人員講述程序執(zhí)行過程,在紙上或黑板上監(jiān)視程序狀態(tài),秘書記錄下發(fā)現(xiàn)的問題。(4)形成報告:會后將發(fā)現(xiàn)的差錯形成報告,并交給程序開發(fā)人員。對發(fā)現(xiàn)差錯較多或發(fā)現(xiàn)重大差錯的,在改正差錯之后再次進(jìn)行會議走查。這種靜態(tài)測試方法是一種多人一起進(jìn)行的測試活動,要求每個人盡量多提供測試實(shí)例,這些測試實(shí)例是作為懷疑程序邏輯與計算差錯的啟發(fā)點(diǎn),在隨著測試實(shí)例游歷程序邏輯時,在懷疑程序的過程中發(fā)現(xiàn)差錯。這種方法不如代碼審查檢查的范圍廣,差錯覆蓋全。3.靜態(tài)分析靜態(tài)分析一般包括控制流分析、數(shù)據(jù)流分析、接口分析和表達(dá)式分析。此外,靜態(tài)分析還可以完成下述工作:(1)提供間接涉及程序缺陷的信息。(2)進(jìn)行語法、語義分析,提出語義或結(jié)構(gòu)要點(diǎn),供進(jìn)一步分析。(3)進(jìn)行合同無法號求值。(4)為動態(tài)測試選擇測試用例進(jìn)行預(yù)處理。靜態(tài)分析常需要使用軟件工具進(jìn)行。靜態(tài)分析是在程序編譯通過之后,其他靜態(tài)測試之前進(jìn)行的。1)控制流分析控制流分析是使用控制流程圖系統(tǒng)地檢查被測程序的控制結(jié)構(gòu)的工作。控制流按照結(jié)構(gòu)化程序規(guī)則和程序結(jié)構(gòu)的基本要求進(jìn)行程序結(jié)構(gòu)檢查。這些要求是被測程序不應(yīng)包含:(1)轉(zhuǎn)向并不存在的語句標(biāo)號;(2)沒有使用的語句標(biāo)號;(3)沒有使用的子程序定義;(4)調(diào)用并不存在的子程序;(5)從程序入口進(jìn)入后無法達(dá)到的語句;(6)不能達(dá)到停止語句的語句。控制流程圖是一種簡化的程序流程圖,控制流程圖由“節(jié)點(diǎn)”和“弧”兩種圖形符號構(gòu)成。2)數(shù)據(jù)流分析數(shù)據(jù)流分析是用控制流程圖來分析數(shù)據(jù)發(fā)生的異常情況,這些異常包括被初始化、被賦值或被引用過程中行為序列的異常。數(shù)據(jù)流分析也作為數(shù)據(jù)流測試的預(yù)處理過程。數(shù)據(jù)流分析首先建立控制流程圖,然后在控制流程圖中標(biāo)注某個數(shù)據(jù)對象的操作序列,遍歷控制流程圖,形成這個數(shù)據(jù)對象的數(shù)據(jù)流模型,并給出這個數(shù)據(jù)對象的初始狀態(tài),利用數(shù)據(jù)流異常狀態(tài)圖分析數(shù)據(jù)對象可能的異常。數(shù)據(jù)流分析可以查出引用未定義變量、對以前未使用的變量再次賦值等程序差錯或異常情況。3)接口分析接口分析主要用于程序靜態(tài)分析和設(shè)計分析。接口一致性的設(shè)計分析涉及模塊之間接口的一致性以及模塊與外部數(shù)據(jù)庫之間的一致性。程序的接口分析涉及子程序以及函數(shù)之間的接口一致性,包括檢查形參與實(shí)參的類型、數(shù)量、維數(shù)、順序以及使用的一致性。4)表達(dá)式分析表達(dá)式錯誤主要有以下幾種(但不僅限于):括號使用不正確,數(shù)據(jù)組引用錯誤,作為除數(shù)的變量可能為零,作為開平方的變量可能為負(fù),作為正切值的變量可能為π/2以及浮點(diǎn)數(shù)變量比較時產(chǎn)生的錯誤。8.5.2動態(tài)測試方法1.概述動態(tài)測試建立在程序的執(zhí)行過程中,根據(jù)對被測對象內(nèi)部情況的了解與否,分為黑盒測試和白盒測試。黑盒測試又稱功能測試、數(shù)據(jù)驅(qū)動測試或基于規(guī)格說明的測試,這種測試不必了解被測對象的內(nèi)部情況,而依靠需求規(guī)格說明中的功能來設(shè)計測試用例。白盒測試又稱結(jié)構(gòu)測試、邏輯測試或基于程序的測試,這種測試應(yīng)了解程序的內(nèi)部構(gòu)造,并且根據(jù)內(nèi)部構(gòu)造設(shè)計測試用例。在單元測試時一般采用白盒測試,在配置項(xiàng)測試或系統(tǒng)測試時一般采用黑盒測試。2.黑盒測試方法黑盒測試法把程序看作一個黑盒子,完全不考慮程序的內(nèi)部結(jié)構(gòu)和處理過程。也就是說,黑盒測試是在程序接口進(jìn)行的測試,它只檢查程序功能是否能按照規(guī)格說明書的規(guī)定正常使用,程序是否能適當(dāng)?shù)亟邮蛰斎霐?shù)據(jù)并產(chǎn)生正確的輸出信息,程序運(yùn)行過程中能否保持外部信息的完整性,黑盒測試又被稱為功能測試。1)功能分解功能分解是將需求規(guī)格說明中每一個功能加以分解,確保各個功能被全面地測試,功能分解是一種較常用的方法。功能分解的步驟如下:(1)使用程序設(shè)計中的功能抽象方法把程序分解為功能單元。(2)使用數(shù)據(jù)抽象方法產(chǎn)生測試每個功能單元的數(shù)據(jù)。功能抽象中程序被看成一種抽象的功能層次,每個層次可標(biāo)識被測試的功能,層次結(jié)構(gòu)中的某一功能由其下一層功能定義。按照功能層次進(jìn)行分解,可以得到眾多的最低層次的子功能,以這些子功能為對象,進(jìn)行測試用例設(shè)計。數(shù)據(jù)抽象中,數(shù)據(jù)結(jié)構(gòu)可以由抽象數(shù)據(jù)類型的層次圖來描述,每個抽象數(shù)據(jù)類型有其取值集合。程序的每一個輸入和輸出量的取值集合用數(shù)據(jù)抽象來描述。2)等價類劃分等價類劃分是在分析需求規(guī)格說明的基礎(chǔ)上,把程序的輸入域劃分成若干部分,然后在每部分中選取代表性數(shù)據(jù)形成測試用例。等價類劃分的步驟如下:(1)劃分有效等價類:對規(guī)格說明是有意義、合理的輸入數(shù)據(jù)所構(gòu)成的集合。(2)劃分無效等價類:對規(guī)格說明是無意義、不合理的輸入數(shù)據(jù)所構(gòu)成的集合。(3)為每一個等價類定義一個唯一的編號。(4)為每一個等價類設(shè)計一組測試用例,確保覆蓋相應(yīng)的等價類。3)邊界值分析邊界值分析是針對邊界值進(jìn)行測試的。使用等于、小于或大于邊界值的數(shù)據(jù)對程序進(jìn)行測試的方法就是邊界值分析方法。邊界值分析的步驟如下:(1)通過分析規(guī)格說明,找出所有可能的邊界條件。(2)對每一個邊界條件,給出滿足邊界值的輸入數(shù)據(jù)。(3)設(shè)計相應(yīng)的測試用例。(4)對滿足邊界值的輸入可以發(fā)現(xiàn)計算差錯,對不滿足的輸入可以發(fā)現(xiàn)域差錯。該方法會為其他測試方法補(bǔ)充一些測試用例,絕大多數(shù)測試都會用到本方法。4)判定表判定表由4部分組成:條件樁、條件條目、動作樁和動作條目。任何一個條件組合的取值及其相應(yīng)要執(zhí)行的操作構(gòu)成規(guī)則,條目中的每一列是一條規(guī)則。條件引用輸入的等價類,動作引用被測試軟件的主要功能處理部分,規(guī)則就是測試用例。建立并優(yōu)化判定表,把判定表中每一列表示的情況寫成測試用例。該方法的使用有以下要求:(1)規(guī)格說明以判定表形式給出,或是很容易轉(zhuǎn)換成判定表。(2)條件的排列順序不會影響執(zhí)行哪些操作。(3)規(guī)則的排列順序不會影響執(zhí)行哪些操作。(4)每當(dāng)某一規(guī)則的條件已經(jīng)滿足,并確定要執(zhí)行的操作后,不必檢驗(yàn)別的規(guī)則。(5)如果某一規(guī)則的條件得到滿足,將執(zhí)行多個操作,這些操作的執(zhí)行與順序無關(guān)。5)因果圖因果圖方法是通過畫因果圖,把用自然語言描述的功能說明轉(zhuǎn)換為判定表,然后為判定表的每一列設(shè)計一個測試用例。因果圖的步驟如下:(1)分析程序規(guī)格說明,引出原因(輸入條件)和結(jié)果(輸出結(jié)果),并給每個原因和結(jié)果賦予一個標(biāo)識符。(2)分析程序規(guī)格說明中語義的內(nèi)容,并將其表示成連接各個原因和各個結(jié)果的“因果圖”。(3)在因果圖上標(biāo)明約束條件。(4)通過跟蹤因果圖中的狀態(tài)條件,把因果圖轉(zhuǎn)換成有限項(xiàng)的判定表。(5)把判定表中每一列表示的情況生成測試用例。如果需求規(guī)格說明中含有輸入條件的組合,則宜采用本方法。有些軟件的因果圖可能非常龐大,以至于根據(jù)因果圖得到的測試用例數(shù)目非常大,此時不宜使用本方法。6)隨機(jī)測試隨機(jī)測試指測試輸入數(shù)據(jù)是在所有可能輸入值中隨機(jī)選取的。測試人員只需規(guī)定輸入變量的取值區(qū)間,在需要時提供必要的變換機(jī)制,使產(chǎn)生的隨機(jī)數(shù)據(jù)服從預(yù)期的概率分布。該方法獲得預(yù)期輸出比較困難,多用于可靠性測試和系統(tǒng)強(qiáng)度測試。7)猜錯法猜錯法是有經(jīng)驗(yàn)的測試人員,通過列出可能有的差錯和易錯情況表,寫出測試用例的方法。8)正交實(shí)驗(yàn)法正交實(shí)驗(yàn)法是從大量的實(shí)驗(yàn)點(diǎn)中挑出適量的、有代表性的點(diǎn),應(yīng)用正交表,合理地安排實(shí)驗(yàn)的一種科學(xué)的實(shí)驗(yàn)設(shè)計方法。利用正交實(shí)驗(yàn)法來設(shè)計測試用例時,首先要根據(jù)被測軟件的規(guī)格說明書找出影響功能實(shí)現(xiàn)的操作對象和外部因素,把它們當(dāng)作因子,而把各個因子的取值當(dāng)作狀態(tài),生成二元的因素分析表。然后,利用正交表進(jìn)行各因子的狀態(tài)的組合,構(gòu)造有效的測試輸入數(shù)據(jù)集,并由此建立因果圖。這樣得出的測試用例的數(shù)目將大大減少。3.白盒測試方法白盒測試法與黑盒測試法相反,它的前提是可以把程序看成裝在一個透明的白盒子里,測試者完全知道程序的結(jié)構(gòu)和處理算法。這種方法按照程序內(nèi)部的邏輯測試程序,檢測程序中的主要執(zhí)行通路是否都能按預(yù)定要求正確工作,又稱為結(jié)構(gòu)測試。1)控制流測試控制流測試依據(jù)控制流程圖產(chǎn)生測試用例,通過對不同控制結(jié)構(gòu)成分的測試驗(yàn)證程序的控制結(jié)構(gòu)。所謂驗(yàn)證某種控制結(jié)構(gòu)即指使這種控制結(jié)構(gòu)在程序運(yùn)行中得到執(zhí)行,也稱這一過程為覆蓋。以下介紹幾種覆蓋:(1)語句覆蓋:要求設(shè)計適當(dāng)數(shù)量的測試用例,運(yùn)行被測程序,使得程序中每一條語句至少被執(zhí)行一次,語句覆蓋在測試中主要發(fā)現(xiàn)出錯語句。(2)分支覆蓋:要求設(shè)計適當(dāng)數(shù)量的測試用例,運(yùn)行被測程序,使得程序中每個真值分支和假值分支都至少執(zhí)行一次,分支覆蓋也稱判定覆蓋。(3)條件覆蓋:要求設(shè)計適當(dāng)數(shù)量的測試用例,運(yùn)行被測程序,使得每個判斷中的每個條件的可能取值都至少滿足一次。(4)條件組合覆蓋:要求設(shè)計適當(dāng)數(shù)量的測試用例,運(yùn)行被測程序,使得每個判斷中條件的各種組合至少出現(xiàn)一次,這種方法包含了“分支覆蓋”的各種要求。(5)路徑覆蓋:要求設(shè)計適當(dāng)數(shù)量的測試用例,運(yùn)行被測程序,使得程序沿所有可能的路徑執(zhí)行,較大程序的路徑可能很多,所以在設(shè)計測試用例時,要簡化循環(huán)次數(shù)。以上各種覆蓋的控制流測試步驟如下:(1)將程序流程圖轉(zhuǎn)換成控制流圖;(2)經(jīng)過語法分析求得路徑表達(dá)式;(3)生成路徑樹;(4)進(jìn)行路徑編碼;(5)經(jīng)過譯碼得到執(zhí)行的路徑;(6)通過路徑枚舉產(chǎn)生特定路徑的測試用例。2)數(shù)據(jù)流測試數(shù)據(jù)流測試是用控制流程圖對變量的定義和引用進(jìn)行分析,查找出未定義變量或定義了而未使用的變量,這些變量可能是拼錯的變量、變量混淆或丟失了語句。數(shù)據(jù)流測試一般使用工具進(jìn)行。數(shù)據(jù)流測試通過一定的覆蓋準(zhǔn)則,檢查程序中每個數(shù)據(jù)對象的每次定義、使用和消除的情況。數(shù)據(jù)流測試步驟如下:(1)將程序流程圖轉(zhuǎn)換成控制流圖;(2)在每個鏈路上標(biāo)注對有關(guān)變量的數(shù)據(jù)操作的操作符號或符號序列;(3)選定數(shù)據(jù)流測試策略;(4)根據(jù)測試策略得到測試路徑;(5)根據(jù)路徑可以獲得測試輸入數(shù)據(jù)和測試用例。動態(tài)數(shù)據(jù)異常檢查在程序運(yùn)行時執(zhí)行,獲得的是對數(shù)據(jù)對象的真實(shí)操作序列,克服了靜態(tài)分析檢查的局限,但動態(tài)方式檢查是沿著與測試輸入有關(guān)的一部分路徑進(jìn)行的,檢查的全面性和程序結(jié)構(gòu)覆蓋有關(guān)。3)程序變異程序變異是一種差錯驅(qū)動測試,是為了查出被測軟件在做過其他測試后還剩余的一些小差錯。本方法一般用工具進(jìn)行。4)程序插裝程序插裝是向被測程序中插入操作以實(shí)現(xiàn)測試目的的方法。程序插裝不應(yīng)該影響被測程序的運(yùn)行過程和功能。有很多的工具有程序插裝功能,由于數(shù)據(jù)記錄量大,因此手工進(jìn)行較為煩瑣。5)域測試域測試是要判別程序?qū)斎肟臻g的劃分是否正確。該方法限制太多,使用不

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論