什麼是單元測試?
單元測試是測試程式碼最小功能單位的程序。軟體測試有助於確保程式碼品質,並且是軟體開發中不可或缺的一部分。這是一種軟體開發最佳實務,以較小的功能單元來編寫軟體,然後針對每個程式碼單元編寫一個單元測試。您可以先將單元測試編寫為程式碼。然後,每次對軟體程式碼做出變更時,都會自動執行該測試程式碼。這樣,如果測試失敗,您可以快速隔離包含錯誤或失誤的程式碼區域。單元測試強制執行模組化思維範式,並改善測試覆蓋範圍和品質。自動化單元測試有助於確保您或您的開發人員有更多時間專注於編碼。
什麼是單元測試?
單位測試是一個程式碼區塊,可驗證較小、隔離的應用程式碼區塊 (通常是函數或方法) 的準確性。單元測試旨在依據開發人員背後的理論邏輯檢查程式碼區塊是否如預期運行。單元測試只能透過輸入和擷取的斷言 (true 或 false) 輸出與程式碼區塊進行互動。
單一程式碼區塊也可能有一組單元測試,稱為測試用例。一整套測試用例涵蓋了程式碼區塊的全部預期行為,但並不總是需要定義完整的測試用例集。
當程式碼區塊需要系統的其他部分執行時,您無法與該外部資料結合使用單元測試。單元測試需要獨立執行。程式碼的功能可能需要其他系統資料,例如資料庫、物件或網路通訊。如果是這種情況,您應該改用資料 Stub。為邏輯上簡單的小型程式碼區塊編寫單元測試是最簡單的工作。
單元測試策略
若要建立單元測試,您可以遵循一些基本技巧來確保涵蓋所有測試用例。
邏輯檢查
給定正確的、預期的輸入,系統是否執行正確的計算並遵循通過程式碼的正確路徑? 給定的輸入是否涵蓋通過程式碼的所有路徑?
邊界檢查
對於給定的輸入,系統如何回應? 它如何回應典型的輸入,邊緣案例或無效輸入?
假設您預期在 3 到 7 之間的整數輸入。當您使用 5 (典型輸入),3 (邊緣案例) 或 9 (無效輸入) 時,系統會如何回應?
錯誤處理
當輸入出現錯誤時,系統會如何回應? 是否提示使用者輸入其他內容? 軟體是否當機?
物件導向性檢查
如果透過執行程式碼變更任何持久物件的狀態,則該物件是否正確更新?
單元測試範例
以下是 Python 中一個非常基本的方法的範例,以及一些帶有相應單元測試程式碼的測試用例。
Python 方法
def add_two_numbers(x, y):
return x + y
對應的測試用例
def test_add_positives():
result = add_two_numbers(5, 40)
assert result == 45
def test_add_negatives():
result = add_two_numbers(-4, -50)
assert result == -54
def test_add_mixed():
result = add_two_numbers(5, -5)
assert result == 0
單元測試有哪些優點?
單元測試在許多方面有益於軟體開發專案。
高效的錯誤探索
如果程式碼區塊中存在任何輸入、輸出或邏輯型錯誤,單元測試可協助您在這些錯誤進入生產環境之前擷取它們。當程式碼變更時,您可以執行相同的單元測試 (例如整合測試),並且預期得到相同的結果。如果測試失敗 (也稱為中斷測試),則表示存在基於迴歸的錯誤。
單元測試還有助於更快地找到程式碼中的錯誤。開發人員不會使用大量時間完成偵錯活動。他們可以快速確定出有錯誤的程式碼確切部分。
文件
務必記錄程式碼,以確切地知道該程式碼應該執行的功能。也就是說,單元測試也可以充當某種形式的文件。
其他開發人員可閱讀測試結果,以了解程式碼在執行期間預計會表現出哪些行為。他們會使用這些資訊來修改或重構程式碼。重構程式碼使其效能更高且構成良好。可以再次執行單元測試,以檢查變更後的程式碼是否如預期運作。
開發人員如何使用單元測試?
開發人員在軟體開發生命週期的各個階段使用單元測試。
測試導向性開發
測試導向性開發 (TDD) 是指開發人員先建置測試以檢查軟體的功能要求,然後再編寫完整的程式碼。透過先編寫測試,在編碼完成並執行測試後,即可立即根據要求對程式碼進行驗證。
完成程式碼區塊後
一旦程式碼區塊視為已完成,如果其未透過 TDD 進行開發,則應開發單元測試。然後,您可以立即執行單元測試以驗證結果。在系統測試期間,單元測試也作為其他全套軟體測試的一部分執行。它們通常是在完整系統軟體測試期間執行的第一組測試。
DevOps 效率
將 DevOps 應用於軟體開發實務的核心活動之一是持續整合和持續交付 (CI/CD)。對程式碼的任何變更都會自動整合到更廣泛的程式碼庫中,透過自動測試執行,然後在測試通過後部署。
單元測試與整合測試一起構成測試套件的一部分。它們在 CI/CD 管道中自動執行,以確保隨著時間推移升級和變更期間的程式碼品質。
何時單元測試的優點會減少?
對於每個專案的每個程式碼區塊,並非始終需要對其中的每個測試用例執行單元測試。以下是一些可能省略單元測試的情況範例。
時間受限時
即使使用生成式單元測試框架,編寫新的單元測試也需要開發人員花費大量時間。雖然可以輕鬆產生以輸入和輸出為基礎的單元測試,但很難執行基於邏輯的檢查。
一旦開發人員開始編寫測試,他們還會在程式碼區塊中看到重構的機會,從而分散完成測試的注意力。這可能會導致開發時間延長,並且產生預算不足的問題。
UI/UX 應用程式
如果主系統關注外觀和感覺而非邏輯,就可能沒有太多可執行的單元測試。在這些情況下,其他類型的測試,例如手動測試,是比單元測試更合適的策略。
舊版程式碼庫
事實證明,幾乎無法編寫測試來封裝現有的舊版程式碼,具體取決於所編寫程式碼的風格。由於單元測試需要虛擬資料,因此為具有大量資料解析的高度互連系統編寫單元測試也可能過於耗時。
快速變化的要求
依據不同的專案,在任何給定的工作衝刺階段,軟體都可能發展壯大、轉變方向或完全刪除整個部分。如果要求可能經常發生變化,那麼每次開發程式碼區塊時就沒有太多理由編寫單元測試。
有哪些單元測試最佳實務?
我們提供了一些單元測試最佳實務,協助您充分利用自己的程序。
使用單元測試框架
為每個程式碼區塊編寫明確的、完全自訂的單元測試相當浪費時間。每種流行的程式設計語言都帶有自動測試框架。
例如,Python 提供 pytest 和 unittest 這兩個不同的單元測試框架。測試框架廣泛用於各種規模的軟體開發專案。
自動化單元測試
應依據軟體開發中的不同事件觸發單元測試。例如,可以在使用版本控制軟體將變更推送到分支或部署軟體更新之前使用單元測試。
單元測試也可以按設定的排程在完整的專案上執行。在整個開發生命週期中,自動化單元測試可確保測試在所有適當的事件和案例中執行。
一次斷言
對於每個單元測試,只應有一個真實或錯誤的結果。確保您的測試中只有一條斷言陳述式。在多個斷言陳述式區塊中失敗的斷言陳述式可能會導致無法區分哪條陳述式產生問題。
實作單元測試
單元測試是建置軟體的重要組成部分,但許多專案並沒有為此投入資源。如果專案作為原型啟動,是基於社群的小規模工作,或者只是快速編碼,則由於時間限制,可能會不執行單元測試。
但是,如果從一開始就將單元測試作為標準實務來建置專案,此程序就會變得更容易遵循和重複。
單元測試和其他類型的測試之間有什麼區別?
除了單元測試之外,還有許多其他類型的軟體測試方法。這些方法在軟體開發生命週期中發揮特定的作用:
- 整合測試會檢查設計為互動的軟體系統的不同部分是否正確互動。
- 功能測試會檢查軟體系統是否符合建置前所述的軟體要求。
- 效能測試會檢查軟體是否符合預期的效能要求,例如速度和記憶體大小。
- 接受測試是由利害關係人或使用者群組手動測試軟體,以檢查軟體是否如預期正常運作。
- 安全測試會檢查軟體是否存在已知的弱點和威脅。這包括對威脅面的分析,涉及軟體的第三方入口點。
這些測試方法通常需要專門的工具和獨立程序來檢查軟體。在開發基本的應用程式功能之後也會執行其中的許多方法。
相比之下,每次程式碼建置時都會執行單元測試。可以在編寫任何程式碼後立即編寫單元測試,並且不需要任何特殊工具即可執行。單元測試被視為最基本的軟體測試類型之一。
AWS 如何協助滿足您的單元測試要求?
Amazon Web Services (AWS) 為開發人員提供各種優勢。您可以開發和執行程式碼和測試軟體,例如透過單元測試和整合測試。還可以執行 DevOps 管道並尋求諸多發展機會。
AWS 開發人員工具提供整合式開發環境 (IDE)、外掛程式和 SDK,適用於多種程式設計語言和程式設計使用案例。除了其他優點之外,這些工具還可提高單元測試的效率。
AWS Fargate 是無伺服器、依用量計費的運算引擎,讓您能專注於建置應用程式,而無需管理伺服器。您可以輕鬆地在 Fargate 上執行自動化單元測試軟體,以簡化應用程式開發。
也可以在 AWS Marketplace 上找到第三方單元測試軟體。可以使用所需的控制項快速實作軟體。AWS Marketplace 賣家提供靈活的定價選項,因此您可以在需要時按需求付費。
立即建立帳戶,開始在 AWS 上使用單元測試。