跳轉到內容

軟體工程/質量簡介

來自華夏公益教科書

在軟體工程的背景下,軟體質量衡量軟體設計得有多好(設計質量),以及軟體與該設計的符合程度(符合質量),[1]雖然存在幾種不同的定義。它通常被描述為軟體的“適用性”。

符合質量關注的是實現(參見軟體質量保證),而設計質量衡量的是設計和需求在建立有價值的產品方面的有效性。[2]

軟體質量的一個挑戰是“每個人都覺得他們理解它”。[3]

軟體質量可以定義為對明確說明的功能和效能需求、明確記錄的開發標準以及所有專業開發的軟體應具備的隱含特性的符合程度。

該定義中的三個關鍵點

  1. 軟體需求是衡量質量的基礎。

    不符合需求就是質量不合格。

  2. 規定的標準定義了一組開發標準,指導軟體工程管理人員。

    如果沒有遵循這些標準,通常會導致質量不合格。

  3. 一組隱含的需求通常不會被提及,例如易用性、可維護性等。

    如果軟體符合其明確的需求,但未能滿足隱含的需求,則懷疑軟體質量。

史蒂夫·邁克康奈爾在程式碼大全中的一個定義將軟體分為兩部分:內部外部質量特徵。外部質量特徵是產品面向其使用者的那些部分,而內部質量特徵是那些不面向使用者的部分。[4]

湯姆·德馬科博士的另一個定義是“產品的質量是它對世界產生的積極變化的函式”。[5]這可以被解釋為,使用者滿意度比任何事情都更重要,決定了軟體的質量。[1]

另一個定義,由傑拉爾德·溫伯格在軟體質量管理:系統思考中提出,是“質量是對某個人來說的價值”。這個定義強調質量本質上是主觀的——不同的人對相同軟體的質量體驗會非常不同。這個定義的一個優勢是它引發了軟體團隊思考的問題,例如“我們希望誰來重視我們的軟體?”以及“對他們來說什麼是有價值的?”

軟體產品質量

[編輯 | 編輯原始碼]
  • 正確性
  • 產品質量
    • 符合需求或程式規範;與可靠性有關
  • 可擴充套件性
  • 完整性
  • 沒有錯誤
  • 容錯性
    • 可擴充套件性
    • 可維護性
  • 文件

IT 軟體質量聯盟 (CISQ) 於 2009 年成立,旨在規範軟體產品質量的度量。該聯盟的目標是將來自全球 2000 家 IT 組織、系統整合商、外包商和軟體供應商的行業高管匯聚在一起,共同解決規範 IT 軟體質量度量的挑戰,並促進支援其部署的市場驅動型生態系統。

原始碼質量

[編輯 | 編輯原始碼]

計算機無法理解“寫得好的”原始碼。但是,從人的角度來看,原始碼可以以影響理解其行為所需工作量的方式編寫。許多原始碼程式設計風格指南,通常強調可讀性,並且通常是特定於語言的約定,旨在降低原始碼維護成本。影響程式碼質量的一些問題包括

  • 可讀性
  • 易於維護、測試、除錯、修復、修改和移植
  • 低複雜度
  • 低資源消耗:記憶體、CPU
  • 編譯或 Lint 警告的數量
  • 魯棒的輸入驗證和錯誤處理,由軟體故障注入建立

提高質量的方法

  • 重構
  • 程式碼檢查或軟體評審
  • 程式碼文件

軟體可靠性

[編輯 | 編輯原始碼]

軟體可靠性是軟體質量的一個重要方面。它被定義為“在指定環境中指定時間內計算機程式無故障執行的機率”。[6]

可靠性的一個顯著特徵是它是客觀的、可衡量的,並且可以估計,而大多數軟體質量都是主觀的標準。[7]這種區別在軟體質量保證學科中尤為重要。這些衡量的標準通常被稱為軟體度量。

隨著如今軟體嵌入到許多裝置中,軟體故障帶來的不僅僅是不便。軟體錯誤甚至導致了人員傷亡。原因從設計糟糕的使用者介面到直接的程式設計錯誤。萊維森博士在論文[1] (PDF) 中討論了一個導致多人死亡的程式設計錯誤。這導致了一些型別軟體開發的需求。在美國,食品藥品監督管理局 (FDA) 和聯邦航空管理局 (FAA) 都對軟體開發有要求。

可靠性的目標

[編輯 | 編輯原始碼]

客觀地確定軟體可靠性的方法的需求源於將當代工程領域的技巧應用於軟體開發的願望。這種願望源於普通人和專家共同觀察到的一個普遍現象,即計算機軟體並沒有按照預期的方式工作。換句話說,軟體被認為表現出不希望的行為,包括徹底的失敗,這對處理的資料、軟體執行的機器,以及擴充套件到這些機器可能負面影響的人員和材料都會產生後果。軟體在經濟和生產過程中越關鍵,或者在維持生命的系統中越關鍵,評估軟體可靠性的必要性就越重要。

無論單個軟體應用程式的 критичность 如何,人們也越來越頻繁地觀察到,軟體已經透過我們使用的技術滲透到現代生活的各個方面。預計這種滲透將繼續,以及我們社會維持的系統對軟體的依賴隨之而來。隨著軟體對我們依賴的系統執行越來越重要,人們認為,軟體應該提供相應的可靠性水平。換句話說,軟體應該按照預期的方式執行,甚至更好,按照它應該執行的方式。

可靠性挑戰

[編輯 | 編輯原始碼]

前一句的迴圈邏輯並非偶然——它旨在說明衡量軟體可靠性問題中的一個基本問題,即難以預先確定軟體的預期執行方式。這個問題似乎源於對軟體考慮中的一個常見概念錯誤,即軟體在某種程度上承擔了人類原本應該承擔的角色。這是一個雙重問題。首先,大多數現代軟體執行人類永遠無法執行的工作,特別是在與人類相比,人們經常期望軟體達到很高的可靠性水平。其次,軟體從根本上無法實現人類的大部分精神能力,這些能力將人類與單純的機制區分開來:例如適應性、通用知識、概念和功能上下文意識以及常識。

然而,大多數軟體程式都可以被認為具有特定的甚至唯一的目的。如果允許該目的可以很好地甚至完全定義的可能性,那麼它應該提供一種方法來至少客觀地考慮軟體是否實際上是可靠的,方法是將預期結果與在給定環境中執行軟體的實際結果進行比較,並使用給定的資料。不幸的是,目前尚不清楚是否可以透過窮舉的方式確定給定程式的整個可能的環境和輸入資料的預期結果或實際結果,如果沒有這些,可能無法以任何確定性確定程式的可靠性。

然而,人們正在努力嘗試控制軟體環境和輸入變數空間的廣闊性,無論是針對實際程式還是針對程式的理論描述。此類旨在提高軟體可靠性的嘗試可以在真實軟體的程式開發的不同階段應用。這些階段主要包括:需求、設計、程式設計、測試和執行時評估。理論軟體可靠性的研究主要關注正確性的概念,這是計算機科學的一個數學領域,它源於語言和自動機理論。

程式開發中的可靠性

[編輯 | 編輯原始碼]

如果程式的開發人員實際上並不知道程式的預期行為,或者他們無法在開發過程中與開發並行確定其預期行為,並且細節足夠詳細,則無法期望程式按預期工作。什麼程度的細節被認為足夠是激烈爭論的。完美細節的想法很有吸引力,但可能不切實際,甚至不可能。這是因為預期行為往往會隨著行為可能範圍的確定而發生變化,而行為可能範圍的確定是透過實際嘗試或更準確地說是嘗試失敗來實現的。

如果程式的預期行為根本無法指定,那麼它是否可以在預先成功指定就是一個有爭議的問題,這就是試圖將建立新軟體專案需求的過程形式化的重點。與形式化工作同時進行的是試圖幫助非專家(尤其是非程式設計師)瞭解軟體專案,而他們對計算機軟體的實際能力瞭解不足。由於如上所述,即使程式設計師也無法始終提前知道軟體在嘗試之前實際上可能是什麼,因此傳達這種知識變得更加困難。

雖然需求旨在指定程式應該做什麼,但設計旨在至少在較高層面上指定程式應該如何做。設計的有用性也受到一些人的質疑,但那些尋求將確保可靠性的過程形式化的人通常會提供良好的軟體設計過程作為實現它的最重要手段。軟體設計通常涉及使用更抽象和更通用的方法來指定軟體的各個部分及其功能。因此,它可以被視為將大型程式分解為許多較小的程式的一種方式,以便這些較小的程式組合在一起可以完成整個程式的工作。

高階設計的目的是:它將被認為是架構問題或整個程式概念和結構問題與實際編碼問題區分開來,實際編碼問題解決實際資料處理問題。它透過縮小較小軟體元件的範圍,從而對開發過程施加額外的約束,並因此(希望)消除可能增加程式設計錯誤可能性的變數。它提供了一個程式模板,包括介面規範,可以由不同的開發團隊在不同的部分共享,以便他們可以預先知道他們的每個貢獻將如何與其他團隊的貢獻互動。最後,也許最具爭議的是,它獨立於實現語言或語言來指定程式,從而消除語言特定的偏差和限制,否則這些偏差和限制會潛入設計中,也許是程式設計師設計師無意中造成的。

程式設計

[編輯 | 編輯原始碼]

計算機程式語言發展史通常可以在掌握計算機程式複雜性的嘗試中得到最好的理解,否則計算機程式的複雜性會隨著程式的大小(可能呈指數級)而變得越來越難以理解。(看待程式語言演變的另一種方式僅僅是讓計算機做更多的事情,但這可能只是另一種說法)。對程式整體結構和功能的理解不足是無法檢測程式錯誤的必然途徑,因此,反過來,使用更好的語言應該透過使更好的理解成為可能來減少錯誤數量。

語言的改進往往逐漸提供軟體設計試圖一步到位的東西:在越來越高的抽象級別上考慮軟體。語句、子例程、檔案、類、模板、庫、元件等發明允許使用層、層次結構和模組等抽象來指定程式各個部分的排列,這些抽象在不同的粒度上提供結構,以便從任何角度來看,程式程式碼都可以想象成井然有序且易於理解。

此外,語言的改進使得對資料元素的形狀和使用方法有了更精確的控制,最終形成了抽象資料型別。可以對這些資料型別進行非常細緻的指定,包括如何以及何時訪問它們,甚至訪問資料之前和之後的 資料狀態。。

軟體構建和部署

[編輯 | 編輯原始碼]

許多程式語言(如 C 和 Java)要求將程式的“原始碼”翻譯成計算機可以執行的形式。這種翻譯是由一個稱為編譯器的程式完成的。為了建立軟體應用程式可用的執行時配置,可能涉及其他操作,例如將檔案關聯、繫結、連結或打包在一起。編譯和組裝過程的總和通常稱為“構建”軟體。

軟體構建對軟體質量至關重要,因為如果任何生成的 檔案不正確,軟體構建很可能會失敗。而且,如果意外地使用了不正確的程式版本,那麼測試會導致錯誤的結果。

軟體構建通常在與執行時區域(如應用程式伺服器)無關的工作區域中完成。為此,需要一個部署步驟將軟體構建產品物理傳輸到執行時區域。部署過程也可能涉及技術引數,如果設定不正確,也會阻止軟體測試開始。例如,Java 應用程式伺服器可能具有首選父級或最後父級類載入選項。使用錯誤的引數會導致應用程式無法在應用程式伺服器上執行。

支援軟體質量的技術活動,包括構建、部署、變更控制和報告,統稱為軟體配置管理。許多軟體工具已經出現,以幫助應對配置管理的挑戰,包括檔案控制工具和構建控制工具。

測試

[edit | edit source]

軟體測試,如果操作正確,可以透過測試產品是否符合其要求來提高整體軟體符合性質量[8] 測試包括但不限於

  1. 單元測試
  2. 功能測試
  3. 迴歸測試
  4. 效能測試
  5. 故障轉移測試
  6. 可用性測試

許多敏捷方法在開發週期的早期使用測試來確保其產品的質量。例如,測試驅動開發實踐(在要測試的程式碼之前編寫測試)在極限程式設計中使用,以確保質量。

執行時

[edit | edit source]

執行時可靠性確定類似於測試,但超越了對行為的簡單確認,而是對效能、與其他程式碼或特定硬體配置的互操作性等質量的評估。

軟體質量因素

[edit | edit source]

軟體質量因素是軟體程式的非功能性需求,客戶合同中沒有提及,但仍然是提高軟體程式質量的理想需求。請注意,這些因素都不是二元的;也就是說,它們不是“要麼有要麼沒有”的特徵。相反,它們是人們希望在軟體中最大限度地提高以最佳化其質量的特徵。因此,不要問一個軟體產品是否“具有”因素x,而是問它在多大程度上(或沒有)具有因素x

這裡列出了一些軟體質量因素

可理解性
目的明確。這超出了簡單的目的陳述;所有設計和使用者文件都必須寫得清楚,以便於理解。這顯然是主觀的,因為必須考慮使用者環境:例如,如果軟體產品要由軟體工程師使用,則不需要對非專業人士可理解。
完整性
所有組成部分的存在,每個部分都得到充分開發。這意味著,如果程式碼呼叫外部庫中的子例程,軟體包必須提供對該庫的引用,並且必須傳遞所有必需的引數。所有必需的輸入資料也必須可用。
簡潔
儘量減少過多的或冗餘的資訊或處理。這在記憶體容量有限的情況下很重要,並且通常被認為是將程式碼行數保持在最低限度的良好做法。可以透過將重複的功能替換為一個實現該功能的子例程或函式來改進它。它也適用於文件。
可移植性
能夠在多個計算機配置上良好且輕鬆地執行。可移植性既可以指不同硬體之間的可移植性——例如在 PC 和智慧手機上執行——也可以指不同作業系統之間的可移植性——例如在 Mac OS X 和 GNU/Linux 上執行。
一致性
在符號、符號、外觀和術語方面保持一致性。
可維護性
傾向於促進更新以滿足新的需求。因此,可維護的軟體產品應該有良好的文件記錄,不應複雜,並且應該有備用容量用於記憶體、儲存和處理器利用率以及其他資源。
可測試性
傾向於支援驗收標準和效能評估。如果要使產品易於測試,則必須在設計階段內建這種特性;複雜的設計會導致可測試性差。
可用性
使用方便實用。這受到諸如人機介面等因素的影響。對可用性影響最大的軟體元件是使用者介面 (UI),為了獲得最佳的可用性,使用者介面通常是圖形化的(即 GUI)。
可靠性
預期能夠令人滿意地執行其預期功能的能力。這意味著有一個時間因素,即可靠的產品預期能夠在一段時間內正常執行。它還包含環境因素,即產品要求在任何環境中都能正常執行(有時稱為健壯性)。
效率
在不浪費資源的情況下實現目的,例如記憶體、空間和處理器利用率、網路頻寬、時間等。
安全性
能夠保護資料免受未經授權的訪問,並能夠抵抗惡意或意外干擾其操作。除了存在適當的安全機制(如身份驗證、訪問控制和加密)外,安全性還意味著在面對惡意、智慧和自適應攻擊者時具有彈性。

軟體質量因素的度量

[edit | edit source]

該領域對度量有不同的觀點。許多度量受到一些專業人士的重視——或者在某些情況下,受到其他人的譴責為有害。一些人認為,軟體質量的定量度量是必不可少的。另一些人認為,定量度量有用的情況非常罕見,因此更喜歡定性度量。該領域的幾位軟體測試領導者撰寫了關於難以衡量我們真正想很好地衡量的東西的文章。[9][10]

一個流行指標的例子是軟體中遇到的故障數量。一些人認為,包含少量故障的軟體比包含大量故障的軟體質量更高。以下問題可以幫助確定此指標在特定環境中的有用性

  1. 什麼是“大量故障”?這是否因軟體的目的而異(例如,部落格軟體與導航軟體)?這是否考慮了軟體的大小和複雜性?
  2. 這是否考慮了錯誤的重要性(以及這些錯誤影響的人對利益相關者的重要性)?是否試圖根據錯誤的嚴重程度或受其影響的使用者發生率來加權此指標?如果是,如何加權?如果不是,如何知道發現的 100 個錯誤比 1000 個錯誤更好?
  3. 如果發現的錯誤數量正在減少,我該如何知道這意味著什麼?例如,這是否意味著該產品現在比以前質量更高?或者,這比以前更小/更不雄心勃勃的變化?或者,投入到該專案中的測試人員工時少於以前?或者,這個專案是由比以前技能更差的測試人員測試的?或者,團隊發現報告的錯誤更少符合他們的利益?

最後一個問題指出了一個特別難以管理的問題。所有軟體質量指標在某種程度上都是對人類行為的度量,因為人類建立軟體。[9] 如果一個團隊發現他們將從報告的錯誤數量下降中受益,那麼該團隊極有可能開始報告更少的缺陷。這可能意味著電子郵件開始繞過錯誤跟蹤系統,或者四五個錯誤被合併到一個錯誤報告中,或者測試人員學會不報告輕微的煩惱。困難在於衡量我們想要衡量的指標,而不會為軟體程式設計師和測試人員創造有意識或無意識地“玩弄”這些指標的動機。

由於其定義模糊,無法衡量軟體質量因素。有必要找到度量或指標,可以用來量化它們作為非功能性需求。例如,可靠性是一個軟體質量因素,但不能獨立評估。但是,確實有一些與可靠性相關的屬性可以測量。這些屬性包括平均故障間隔時間、故障發生率和系統的可用性。類似地,可移植性的一個屬性是程式中目標依賴語句的數量。

下面給出了一種可以用來評估軟體質量因素的方案。對於每種特性,都有一組與該特性相關的問題。可以根據對這些問題的答案開發某種評分公式,從中可以獲得對該特性的測量結果。

可理解性

[edit | edit source]

變數名是否描述了所表示的物理或功能屬性? 獨特的可識別功能是否包含足夠的註釋,以便其目的明確? 是否對偏離前向邏輯流進行了充分的註釋? 陣列的所有元素是否在功能上相關?...

完整性

[編輯 | 編輯原始碼]

所有必要的元件是否可用? 任何程序是否因缺乏資源或程式設計而失敗? 程式碼中所有潛在的路徑是否都已考慮在內,包括適當的錯誤處理?

所有程式碼是否可以訪問? 任何程式碼是否冗餘? 迴圈中多少個語句可以放在迴圈之外,從而減少計算時間? 分支決策是否過於複雜?

可移植性

[編輯 | 編輯原始碼]

程式是否依賴於特定安裝中獨有的系統或庫例程? 是否已標記並註釋了機器相關的語句? 是否已避免對字母數字或特殊字元的內部位表示的依賴? 將程式從一個硬體/軟體系統或環境轉移到另一個環境需要多少工作量?

一致性

[編輯 | 編輯原始碼]

一個變數名是否用於在程式中表示不同的邏輯或物理實體? 程式中是否只包含任何給定物理或數學常數的一種表示形式? 功能相似的算術表示式是否以類似的方式構建? 是否對縮排、命名法、調色盤、字型和其他視覺元素使用了一致的方案?

可維護性

[編輯 | 編輯原始碼]

是否已為將來的擴充套件預留了一些記憶體容量? 設計是否具有凝聚力,即每個模組是否具有獨特、可識別的功能? 軟體是否允許更改資料結構(面向物件的設計更有可能允許這樣做)? 如果程式碼是基於過程的(而不是面向物件的),更改是否可能需要重新構建主程式,或者只是一個模組?

可測試性

[編輯 | 編輯原始碼]

程式碼中是否使用了複雜的結構? 詳細設計中是否包含清晰的虛擬碼? 虛擬碼的抽象級別是否高於程式碼? 如果在併發設計中使用任務,是否提供了用於提供足夠的測試用例的方案?

可用性

[編輯 | 編輯原始碼]

是否使用了 GUI? 是否有足夠的線上幫助? 是否提供了使用者手冊? 是否提供了有意義的錯誤訊息?

可靠性

[編輯 | 編輯原始碼]

迴圈索引是否進行了範圍測試? 輸入資料是否已檢查範圍錯誤? 是否避免了除以零? 是否提供了異常處理? 軟體在指定時間段內在規定的操作條件下正確執行其預期功能的機率,但需求文件中也可能存在問題...

功能是否已針對速度進行了最佳化? 是否已將重複使用的程式碼塊形成子例程? 程式是否已檢查記憶體洩漏或溢位錯誤?

安全性

[編輯 | 編輯原始碼]

軟體是否保護自身及其資料免受未經授權的訪問和使用? 它是否允許操作員執行安全策略? 安全機制是否合適、充分且正確地實施? 軟體是否能夠抵禦其預期環境中可能發生的攻擊?

使用者的視角

[編輯 | 編輯原始碼]

除了軟體的技術質量外,終端使用者的體驗也決定了軟體的質量。 軟體質量的這個方面被稱為可用性。 很難量化給定軟體產品的可用性。 一些需要問的重要問題是

  • 使用者介面是否直觀(不言自明/自文件)?
  • 執行簡單操作是否容易?
  • 執行復雜操作是否可行?
  • 軟體是否提供合理的錯誤訊息?
  • 小部件的行為是否符合預期?
  • 軟體是否記錄良好?
  • 使用者介面是否響應迅速或過慢?

此外,(免費或付費)支援的可用性也可能影響軟體的可用性。

參考文獻

[編輯 | 編輯原始碼]
註釋
  1. a b Pressman 2005, p. 746
  2. Pressman 2005, p. 388
  3. Crosby, P., Quality is Free, McGraw-Hill, 1979
  4. McConnell 1993, p. 558
  5. DeMarco, T., Management Can Make Quality (Im)possible, Cutter IT Summit, Boston, April 1999
  6. J.D. Musa, A. Iannino, and K. Okumoto, Engineering and Managing Software with Reliability Measures, McGraw-Hill, 1987
  7. Pressman 2005, p. 762
  8. ISTQB - What is software testing?
  9. a b Cem Kaner http://www.kaner.com/pdfs/metrics2004.pdf
  10. Douglass Hoffman http://www.softwarequalitymethods.com/Papers/DarkMets%20Paper.pdf
參考書目
  • McConnell, Steve (1993), Code Complete (First ed.), Microsoft Press
  • Pressman, Scott (2005), Software Engineering: A Practitioner's Approach (Sixth, International ed.), McGraw-Hill Education

進一步閱讀

[編輯 | 編輯原始碼]
  • 國際標準化組織。 軟體工程 - 產品質量 - 第 1 部分:質量模型。ISO,瑞士日內瓦,2001 年。ISO/IEC 9126-1:2001(E)。
  • Diomidis Spinellis。 程式碼質量:開源視角。Addison Wesley,美國馬薩諸塞州波士頓,2006 年。
  • Ho-Won Jung、Seung-Gweon Kim 和 Chang-Sin Chung。測量軟體產品質量:ISO/IEC 9126 調查IEEE 軟體,21(5):10–13,2004 年 9 月/10 月。
  • Stephen H. Kan。 軟體質量工程中的度量和模型。Addison-Wesley,美國馬薩諸塞州波士頓,第二版,2002 年。
  • Robert L. Glass。 構建高質量軟體。Prentice Hall,美國新澤西州上鞍河,1992 年。
  • Roland Petrasch,“‘軟體質量’的定義:一種實用方法”,ISSRE,1999 年
[編輯 | 編輯原始碼]
華夏公益教科書