測試函數——python編程從入門到實踐


測試函數

  學習測試,得有測試的代碼。下面是一個簡單的函數:

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類中可以使用很長的方法名,這些方法名必須是描述性的,這樣才能明白測試未通過時的輸出。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM