Python零基礎(chǔ)入門之編寫測試實(shí)例(python測驗(yàn)3)
測試函數(shù)
首先是給出用于測試的代碼,如下所示,這是一個接收姓和名然后返回整潔的姓名的函數(shù):
def get_formatted_name(first, last): full_name = first ' ' last return full_name.title()
簡單的測試代碼:
first = 'kobe'last = 'bryant'print(get_formatted_name(first, last)) # 輸出 Kobe Bryant復(fù)制代碼
在 Python 標(biāo)準(zhǔn)庫中的模塊 unittest 提供了代碼測試工具。這里介紹幾個名詞的含義:
- 單元測試:用于核實(shí)函數(shù)的某個方面沒有問題;
- 測試用例:一組單元測試,它們一起核實(shí)函數(shù)在各種情形下的行為符合要求。
- 全覆蓋式測試用例:包含一整套單元測試,涵蓋了各種可能的函數(shù)使用方式。
通常,最初只需要對函數(shù)的重要行為編寫測試即可,等項(xiàng)目被廣泛使用時才考慮全覆蓋。
接下來就開始介紹如何采用 unittest 對代碼進(jìn)行測試。
首先是需要導(dǎo)入 unittest 模塊,然后創(chuàng)建一個繼承 unittest.TestCase 的類,并編寫一系列類方法對函數(shù)的不同行為進(jìn)行測試,如下代碼所示:
import unittestclass NamesTestCase(unittest.TestCase): ''' 測試生成名字函數(shù)的類 ''' def test_first_last_name(self): formatted_name = get_formatted_name('kobe', 'bryant') self.assertEqual(formatted_name, 'Kobe Bryant') unittest.main()
輸出結(jié)果如下,顯示運(yùn)行的測試樣例是 1 個,耗時是 0.001s。
.----------------------------------------------------------------------Ran 1 test in 0.001sOK
上述是給了一個可以通過的例子,而如果測試不通過,輸出是怎樣的呢,如下所示:
# 添加中間名def get_formatted_name(first, middel, last): full_name = first ' ' middle ' ' last return full_name.title()class NamesTestCase(unittest.TestCase): ''' 測試生成名字函數(shù)的類 ''' # 不能通過的例子 def test_first_name(self): formatted_name = get_formatted_name('kobe', 'bryant') self.assertEqual(formatted_name, 'Kobe Bryant') unittest.main()
輸出結(jié)果如下,這里會打印錯誤發(fā)生的地方和錯誤原因:
E======================================================================ERROR: test_first_last_middle_name (__main__.NamesTestCase)----------------------------------------------------------------------Traceback (most recent call last): File "E:/Python_Notes/Practise/unittest_practise.py", line 39, in test_first_last_middle_name formatted_name = get_formatted_name('kobe', 'bryant')TypeError: get_formatted_name() missing 1 required positional argument: 'middle'----------------------------------------------------------------------Ran 1 test in 0.001sFAILED (errors=1)
很明顯是因?yàn)槿鄙?middle 參數(shù),如果希望通過測試,可以將原函數(shù)進(jìn)行如下修改:
def get_formatted_name(first, last, middle=''): ''' 接收姓和名然后返回完整的姓名 :param first: :param last: :return: ''' if middle: full_name = first ' ' middle ' ' last else: full_name = first ' ' last return full_name.title()
然后添加新的測試方法,繼續(xù)運(yùn)行,就可以測試通過。
def test_first_last_middle_name(self): formatted_name = get_formatted_name('kobe', 'bryant', 'snake') self.assertEqual(formatted_name, 'Kobe Snake Bryant')
測試類
上一小節(jié)介紹了給函數(shù)寫測試的代碼,接下來介紹如何編寫針對類的測試。
斷言方法
在 unitest.TestCase 類中提供了很多斷言方法,上一小節(jié)就采用了 assertEqual 這一個判斷給定兩個參數(shù)是否相等的斷言方法,下面給出常用的 6 個斷言方法:
這些方法都只能在繼承了 unittest.TestCase 的類中使用這些方法。
編寫針對類的測試
首先,編寫用于進(jìn)行測試的類,代碼如下所示,這是一個用于管理匿名調(diào)查問卷答案的類:
class AnonymousSurvey(): ''' 收集匿名調(diào)查問卷的答案 ''' def __init__(self, question): ''' :param question: ''' self.question = question self.responses = [] def show_question(self): ''' 顯示問卷 :return: ''' print(self.question) def store_response(self, new_response): ''' 存儲單份調(diào)查問卷 :param new_response: :return: ''' self.responses.append(new_response) def show_results(self): ''' 顯示所有答卷 :return: ''' print('Survey results:') for response in self.responses: print('- ' response)
這個類包含三個方法,分別是顯示問題、存儲單份問卷以及展示所有調(diào)查問卷,下面是一個使用例子:
def use_anonymous_survey(): question = "世上最好的語言是?" language_survey = AnonymousSurvey(question) # 顯示問題 language_survey.show_question() # 添加問卷 language_survey.store_response('php') language_survey.store_response('python') language_survey.store_response('c ') language_survey.store_response('java') language_survey.store_response('go') # 展示所有問卷 language_survey.show_results()if __name__ == '__main__': use_anonymous_survey()
輸出結(jié)果如下:
世上最好的語言是?Survey results:- php- python- c - java- go
然后就開始編寫對該類的測試代碼,同樣創(chuàng)建一個類,繼承 unittest.TestCase ,然后類方法進(jìn)行測試,代碼如下所示:
import unittestclass TestAnonmyousSurvey(unittest.TestCase): def test_store_single_response(self): ''' 測試保存單份問卷的方法 :return: ''' question = "世上最好的語言是?" language_survey = AnonymousSurvey(question) language_survey.store_response('php') self.assertIn('php', language_survey.responses)unittest.main()
上述代碼采用了 assertIn 斷言方法來測試函數(shù) store_response()。
這里還可以繼續(xù)測試能否存儲更多的問卷,如下所示,測試存儲三份問卷:
def test_store_three_response(self): question = "世上最好的語言是?" language_survey = AnonymousSurvey(question) responses = ['c ', 'php', 'python'] for response in responses: language_survey.store_response(response) for response in responses: self.assertIn(response, language_survey.responses)
最后,在 unittest.TestCase 中其實(shí)包含一個方法 setUp() ,它的作用類似類的初始化方法 __init()__,它會在各種以 test_ 開頭的方法運(yùn)行前先運(yùn)行,所以可以在這個方法里創(chuàng)建對象,避免在每個測試方法都需要創(chuàng)建一遍,所以上述代碼可以修改為:
class TestAnonmyousSurvey(unittest.TestCase): def setUp(self): ''' 創(chuàng)建一個調(diào)查對象和一組答案 :return: ''' question = "世上最好的語言是?" self.language_survey = AnonymousSurvey(question) self.responses = ['c ', 'php', 'python'] def test_store_single_response(self): ''' 測試保存單份問卷的方法 :return: ''' self.language_survey.store_response(self.responses[1]) self.assertIn('php', self.language_survey.responses) def test_store_three_response(self): for response in self.responses: self.language_survey.store_response(response) for response in self.responses: self.assertIn(response, self.language_survey.responses)
運(yùn)行后,輸出結(jié)果如下:
..----------------------------------------------------------------------Ran 2 tests in 0.000sOK
注意,這里運(yùn)行成功,打印一個句號,因?yàn)槭沁\(yùn)行兩個測試方法成功,所以打印了兩個句號;如果運(yùn)行出錯,打印一個 E ;測試導(dǎo)致斷言失敗,打印一個 F 。
關(guān)注 轉(zhuǎn)發(fā)。私信小編“零基礎(chǔ)”獲取全套Python零基礎(chǔ)資料大禮包。
來源:本文為第三方轉(zhuǎn)載,如有侵權(quán)請聯(lián)系小編刪除。