在本章中,我們將學習線程應用程序的測試。我們還將了解測試的重要性。
為什么要測試?
在我們深入討論測試的重要性之前,我們需要知道測試的內(nèi)容。一般來說,測試是一種了解某些東西是如何運作的技術。另一方面,特別是如果我們談論計算機程序或軟件,那么測試就是訪問軟件程序功能的技術。
在本節(jié)中,我們將討論軟件測試的重要性。在軟件開發(fā)中,必須在向客戶端發(fā)布軟件之前進行雙重檢查。這就是由經(jīng)驗豐富的測試團隊測試軟件非常重要的原因。請考慮以下幾點來理解軟件測試的重要性
提高軟件質(zhì)量
當然,沒有公司想要提供低質(zhì)量的軟件,也沒有客戶想購買低質(zhì)量的軟件。測試通過查找和修復其中的錯誤來提高軟件的質(zhì)量。
客戶滿意度
任何業(yè)務中最重要的部分是客戶的滿意度。通過提供無錯誤和優(yōu)質(zhì)軟件,公司可以實現(xiàn)客戶滿意度。
減輕新功能的影響
假設我們已經(jīng)建立了一個10000行的軟件系統(tǒng),我們需要添加一個新功能,然后開發(fā)團隊就會擔心這個新功能對整個軟件的影響。此外,測試也起著至關重要的作用,因為如果測試團隊已經(jīng)完成了一系列測試,那么它可以使我們免于任何潛在的災難性中斷。
用戶體驗
任何業(yè)務中另一個最重要的部分是該產(chǎn)品用戶的體驗。只有測試可以確保最終用戶發(fā)現(xiàn)它簡單易用。
減少開支
測試可以通過在開發(fā)的測試階段找到并修復錯誤而不是在交付后修復它來降低軟件的總成本。如果在交付軟件后出現(xiàn)重大錯誤,那么就客戶不滿意,公司負面聲譽等方面的費用和無形成本而言,會增加其實際成本。
測試什么?
始終建議您對要測試的內(nèi)容有適當?shù)牧私狻T诒竟?jié)中,我們將首先了解測試任何軟件時測試人員的主要動機。代碼覆蓋率,即我們的測試套件在測試時會遇到多少行代碼,應該避免。這是因為,在測試時,僅關注代碼行數(shù)對我們的系統(tǒng)沒有任何實際價值??赡苋匀淮嬖谝恍╁e誤,即使在部署之后,這些錯誤也會在稍后階段反映出來。
考慮以下與測試內(nèi)容相關的重要觀點
- 我們需要專注于測試代碼的功能而不是代碼覆蓋率。
- 我們需要首先測試代碼中最重要的部分,然后轉向代碼中不太重要的部分。這肯定會節(jié)省時間。
- 測試人員必須具有多種不同的測試,可以將軟件推向極限。
測試并發(fā)軟件程序的方法
由于能夠利用多核架構的真正能力,并發(fā)軟件系統(tǒng)正在取代順序系統(tǒng)。最近,并發(fā)系統(tǒng)程序被用于從手機到洗衣機,從汽車到飛機等各種各樣的系統(tǒng)程序。我們需要更加謹慎地測試并發(fā)軟件程序,因為如果我們已經(jīng)為單線程應用程序添加了多個線程已經(jīng)是一個錯誤,那么我們最終會遇到多個錯誤。
并發(fā)軟件程序的測試技術廣泛關注于選擇交錯,這種交錯暴露了可能有害的模式,如競爭條件,死鎖和違反原子性。以下是測試并發(fā)軟件程序的兩種方法
系統(tǒng)探索
該方法旨在盡可能廣泛地探索交錯的空間。這種方法可以采用蠻力技術,其他方法采用偏序降階技術或啟發(fā)式技術來探索交織空間。
房產(chǎn)驅(qū)動
屬性驅(qū)動的方法依賴于觀察到并發(fā)錯誤更可能發(fā)生在暴露特定屬性(例如可疑內(nèi)存訪問模式)的交錯下。不同的屬性驅(qū)動方法針對不同的錯誤,如競爭條件,死鎖和違反原子性,這進一步取決于一個或其他特定屬性。
測試策略
測試策略也稱為測試方法。該策略定義了如何進行測試。測試方法有兩種技術 -
主動
一種方法,盡可能早地啟動測試設計過程,以便在創(chuàng)建構建之前找到并修復缺陷。
反應
一種方法,在開發(fā)過程完成之前,測試不會開始。
在對python程序應用任何測試策略或方法之前,我們必須對軟件程序可能具有的錯誤類型有一個基本的想法。錯誤如下
語法錯誤
在程序開發(fā)期間,可能會出現(xiàn)許多小錯誤。錯誤主要是由于輸入錯誤。例如,缺少冒號或關鍵字的拼寫錯誤等。此類錯誤是由于程序語法錯誤而非邏輯錯誤造成的。因此,這些錯誤稱為語法錯誤。
語義錯誤
語義錯誤也稱為邏輯錯誤。如果軟件程序中存在邏輯或語義錯誤,則語句將正確編譯并運行,但由于邏輯不正確,因此無法提供所需的輸出。
單元測試
這是測試python程序最常用的測試策略之一。此策略用于測試代碼的單元或組件。按單位或組件,我們指的是代碼的類或函數(shù)。單元測試通過測試“小”單元簡化了大型編程系統(tǒng)的測試。借助于上述概念,單元測試可以被定義為一種方法,其中測試各個源代碼單元以確定它們是否返回所需的輸出。
在隨后的章節(jié)中,我們將了解用于單元測試的不同python模塊。
unittest模塊
單元測試的第一個模塊是unittest模塊。它受junit的啟發(fā),默認情況下包含在python3.6中。它支持測試自動化,共享測試的設置和關閉代碼,將測試聚合到集合中,以及測試與報告框架的獨立性。
以下是unittest模塊支持的一些重要概念
文字夾具
它用于設置測試,以便在開始測試之前運行并在測試結束后拆除。它可能涉及在開始測試之前創(chuàng)建臨時數(shù)據(jù)庫,目錄等。
測試用例
測試用例檢查所需的響應是否來自特定的輸入集。unittest模塊包含一個名為testcase的基類,可用于創(chuàng)建新的測試用例。它包含兩個默認方法 -
- setup() - 一種用于在運行之前設置測試夾具的鉤子方法。 在調(diào)用實現(xiàn)的測試方法之前調(diào)用它。
- teardown( - 用于在類中運行所有測試后解構類夾具的鉤子方法。
測試套件
它是測試套件,測試用例或兩者的集合。
試驗跑步者
它控制測試用例或套裝的運行,并為用戶提供結果。它可以使用gui或簡單的文本界面來提供結果。
例
以下python程序使用unittest模塊來測試名為 fibonacci 的模塊。該程序有助于計算一個數(shù)字的斐波那契數(shù)列。在此示例中,我們創(chuàng)建了一個名為fibo_test的類,以使用不同的方法定義測試用例。這些方法繼承自unittest.testcase。我們使用兩種默認方法 setup()和teardown()。我們還定義了testfibocal方法。必須使用字母測試開始測試的名稱。在最后一個塊中,unittest.main()為測試腳本提供了一個命令行界面。
import unittest def fibonacci(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a class fibo_test(unittest.testcase): def setup(self): print("this is run before our tests would be executed") def teardown(self): print("this is run after the completion of execution of our tests") def testfibocal(self): self.assertequal(fib(0), 0) self.assertequal(fib(1), 1) self.assertequal(fib(5), 5) self.assertequal(fib(10), 55) self.assertequal(fib(20), 6765) if __name__ == "__main__": unittest.main()
從命令行運行時,上面的腳本會生成一個如下所示的輸出 -
輸出
this runs before our tests would be executed. this runs after the completion of execution of our tests. . ---------------------------------------------------------------------- ran 1 test in 0.006s ok
現(xiàn)在,為了更清楚,我們正在改變我們的代碼,這有助于定義fibonacci模塊。
以下面的代碼塊為例
def fibonacci(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a
對代碼塊進行了一些更改,如下所示 -
def fibonacci(n): a, b = 1, 1 for i in range(n): a, b = b, a + b return a
現(xiàn)在,在使用更改的代碼運行腳本后,我們將獲得以下輸出
this runs before our tests would be executed. this runs after the completion of execution of our tests. f ====================================================================== fail: testcalculation (__main__.fibo_test) ---------------------------------------------------------------------- traceback (most recent call last): file "unitg.py", line 15, in testcalculation self.assertequal(fib(0), 0) assertionerror: 1 != 0 ---------------------------------------------------------------------- ran 1 test in 0.007s failed (failures = 1)
上面的輸出顯示模塊未能提供所需的輸出。
docktest模塊
docktest模塊還有助于單元測試。它還預先包裝了python。它比unittest模塊更容易使用。unittest模塊更適合復雜的測試。要使用doctest模塊,我們需要導入它。相應函數(shù)的docstring必須具有交互式python會話及其輸出。
如果我們的代碼中的一切都很好,那么docktest模塊就沒有輸出; 否則,它將提供輸出。
例
以下python示例使用docktest模塊測試名為fibonacci的模塊,該模塊有助于計算數(shù)字的fibonacci系列。
import doctest def fibonacci(n): """ calculates the fibonacci number >>> fibonacci(0) 0 >>> fibonacci(1) 1 >>> fibonacci(10) 55 >>> fibonacci(20) 6765 >>> """ a, b = 1, 1 for i in range(n): a, b = b, a + b return a if __name__ == "__main__": doctest.testmod()
我們可以看到名為fib的相應函數(shù)的docstring具有交互式python會話以及輸出。如果我們的代碼沒問題,那么doctest模塊就沒有輸出。但要了解它是如何工作的,我們可以使用-v選項運行它。
(base) d:\programdata>python dock_test.py -v trying: fibonacci(0) expecting: 0 ok trying: fibonacci(1) expecting: 1 ok trying: fibonacci(10) expecting: 55 ok trying: fibonacci(20) expecting: 6765 ok 1 items had no tests: __main__ 1 items passed all tests: 4 tests in __main__.fibonacci 4 tests in 2 items. 4 passed and 0 failed. test passed.
現(xiàn)在,我們將更改有助于定義fibonacci模塊的代碼
以下面的代碼塊為例
def fibonacci(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a
以下代碼塊有助于更改
def fibonacci(n): a, b = 1, 1 for i in range(n): a, b = b, a + b return a
在沒有-v選項的情況下運行腳本后,使用更改的代碼,我們將獲得如下所示的輸出。
輸出
(base) d:\programdata>python dock_test.py ********************************************************************** file "unitg.py", line 6, in __main__.fibonacci failed example: fibonacci(0) expected: 0 got: 1 ********************************************************************** file "unitg.py", line 10, in __main__.fibonacci failed example: fibonacci(10) expected: 55 got: 89 ********************************************************************** file "unitg.py", line 12, in __main__.fibonacci failed example: fibonacci(20) expected: 6765 got: 10946 ********************************************************************** 1 items had failures: 3 of 4 in __main__.fibonacci ***test failed*** 3 failures.
我們可以在上面的輸出中看到三個測試都失敗了。