一、程序編碼
程序編碼是設計的繼續,將軟件設計的結果翻譯成用某種程序設計語言描述的源代碼。
程序編碼涉及到方法、工具和過程。
程序設計風格和程序設計語言的特性會深刻地影響軟件的質量和可維護性。
要求源程序具有良好的結構性和設計風格。
程序設計風格
(1)源程序文檔化
程序內部的文檔包括恰當的標識符、適當的注釋和程序的視覺組織等。
標識符應選取含義鮮明的名字,有一定實際意義,名字不是越長越好,必要時采用縮寫。
注釋作為程序員與讀者之間通信的重要手段決不是可有可無的,分為序言性注釋和功能性注釋。
利用空格、空行和移行,提高程序的可視化程度。
(2)數據說明
設計階段已經確定了數據結構的組織及其復雜性;在編寫程序時,則需要注意數據說明的風格。
為了使程序中數據說明更易于理解和維護,必須注意以下幾點:
數據說明的次序應當規范化
說明語句中變量安排有序化
使用注釋說明復雜數據結構
(3)語句構造
設計階段確定軟件的邏輯結構,編碼階段的任務是構造語句。語句構造力求簡單、直接,不能為片面追求效率而使語句復雜化。
在一行內只寫一條語句 ,?采取適當的移行格式,使程序的邏輯和功能變得更加明確。
程序編寫首先應當考慮清晰性 ? ?不要刻意追求技巧性。
程序要直截了當地說明程序員的用意
盡量采用三種基本控制結構來編寫程序,避免不必要的轉移,盡量少用GOTO語句。
利用括號使表達式的運算次序清晰直觀。
避免大量使用循環嵌套和條件嵌套。
避免采用過于復雜的條件測試,盡量少用“否定”條件的條件語句。
盡可能使用庫函數。
盡可能用通俗易懂的偽碼描述程序流程,然后再翻譯成必須使用的語言。
確保模塊獨立,模塊內信息隱蔽,耦合清晰可見。
(4)輸入和輸出
輸入和輸出信息是與用戶的使用直接相關的。輸入和輸出的方式和格式應當盡可能方便用戶的使用。一定要避免因設計不當給用戶帶來的麻煩。
因此,在軟件需求分析階段和設計階段,就應基本確定輸入和輸出的風格。系統能否被用戶接受,有時就取決于輸入和輸出的風格。
設計和實現考慮原則:
對所有的輸入數據都要進行檢驗,識別錯誤的輸入,以保證每個數據的有效性;
檢查輸入項各種組合的合理性,必要時報告輸入狀態;
輸入的步驟和操作盡可能簡單,保持簡單的輸入格式;
輸入數據時,應允許使用自由格式;
應允許缺省值;
交互式輸入時,使用提示符明確提示交互輸入的請求;
最好使用輸入結束標志,不要由用戶指定輸入數據數目;
給所有的輸出加注解,并設計輸出報表格式。
(5)程序效率
程序的效率是指程序的執行速度及程序所需占用的內存存儲空間。
程序編碼是最后提高運行速度和節省存儲的機會,在此階段不能不考慮程序的效率。
討論程序效率的三條原則:
①效率是性能要求,應在需求分析階段確定這方面要求;
②效率是靠好的設計來提高的;
③程序的效率和程序的簡單程度是一致的。
程序設計語言
程序編碼階段的任務是將軟件的詳細設計轉換成用程序設計語言實現的程序代碼,即把用PDL等工具描寫的算法,翻譯成計算機能接受的諸如C++、Java等程序設計語言的程序。 因此,程序設計風格和設計語言的性能對于程序設計的效率和質量有著直接的關系。
(1)程序設計語言的基本成分
①數據部分:程序中構造的數據類型,描述程序中使用的各種類型的數據,如變量、數組、指針等。
②運算部分:程序中允許執行的運算,用以描述程序中所需執行的運算。
是哪控制部分:程序中允許使用的控制結構,用它們構造程序的控制邏輯。
④傳輸部分:傳輸數據的方式,如輸入/輸出語句。
(2)分類
①按抽象級別
低級語言,包括機器語言和匯編語言,與特定計算機硬件相關。
高級語言,不反映特定計算機體系結構,表示方法更接近待解決的問題,包括FORTRAN、C/C++、Java等。
②按應用范圍
通用語言,適用多種應用,包括FORTRAN、C、C++、Java等。
專用語言,為特殊應用而設計,具有特定的語法形式、結構及詞匯,與問題的相應范圍密切相關。例如PROLOG、Lisp等。
③按對用戶的要求
過程性語言,描述計算過程,如 C、FORTRAN等。
非過程性語言,不顯式指定處理細節,如查詢語言、原型語言等。
(3)語言選擇原則
為特定開發項目選擇程序設計語言時,應從技術角度、工程角度、心理學角度評價和比較各種語言的適用程度,考慮現實可能性,作出合理的折衷。
①編譯程序應具有較高的效率② 盡可能應用代碼生成的工具 ③源程序應具有可移植性④工程的規模⑤ 軟件的應用領域⑥用戶的要求 ⑦程序員的知識
二、軟件測試
盡管在分析、設計和實現過程中,使用了許多保證軟件質量的方法,但難免還會犯錯誤。 軟件開發過程必須伴有質量保證活動。 軟件測試是在軟件投入運行前,對分析、設計和編碼的最終復審。
(1)目的
測試是為了發現程序中的錯誤而執行程序的過程;一個成功的測試是發現了至今為止尚未發現的錯誤的測試;一個好的測試方案是極可能發現迄今為止尚未發現的錯誤的測試方案。
以最少的時間和人力,系統地找出軟件中潛在的各種錯誤和缺陷。如果成功地實施了測試,就能發現軟件中的錯誤。
測試不能表明軟件不存在錯誤,只能說明軟件中存在錯誤。測試的附帶收獲是,它能夠證明軟件的功能和性能與需求說明相符。
收集的測試結果數據為軟件可靠性分析提供依據。
(2)準則
①所有的測試都應追溯到用戶要求,并將“盡早地、不斷地進行軟件測試”作為軟件開發者的座右銘。
②應從“小規模”測試開始,逐步進行“大規模”測試。
③遠在測試開始之前就制定出測試計劃并嚴格地執行,排除測試的隨意性。
④窮盡測試是不可能的,應精心地設計測試方案。
⑤為達到最佳測試效果,應由獨立的第三方從事測試工作,限制開發人員檢查自己的程序。
⑥全面檢查每個測試結果,妥善保存測試計劃、測試用例、出錯統計和分析報告,為維護提供方便。
(3)信息流
三類輸入:軟件配置、測試配置、測試工具
輸出測試結果,發生錯誤對軟件進行調試,并修改程序,修改好再次返回測試。
輸入預測結果,根據結果對出錯數據進行可靠性分析
(4)測試與各階段的關系
軟件測試不等于程序測試
所有的測試都應追溯到用戶需求
問題的根源可能在開發前期的各階段 解決、糾正錯誤也必須追溯到前期工作
軟件測試貫穿軟件定義與開發的整個期間 各階段所得的文檔都應成為測試的對象
(5)軟件測試方法
靜態測試方法:人工測試方法,計算機輔助靜態分析
動態測試方法:黑盒測試和白盒測試
黑盒測試
將測試對象看做一個黑盒,測試人員不考慮程序內部的邏輯結構和內部特性,只依據需求規格說明,檢查程序的功能是否符合其規格說明。
黑盒測試又稱功能測試或數據驅動測試。
測試人員充當客戶來使用它。
黑盒測試——等價類劃分
典型的黑盒測試方法,不考慮程序的內部結構,只依據程序的規格說明來設計測試用例。
把所有可能的輸入數據,即程序的輸入域劃分成若干部分,然后從每一部分中選取少數代表性數據做為測試用例。
設計測試用例要經歷劃分等價類(列出等價類表)和選取測試用例兩步。
等價類指某個輸入域的子集,該集合中,各個輸入數據對于揭露程序中的錯誤都是等效的。 測試某等價類的代表值等價于測試該類的其他值。 等價類的劃分有兩種情況:①有效等價類:對于程序規格說明來說,是合理、有意義的輸入數據構成的集合。 ② 無效等價類:對于程序的規格說明來說,是不合理、無意義的輸入數據構成的集合。
確立了等價類之后,建立等價類表,列出所有劃分出的等價類。
按有效等價類的一個測試用例盡可能多地覆蓋尚未被覆蓋的有效等價類和無效等價類的一個測試用例僅覆蓋一個尚未被覆蓋的無效等價類的原則從劃分的等價類中選擇測試用例。
黑盒測試——邊界值分析
另一種黑盒測試方法,是等價類劃分的補充。人們從長期測試的經驗得知,大量的錯誤發生在輸入或輸出范圍的邊界上,而不是在輸入范圍的內部。
首先應確定邊界情況,針對各種邊界情況設計測試用例,可以查出更多的錯誤。
應選取正好等于,剛剛小于或剛剛大于邊界的值做為測試數據,而不是選取等價類中的典型值或任意值做為測試數據。
與懸崖很類似
黑盒測試——因果圖
等價類劃分方法和邊界值分析方法,都著重考慮輸入條件,但未考慮輸入條件間的聯系。
若測試時必須考慮輸入條件的各種組合,可使用一種適合于描述對于多種條件的組合,相應產生多個動作的形式來設計測試用例,這就需要因果圖。
因果圖方法最終生成的是判定表,它適合于檢查程序輸入條件的各種組合情況。
黑盒測試——錯誤推測法
人們可以靠經驗和直覺推測程序中可能存在的各種錯誤,從而有針對性地編寫檢查這些錯誤的例子,這就是錯誤推測法。
錯誤推測法基本想法:列舉程序中所有可能的錯誤和容易發生錯誤的特殊情況,根據它們選擇測試用例。例如,數據測試中的缺省值、空值、零值等。
白盒測試
將測試對象看做一個玻璃盒,測試人員利用程序內部的邏輯結構及有關信息,設計或選擇測試用例,對程序所有邏輯路徑進行測試,提高測試覆蓋率。
白盒測試又稱結構測試或邏輯驅動測試。
在不同點檢查程序的狀態,確定實際的狀態是否與預期的狀態一致。
利用程序內部的邏輯結構及有關信息,設計或選擇測試用例,測試所有邏輯路徑,對軟件的過程性細節做細致的檢查。
白盒測試——邏輯覆蓋
邏輯覆蓋以程序內部邏輯結構為基礎,是一系列測試過程的總稱,逐漸進行越來越完整的通路測試。
①語句覆蓋:語句覆蓋就是設計若干測試用例,運行被測程序,使每一個可執行語句至少執行一次。
②判定覆蓋:又稱分支覆蓋,設計若干測試用例,運行被測程序,使程序中每個判斷的取真分支和取假分支至少經歷一次。
③條件覆蓋:設計若干測試用例,運行被測程序,使程序中每個判斷的每個條件的可能取值至少執行一次。
④判定-條件覆蓋:為兼顧判定覆蓋和條件覆蓋,提出了判定-條件覆蓋,即設計足夠多的測試用例,使得: 每個條件的所有可能取值至少執行一次; 同時每個判斷的每個分支至少執行一次。
⑤條件組合覆蓋:設計足夠的測試用例,運行被測程序,使每個判斷的所有可能的條件取值組合至少執行一次。
⑥路徑覆蓋:設計足夠的測試用例,覆蓋程序中所有可能的路徑。
白盒測試——基本路徑測試
基本路徑測試方法把覆蓋的路徑數壓縮到一定限度內,程序中的循環最多只執行一次。
使用基本路徑測試技術設計測試用例的步驟:1、根據詳細設計結果畫出相應的流圖; 2、計算流圖的環路復雜度; 3、確定基本路徑集合; 4、設計執行基本路徑集中每條路徑的測試用例。
控制流圖的基礎上分析控制構造的環路復雜度,用來度量程序的邏輯復雜性,計算如下:控制流圖G中的區域數; 環路復雜度V(G)=E-N+2,其中E是流圖中邊數,N是節點數; 環形復雜度V(G)=P+1,其中P是流圖中判定節點的數目。
環路復雜度給出了基本路徑集中的獨立路徑的數量,這是確保程序中所有語句至少被執行一次所需的測試數量的上界。 獨立路徑是指至少引入一個以前未處理的新語句或新條件的一條路徑。用流圖術語描述,獨立路徑至少包含一條在定義該路徑前不曾用過的邊。 注意,基本路徑集不是唯一的。
三、軟件測試過程
(1)單元測試
單元測試又稱模塊測試,針對軟件設計的最小單位——程序模塊,進行檢驗的測試工作。
目的在于發現各模塊內部可能存在的錯誤。
單元測試從程序內部結構出發設計測試用例。
多個模塊可以平行、獨立進行單元測試。
單元測試內容
測試者依據詳細設計說明書和源程序清單,了解該模塊的邏輯結構和模塊的I/O條件。包括模塊接口、局部數據結構、重要執行通路、出錯處理、邊界條件
單元測試環境
模塊并不是一個獨立的程序,在考慮測試模塊時,同時要考慮它和外界的聯系。 用一些輔助模塊去模擬與被測模塊有聯系的其他模塊。包括驅動模塊和樁模塊
(2)集成測試
又稱組裝測試或聯合測試,在單元測試基礎上,將模塊按要求組裝為系統,發現與接口有關的問題:連接時,穿越模塊接口的數據是否會丟失; 一個模塊的功能是否對另一模塊產生不利影響; 全局數據結構是否有問題; 各子功能組合起來,能否達到預期的父功能; 單個模塊的誤差累積起來是否會放大。
一次性集成
也叫整體拼裝,首先對每個模塊分別進行單元測試,然后把所有模塊一次全部集成進行測試,最終得到要求的軟件系統。
增量式集成
又稱漸增式組裝,首先對每個模塊測試,然后將這些模塊逐步組裝成較大的系統。 在組裝的過程中邊連接邊測試,以發現連接過程中產生的問題。通過增量逐步加入,組裝成為要求的軟件系統。
①自頂向下增量:按系統程序結構,將模塊沿控制層次自頂向下進行組裝。 自頂向下的增量方式在測試過程中較早地驗證了主要的控制和判斷點。 兩種組裝策略:廣度優先和深度優先。
②自底向上增量:從程序模塊結構的最底層的模塊開始集成和測試。 模塊自底向上進行組裝,對于一個給定層次的模塊,因為其子模塊(包括子模塊的所有下屬模塊)已經集成并測試完成,需要從子模塊得到的信息可以直接得到,所以不再需要樁模塊。 低層的多個模塊可以并行測試,提高測試效率。
③混合式增量:對軟件結構中的中、上層模塊采用自頂向下的集成測試方法; 對下層模塊和關鍵算法模塊采用自底向上的集成測試方法; 形成從上下向中間逼近的混合式測試方法。
集成測試完成標志:集成測試應由專門的測試小組進行,測試小組由有經驗的系統設計人員和程序員組成,測試活動要在評審人員出席的情況下進行。完成后提交 集成測試計劃 、 集成測試規格說明 、? 集成測試分析報告。
(3)確認測試
目標是驗證軟件的有效性,驗證軟件的功能和性能等特性是否與用戶的要求一致,復查軟件配置。
有效性測試
任務是驗證被測軟件是否滿足需求規格說明書列出的需求,是確認測試的基礎,通常運用黑盒測試方法。經過確認測試,有下述兩種可能的結果:測試結果與預期結果相符和 測試結果與預期結果不符
復查軟件配置
軟件配置復查的目的是保證:軟件配置的所有成分都齊全; 各方面的質量都符合要求; 具有維護階段所必需的細節; 已編排好分類的目錄。
除了按合同規定的內容和要求人工審查軟件配置外,確認測試過程還應該嚴格遵循用戶指南及其他操作程序。
確認測試必須有用戶積極參與(當軟件為特定用戶開發時,通過驗收測試,讓用戶驗證所有的需求是否已經滿足/當軟件是為了多個用戶開發的商品軟件時,讓每個用戶逐個執行驗收測試是不切實際的)或者以用戶為主進行,由用戶設計測試用例,使用生產中的實際數據進行測試。
α測試
由用戶在開發環境下進行的,也可以是開發機構內部的用戶在模擬實際操作環境下進行的測試。
α測試是在受控環境下進行的測試,開發者坐在用戶旁邊參與測試,隨時記下錯誤情況和問題。
目的是評價軟件的功能、可使用性、可靠性、性能和支持,尤其注重產品的界面和特色。
α測試可以從編碼結束或單元測試完成后開始,也可以在確認測試過程中產品達到一定的穩定和可靠程度之后再開始。
β測試
由用戶在實際使用環境下進行,開發者通常不在測試現場。
β測試是在開發者無法控制的環境下進行的軟件現場應用,由用戶記下遇到的問題(真實的以及主觀認定的),定期向開發者報告。
β測試衡量產品的功能、可使用性、可靠性、性能和支持,著重于產品的支持性。
β測試處在整個測試的最后階段,當α測試達到一定的可靠程度時才開始β測試,所有手冊文本在此階段完全定稿。
確認測試后需要提交的文檔:確認測試計劃、? 確認測試規格說明、? 確認測試分析報告、? 最終的用戶手冊和操作手冊、? 項目開發總結報告。
四、軟件調試
調試在成功測試階段后開始,任務是進一步診斷和改正程序中潛在的錯誤。
調試活動由兩部分組成:① 確定程序中錯誤的位置和性質; ②對程序(設計,編碼)進行修改,排除錯誤。
調試是通過現象找出原因的一個思維分析的過程,是一個具有很強技巧性的工作。
調試過程:①確定出錯位置;②找出錯誤原因;③修改排除錯誤;④重復進行暴露該錯誤的測試。
調試方法
①強行排錯(蠻干法) ②回溯法 ③原因排除法(對分查找、歸納法、演繹法)
強行排錯法
這種方法目前使用較多,不需要過多的思考,比較省腦筋,效率較低。
內存全部打印調試:在大量數據中尋找出錯位置;
程序特定部位設置打印語句:把打印語句插在出錯的源程序的各關鍵變量改變部位、重要分支部位、子程序調用部位,跟蹤程序執行,監視重要變量的變化;
自動調試工具:利用某些語言的調試功能或專門的調試工具,分析程序的動態過程。
回溯法
在小程序中常用的一種有效的調試方法。 一旦發現了錯誤,首先分析錯誤征兆,確定最先發現“癥狀”的位置。然后,人工沿程序的控制流程,向回追蹤源程序代碼,直到找到錯誤根源或確定錯誤產生的范圍。
對分查找法
如果已知每個變量在程序中若干個關鍵點的正確值,可以在程序中點附近“注入”這些變量的正確值,然后運行程序并檢查輸出。若輸出結果正確,則錯誤原因在程序的前半部分;反之,錯誤原因在程序的后半部分。 對錯誤原因所在部分重復使用上述方法,直至把出錯范圍縮小到容易診斷的程度為止。
調試原則
1、確定錯誤性質和位置的原則:①分析與錯誤征兆相關信息,避免用試探法(最后手段);② 避開死胡同;③ 將調試工具作為輔助手段(幫助思考但不能代替思考)。
2、修改錯誤的原則:①注意錯誤的群集現象,出錯多的地方很可能還有錯誤;② 不能只修改錯誤的表象,而沒有修改錯誤的本身; ③修正一個錯誤的同時,避免引入新的錯誤;④ 改錯過程暫時回到程序設計階段,注意程序設計風格。