测试代码
参与工作量较大的项目时,你应对自己编写的函数和类的重要行为进行测试。这样你就能够更加确定自己所做的工作不会破坏项目的其他部分,因此你可以更加放心地去改善自己的其他部分代码。如果破坏了原来的功能,python会反馈给你,从而能够轻松地修复问题。相比于等到不满意的用户 报告bug后再采取措施,在测试未通过时采取措施要容易得多。
单元测试和与测试用例
python标准库中的模块unittest 提供了代码测试工具。
单元测试用于核实函数的某个方面没有问题;测试用例是一组单元测试,这些单元测试一起核实函数在各种情形下的行为都符合要求。
e.g.
先是有关调查的一个类
class AnonymousSurvey():
"""收集匿名调查问卷的答案"""
def __init__(self, question):
"""存储一个问题,并为存储答案做准备"""
self.question = question
self.responses = []
def show_question(self,question):
"""显示问卷"""
print(question)
def store_response(self, new_response):
"""存储答卷"""
self.responses.append(new_response)
def show_results(self):
"""显示答卷"""
print("Survey results:")
for response in self.responses:
print('- ' + response)
对类中存储方法进行测试:
import unittest
from survey import AnonymousSurvey
class Test_survey(unittest.TestCase):
def test_stor_one_ansawer(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)
unittest.main()
测试结果:
测试过程分析
1.首先,我们导入了模块unittest和要测试的函数。然后,我们创建了一个名为Test_survey的类,用于包含一系列针对被测试函数的单元测试。类名随便,但要包含字样Test。这个类必须要继承unittest.TestCase类,这样Python才知道如何运行你编写的测试。
2.self.assertIn('English', my_survey.responses) 这里使用了方法”断言“。
断言方法用来核实得到的结果是否与期望的结果一致。
断言
断言方法用来核实得到的结果是否与期望的结果一致。
断言方法:
测试结果反馈
如果通过测试
第1行的句点表明有一个测试通过了。
接下来的一行指出Python运行了一个测试,消耗的时间不到0.001秒。
OK表明该测试用例中的所有单元测试都通过了。
接下来的一行指出Python运行了一个测试,消耗的时间不到0.001秒。
OK表明该测试用例中的所有单元测试都通过了。
结果表明被测试的函数总是能正确地处理。
如果不能通过测试
E:当测试引发错误时打印一个E;
F:当断言失败时打印一个F。
第二行及trace back显示错误原因
最后的FAILED (errors=1),反馈运行该测试用例时发生了一个错误 。
setUp()方法
为了不在每个测试方法中重复相同的代码,unittest.TestCase类包含方法setUp(),让
我们只需创建某个对象一 次,并在每个测试方法中使用它们。如果你在TestCase类中包含了方法setUp(),Python将先运行setUp(),再运行各个以test_打头的方法。这样,在你编写的每个测试方法中都可使用在方法setUp()中创建的对象了。
e.g.
没有setUp()时
import unittest
from survey import AnonymousSurvey
class Test_survey(unittest.TestCase):
# def setUp(self):
# question = "wafffff....."
# self.my... = AnonymousSurvey(question)
# self.responses = ['c', 'python']
def test_stor_one_ansawer(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_stor_three_answer(self):
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)
response = ['C', 'Python', 'linux']
for res in response:
my_survey.store_response(res)
for resp in response:
self.assertIn(resp, my_survey.responses)
unittest.main()
# for resp in self.responses:
# self.my_....stor...(resp)
# for resp in self.responses:
# self.assertIn(resp, self.my....responses)
使用setUp()后
import unittest
from survey import AnonymousSurvey
class TestAnonymousSurvey(unittest.TestCase):
"""针对AnonymousSurvey类的测试"""
def setUp(self):
""" 创建一个调查对象和一组答案,供使用的测试方法使用"""
question = "What language did you first learn to speak?"
self.my_survey = AnonymousSurvey(question)
self.responses = ['C', 'python', 'php']
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)
unittest.main()
相比下来,后者避免了多次创建my_survey实例和responses。