編寫函數和類時,還可以爲其編寫測試。通過測試,可確定代碼面對各種輸入都能夠按要求那樣工作。在程序添加新代碼時,你也可以對其進行測試,確認它們不會破壞程序既有的行爲。程序員都會犯錯,因此每個程序員都必須經常測試其代碼,在用戶發現問題前找出它們。
測試函數
name_function.py
def get_formatted_name(first, last):
"""Generate a neatly formatted full name."""
full_name = first + ' ' + last
return full_name.title()
names.py
from name_function import get_formatted_name
print("Enter 'q' at any time to quit.")
while True:
first = input("\nPlease give me a first name: ")
if first == 'q':
break
last = input("Please give me a lst name: ")
if last == 'q':
break
formatted_name = get_formatted_name(first, last)
print("\tNeatly formatted name: " + formatted_name + '.')
單元測試和測試用例
Python標準庫中的模塊unittest提供了代碼測試工具。單元測試用於覈實函數的某個方面沒有問題;測試用例是一組單元測試,這些單元測試一起覈實函數在各種情形下的行爲都符合要求。良好的測試用例考慮到了函數可能的各種輸入,包含針對所有這些情形的測試。全覆蓋式測試用例包含一整套單元測試,涵蓋了各種可能的函數使用方式。對於大型項目,要實現全覆蓋可能很難。通常,最初只要針對代碼的重要行爲編寫測試即可,等項目被廣泛使用時再考慮全覆蓋。
可通過的測試
創建測試用例的語法需要一段時間才能習慣,但測試用例創建後,再針對函數的單元測試就很簡單了。要爲函數編寫測試用例,可先導入模塊unittest以及要測試的函數,再創建一個繼承unittest.TestCase的類,並編寫一系列方法對函數行爲的不同方面進行測試。
下面時一個只包含一個方法的測試用例,它檢查函數get_formatted_name( )在給定名和姓時能否正確地工作:
test_name_function.py
import unittest
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
"""測試name_function.py"""
def test_first_last_name(self):
"""能夠正確地處理像Janis Joplin這樣的姓名嗎?"""
formatted_name = get_formatted_name('janis','joplin')
self.assertEqual(formatted_name,'Janis Joplin')
unittest.main()
----------------------------------------------------------------------
Ran 1 test in 0.007s
OK
首先,我們導入了模塊unittest和要測試的函數get_formatted_name( )。我們創建了一個名爲NamesTestCase的類,用於包含一系列針對get_formatted_name( )的單元測試。你可隨便給這個類命名,但最好讓它看起來與要測試的函數相關,幷包含字樣Test。這個類必須繼承unittest.TestCase類,這樣Python才知道如何運行你編寫的代碼。
NamesTestCase只包含一個方法,用於測試get_formatted_name( )的一個方面。我們將這個方法命名爲test_first_last_name( ),因爲我們要覈實的時只有名和姓的姓名能夠被正確地格式化。我們運行test_name_function.py時,所有以test_打頭的方法都將自動運行。在這個方法中,我們調用了要測試的函數,並存儲了要測試的返回值。在這個示例中,我們使用實參‘janis’和‘joplin’調用get_formatted_name( ),並將結果存儲到變量formatted_name中。
我們使用了unittest類最有用的功能之一:一個斷言方法。斷言方法用來覈實得到的結果是否與期望的一致。代碼行self.assertEqual(formatted_name,’Janis Joplin’)的意思是說:“將formatted_name的值同字符串‘Janis Joplin’進行比較,如果它們相等,就萬事大吉。
測試類
Unittest Module中斷言的方法
方法 | Are |
---|---|
assertEqual(a,b) | 覈實a==b |
assertNotEqual(a,b) | 覈實a!=b |
assertTrue(x) | 覈實X爲true |
assertFalse(x) | 覈實X爲false |
assertIn(item,list) | 覈實item在list中 |
assertNotIn(item,list) | 覈實item不在list中 |
一個要測試的類
類的測試與函數的測試相似——你所做的大部分動作都是測試類中方法的行爲,但存在一些不同之處。
class AnonymousSurvey():
"""手機匿名調查問卷的答案"""
def __init__(self,question):
"""存儲一個問題,併爲村存儲答案做準備"""
self.question = quesiton
self.responses = []
def show_question(self):
"""顯示調查問卷"""
print(question)
def show_response(self,new_response):
"""存儲單份調查答卷"""
self.response.append(new_response)
def show_results(self):
"""顯示收集到的所有答案"""
print("Survey results:")
for response in responses:
print('- ' + response)