測試函數 學習測試,得有測試的代碼。下麵是一個簡單的函數: 為核實get_formatted_name()像期望的那樣工作,編寫一個使用這個函數的程式: 運行: 從輸出可知,合併得到的姓名正確無誤。現在假設要修改get_formatted_name(),使其還能夠處理中間名。確保不破化這個函數處理只 ...
測試函數
學習測試,得有測試的代碼。下麵是一個簡單的函數:
name_function.py
def get_formatted_name(first, last): """Generate a neatly formatted full name.""" full_name = first + ' ' + last return full_name.title()
為核實get_formatted_name()像期望的那樣工作,編寫一個使用這個函數的程式:
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 last name: ") if last == 'q': break formatted_name = get_formatted_name(first, last) print("\tNeatly formatted name: " + formatted_name + ".")
運行:
Enter 'q' at any time to quit. Please give me a first name: janis Please give me a last name: joplin Neatly formatted name: Janis Joplin. Please give me a first name: bob Please give me a last name: dylan Neatly formatted name: Bob Dylan. Please give me a first name: q
從輸出可知,合併得到的姓名正確無誤。現在假設要修改get_formatted_name(),使其還能夠處理中間名。確保不破化這個函數處理只有名和姓的方式,為此可在每次修改get_formatted_name()後都進行測試:運行names.py,並輸入像Janis Joplin這樣的姓名。但python提供了一種自動化測試函數輸出的高效方式,對get_formatted_name()進行自動化測試,就可信心滿滿,確信函數提供測試過的姓名時,都能正確工作。
1 單元測試和測試用例
Python標準庫中的模塊unittest提供了代碼測試工具。單元測試——合適函數某個方面沒有問題;測試用例——一組單元測試,這些單元測試一起核實函數在各種情況下的行為都符合要求。良好的測試用例考慮到函數可能收到的各種輸入,包含針對所有這些測試情形的測試。。。全覆蓋式測試用例包含一整套單元測試,涵蓋了各種可能的函數使用方式。
2 可通過的測試
編寫測試用例,可先導入模塊unittest以及要測試的函數,再創建一個繼承unittest.TestCase的類,並編寫一系列方法對函數行為的不同方面進行測試。
下麵時一個只包含一個方法的測試用例,檢查函數get_formatted_name()在給定名和姓時能否正確工作:
test_name_function.py
import unittest from name_function import get_formatted_name class NamesTestCase(unittest.TestCase): # 創建包含針對 get_formatted_name() 的單元測試的類;最好包含字樣Test;必須繼承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類中的一個斷言方法,判斷是否相等 if __name__ == '__main__': # 在pycharm中運行時需要這行代碼,IDLE運行則不需要 unittest.main() # 讓python運行這個文件中的測試
運行test_name_function.py時,所有以test打頭的方法都將自動運行。
3 不能通過的測試
修改get_formatted_name(),使其能夠處理中間名,但這樣做時,故意讓函數無法處理只有名和姓的名字。
get_formatted_name()的新版本,通過一個實參指定中間名:
name_function.py
def get_formatted_name(first, middle, last): """Generate a neatly formatted full name.""" full_name = first + ' ' + middle + ' ' + last return full_name.title()
此時運行test_name_function.py,運行結果:
Ran 1 test in 0.003s FAILED (errors=1) Error Traceback (most recent call last): File "C:\Program Files\Python 3.7\lib\unittest\case.py", line 59, in testPartExecutor yield File "C:\Program Files\Python 3.7\lib\unittest\case.py", line 615, in run testMethod() File "C:\Users\yxf\Desktop\python_pycharm\test_names_function.py", line 10, in test_first_last_name formatted_name = get_formatted_name('janis', 'joplin') TypeError: get_formatted_name() missing 1 required positional argument: 'last' Process finished with exit code 1 Assertion failed Assertion failed Assertion failed
運行結果中給出了詳細的錯誤信息。
4 測試未通過時怎麼辦
由測試代碼運行得到的錯誤信息可知get_formatted_name()少一個實參,修改get_formatted_name():
def get_formatted_name(first, last, middle=''): """Generate a neatly formatted full name.""" if middle: full_name = first + ' ' + middle + ' ' + last else: full_name = first + ' ' + last return full_name.title()
再次運行test_name_function.py:
Ran 1 test in 0.002s OK
5 添加新測試
再編寫一個測試用例,用於測試包含中間名字的測試,即在NamesTestCase類中再添加一個方法:
def test_first_last_middle_name(self): """能夠正確地處理像Wolfgang Amadeus Mozart這樣的名字嗎?""" formatted_name = get_formatted_name('wolfgang', 'mozart', 'amadeus') self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
***調用函數時,可選實參,即本段代碼中中間名在最後。
方法名必須以test_打頭,這樣它才會在運行test_name_function.py時自動運行。
在TestCase類中可以使用很長的方法名,這些方法名必須是描述性的,這樣才能明白測試未通過時的輸出。