测试函数:单元测试用于核实函数的某个方面没有问题;测试用例是一组单元测试,一起核实函数各种情形下的行为都符合要求;全覆盖式测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。为函数编写测试用例,可先导入模块unittest以及要测试的函数,再创建一个集成unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。断言方法用来核实得到的结果是否与期望的结果一致,此处用到了unittest的方法assertEqual()。代码行unittest.main()让Python运行这个文件中的测试,即所有以test_打头的方法。当测试未通过时,不要修改测试,而应该修复导致测试不能通过的代码。
# -*- coding: GBK -*-
'''导入模块unittest和测试函数之后,创建继承unittest.TestCase的类,
编写一系列的方法对函数行为的不同方面进行测试。
断言方法(assertEqual()):核实得到结果是否和预期结果一致'''
import unittest
from name_function import get_formatted_city
from name_function import get_formatted_name
class NamesTestCase(unittest.TestCase):
def test_first_last_name(self):
formatted_name = get_formatted_name('janis', 'joplin')
self.assertEqual(formatted_name, 'Janis Joplin')
def test_first_last_middle_name(self):
formatted_name = get_formatted_name('wolfgang', 'mozart', 'amadeus')
self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart')
class CityTestCase(unittest.TestCase):
def test_city_country(self):
formatted_city = get_formatted_city('Santiago', 'Chile')
self.assertEqual(formatted_city, 'Santiago, Chile')
def test_city_country_population(self):
formatted_city = get_formatted_city('Santiago', 'Chile', 5000000)
self.assertEqual(formatted_city, 'Santiago, Chile - population 5000000')
# 让python运行这个文件的测试,自动运行test_打头的方法
unittest.main()
运行结果解析:第一行的句点表示有4个测试通过了,接下一行指运行4个测试消耗的时间,最后的OK表明该测试用例中的所有单元你测试都通过了(测试通过时打印一个句点,测试引发错误时打印一个E,测试导致断言失败时打印一个F。若有测试未通过,则最后的OK改为FAILED,并提示有几个错误)
测试类:与函数的测试相似,大部分工作都是测试类中方法的行为。6个常用的断言方法,可核实返回的值等于或不等于预期的值、返回的职位True或False、返回的值在列表中或不在列表中。在继承unittest.TestCase的类中使用这些方法。
- 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中
要测试类的行为,需要创建其实例。unittest.TestCase类包含方法setUp(),让我们只需创建这些对象一次,并在每个测试方法中使用它们,若TestCase类中包含方法setUp(),Python将先运行它,再运行各个以test_打头的方法。
setUp()方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例。以下代码中第一个TestCase类中的setUp()做了两件事情:创建一个调查对象、创建一个答案列表。存储这两样东西的变量名包含前缀self(即存储在属性中),因此可在这个类的任何地方使用。
survey.py 文件代码如下:
# -*- coding: GBK -*-
class AnonymousSurvey():
'''收集匿名调查问卷答案'''
def __init__(self, question):
'''存储问题,为存储答案做准备'''
self.question = question
self.responses = []
def show_question(self):
'''显示调查问卷'''
print(self.question)
def store_response(self, new_response):
'''存储单份调查问卷'''
self.responses.append(new_response)
def show_results(self):
'''显示收集到的所有答卷'''
print("Survey result:")
for response in self.responses:
print("- " + response)
# ~ # 定义问题,创建实例对象
# ~ question = 'What language did you first learn to speak?'
# ~ my_survey = AnonymousSurvey(question)
# ~ # 显示问题并存储答案
# ~ my_survey.show_question()
# ~ print("Enter 'q' at any time to quit.\n")
# ~ while True:
# ~ response = input("Language: ")
# ~ if response == 'q':
# ~ break
# ~ my_survey.store_response(response)
# ~ # 显示调查结果
# ~ print("\nThank you to everyone who participated in the survey!")
# ~ my_survey.show_results()
class Employee():
'''记录姓名和年薪'''
def __init__(self,first_name, last_name, yearly_salary):
'''初始化属性'''
self.first_name = first_name
self.last_name = last_name
self.yearly_salary = yearly_salary
def give_raise(self, raise_salary=''):
if raise_salary:
self.yearly_salary += int(raise_salary)
else:
self.yearly_salary += 5000
# ~ my_employee = Employee('hui', 'liu', 5000)
# ~ my_employee.give_raise()
# ~ print(my_employee.yearly_salary)
执行文件代码如下:
import unittest
from survey import AnonymousSurvey
from survey import Employee
class TestAnonymousSurvey(unittest.TestCase):
'''针对类AnonymouseSurvey的测试'''
def setUp(self):
'''创建一个调查对象和一组答案,供使用的的测试方法使用'''
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['English', 'Spanish', 'Mandarin']
def test_store_single_response(self):
'''测试单个答案会被妥善地处理'''
self.my_survey.store_response(self.responses[0])
self.assertIn(self.responses[0], self.my_survey.responses)
def test_store_three_responses(self):
'''测试三个答案是否会被妥善处理'''
for response in self.responses:
self.my_survey.store_response(response)
for response in self.responses:
self.assertIn(response, self.my_survey.responses)
class EestEmployee(unittest.TestCase):
'''针对类Employee的测试'''
def setUp(self):
'''创建一个员工对象'''
self.my_employee = Employee('hui', 'liu', 5000)
def test_give_default_raise(self):
'''测试默认增加年薪'''
self.my_employee.give_raise()
self.assertEqual(self.my_employee.yearly_salary, 10000)
def test_give_custom_raise(self):
'''测试自定义增加年薪'''
self.my_employee.give_raise(6000)
self.assertEqual(self.my_employee.yearly_salary, 11000)
unittest.main()