(一)、各种断言的方法
python在unittest.TestCase类中提供了很多方法。
表a描述了6种常用的断言方法:
方法 | 用途 |
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中 |
(二)、一个要测试的类
类的测试与函数的测试相类似---你所做的大部分工作都是测试类中的方法的行为,但存在一些不同之处,下面来编写一个类进行测试。
survey.py
class AnonymousSurvey():
"""收集匿名调查问卷"""
1. def __init__(self,question):
"""存储一个问题"""
self.question = question
self.responses = []
2. def show_question(self):
"""显示调查问卷"""
print(self.question)
3. def store_response(self,new_response):
"""存储单份调查问卷"""
self.responses.append(new_response)
4. def show_results(self):
"""显示收集到的所有答案"""
print("Survet results:")
for response in self.responses:
print('- ' + response)
这个类首先存储了一个你指定的调查问题(见1),并创建了一个空列表,用于存储答案。这个类包含打印调查问题的方法(见2)、在答案列表中添加新答案的方法(见3)以及将存储在列表中的答案都打印出来的方法(见4)。要创建这个类的实例,只需提出一个问题即可。有了表示调查的实例后,就可使用show_question()来显示其中的问题,可使用store_resopnse()来存储答案,并使用show_results()来显示调查结果。
为证明AnonymousSurvey类能够正确工作,我们来编写一个使用它的程序:
language_survey.py
from survey import AnonymousSurvey
#定义一个问题
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")
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()
(三)、测试AnonymousSurvey类
import unittest
from survey import AnonymousSurvey
class TestAnonmyousSurvey(unittest.TestCase):
#针对AnonymousSurvey类的测试
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)
unittest.main()
运行结果:
(四)、方法setup()
在前面的test_survey.py中,我们在每个测试方法中都创建了一个AnonymousSurey实例,并在每个方法中都创建了答案。unittest.TestCase类包含方法setup(),让我们只需创建这些对象一次,并在每个测试方法中使用他们。如果你在TestCase类中包含了方法setup()方法,python将先运行它,在运行以test_打头的方法。这样,在你编写的每个测试方法中都可以使用在方法setup()中创建的对象了。
下面使用setup()来创建一个调查对象和一组答案,共方法test_store_signle_response()和test_store_three_responses()使用:
import unittest
from survey import AnonymousSurvey
class TestAnonmyousSurvey(unittest.TestCase):
#针对AnonymousSurvey类的测试
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)
unittest.main()
方法setup做了两件事:创建一个调查对象;创建一个答案列表。存储这两样东西的变量名包含前缀self(即存储在属性中),因此可以在这个类的任何地方使用。这让两个测试方法都更简单,因为他们都不用创建调查对象和答案。方法test_store_single_response()核实self.responses中的第一个答案----self.responses[0]------被妥善的存储,而方法test_store_three_response()核实self.responses中的全部三个答案都被妥善的存储。
再次运行test_survey.py时,这两个测试也都通过了。如果要扩展AnonymousSurvey,使其允许每位用户输入多个答案,这些测试将很有用。修改代码后接受多个答案后,可运行这些测试,确认存储单个答案或一系列答案的行为受到影响。
注:运行测试用例时,没完成一个单元测试,python都打印一个字符:测试通过时打印一个句点;测试引发错误时打印一个E;测试导致断言失败时打印一个F。这就是你运行测试用例时,在输出的第一行中看到的句点和字符数两个不相同的原因