Python标准库中的模块unittest提供了代码测试工具。单元测试用于核实函数的某个方面没有问题。测试用例是一组单元测试,他们一道核实函数在各种情形下的行为都符合要求。全覆盖的测试用例包含一整套单元测试,涵盖了各种可能的函数使用方式。
一、测试函数
1. 可通过的测试
要为函数编写测试用例,先导入模块unittest和要测试的函数,再创建一个继承unittest.TestCase的类,并编写一系列方法对函数行为的不同方面进行测试。
import unittest
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')
if __name__ == '__main__':
unittest.main()
创建了名为NamesTestCase的类,用于包含一系列针对get_formatted_name()的单元测试。这个类可以随意命名,但最好让它看起来和要测试的函数相关并包含Test字样,这个类必须继承unittest.TestCase类,这样Python才知道如何运行。
运行这个python文件时,所有以test打头的方法都将自动运行。
assertEqual()是unittest类中最有用的功能之一,断言方法。断言方法核实得到的结果是否与期望的结果一致。
我们可以直接运行这个文件,但需要指出的是,很多测试框架都会先导入测试文件再运行。在本代码中,我们调用unittest.main()来运行测试用例。如果这个文件被测试框架导入,变量__name__的值将不是'__main__',也不会调用unitt.main()。
输出如下:
2. 未通过的测试
测试未通过时,不要修改测试,而应修复导致测试不能通过的代码:检查刚刚对函数所做的修改,找出导致函数行为不符合预期的修改。
3. 添加新测试
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')
全部通过:
只错一个:
二、测试类
1.各种断言方法
方法 | 用途 |
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 |
2. 一个要测试的类
class AnonymousSurvey:
def __init__(self, question):
self.question = question
self.responses = []
def show_question(self):
print(self.question)
def store_response(self, response):
self.responses.append(response)
def show_results(self):
print("Survey results:")
for responce in self.responses:
print(f" - {responce}")
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
def test_store_single_response(self):
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
my_survey.store_response('English')
self.assertIn('English', my_survey.responses)
def test_store_three_responces(self):
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
responses = ['English', 'Chinese', 'French']
for response in responses:
my_survey.store_response(response)
for response in responses:
self.assertIn(response, my_survey.responses)
if __name__ == '__main__':
unittest.main()
如上。
3. 方法SetUp()
在测试一个类中,我们在每个测试方法中都创建了一个AnonymousSurvey实例,并在每个方法中都创建了答案。而SetUp()让我们只需要创建这些对象一次,就能在每个测试方法中使用。
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
def setUp(self):
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['English', 'Chinese', 'French']
def test_store_single_response(self):
self.my_survey.store_response(self.responses[0])
self.assertIn('English', 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)
if __name__ == '__main__':
unittest.main()
setUp()创建了一个调查对象以及答案列表,存储这两样东西的变量名包含前缀self,即存储在属性中,因此可以在这个类的任何地方使用。