针对单个函数的测试
1.要测试的函数
name_function.py
1 def get_formatted_name(first, last): 2 """接受名和姓并返回整洁的姓名""" 3 full_name = first + ' ' + last 4 return full_name.title() 5 6 #函数 get_formatted_name() 将名和姓合并成姓名,在名和姓之间加上一个空格,并将它们的首字母都大写,再返回结果。
2.编写测试用例
test_name_function.py
1 import unittest #导入 unittest 模块 2 from name_function import get_formatted_name #导入要测试的函数 3 4 class NamesTestCase(unittest.TestCase): #测试用例:创建一个继承 unittest.TestCase 的类,包含一系列针对 get_formatted_name 的单元测试 5 """ 测试 name_function.py""" 6 7 def test_first_last_name(self): #编写方法对函数的行为进行测试 8 """ 检查函数 get_formatted_name() 在给定名和姓时能否正确地工作 """ 9 formatted_name = get_formatted_name('janis', 'joplin') #在这个方法中,我们调用了要测试的函数,并存储了要测试的返回值。 10 self.assertEqual(formatted_name, 'Janis Joplin') #通过断言,将 formatted_name 的值同字符串 'Janis Joplin' 进行比较。 11 12 unittest.main() #运行这个文件中的测试,运行 testname_function.py 时,所有以 test_ 打头的方法都将自动运行。
3.运行结果(测试通过)
1 . # . 表示有一个测试通过了 2 ---------------------------------------------------------------------- 3 Ran 1 test in 0.000s # 表示执行了一个测试,执行时间0.000s 4 OK #表示该测试用例中的所有单元测试都通过了
1.修改要测试的函数
name_function.py
1 def get_formatted_name(first, middle, last): 2 """ 接受名和姓并返回整洁的姓名 """ 3 full_name = first + ' ' + middle + ' ' + last 4 return full_name.title() 5 6 #函数 get_formatted_name() 将姓、中间名、名合并成姓名。
2.运行测试用例(测试未通过)
1 E #测试用例中有一个单元测试导致了错误 2 ====================================================================== 3 ERROR: test_first_last_name (__main__.NamesTestCase) # NamesTestCase 中的 test_first_last_name() 导致了错误 4 ---------------------------------------------------------------------- 5 Traceback (most recent call last): 6 File "test_name_function.py", line 8, in test_first_last_name 7 formatted_name = get_formatted_name('janis', 'joplin') 8 TypeError: get_formatted_name() missing 1 required positional argument: 'last' 9 # traceback指出:函数调用 get_formatted_name('janis', 'joplin') 有问题,因为它缺少一个必不可少的位置实参。 10 11 ---------------------------------------------------------------------- 12 Ran 1 test in 0.000s 1314 FAILED (errors=1) #整个测试用例都未通过,因为运行该测试用例时发生了一个错误
1.修改要测试的函数
name_function.py
1 def get_formatted_name(first, last, middle=''): #将形参 middle 移到形参列表末尾,默认值为一个空字符串,变成可选项 2 """ 接受名、中间名、姓并返回整洁的姓名 """ 3 if middle: #添加 if 测试,以便根据是否提供了中间名相应地创建姓名 4 full_name = first + ' ' + middle + ' ' + last 5 else: 6 full_name = first + ' ' + last 7 return full_name.title()
2.编写测试用例,新增单元测试
test_name_function.py
1 import unittest 2 from name_function import get_formatted_name 3 4 class NamesTestCase(unittest.TestCase): 5 """ 测试 name_function.py """ 6 7 def test_first_last_name(self): 8 """ 能够正确地处理像 Janis Joplin 这样的姓名吗? """ 9 formatted_name = get_formatted_name('janis', 'joplin') 10 self.assertEqual(formatted_name, 'Janis Joplin') 11 12 def test_first_last_middle_name(self): #方法名必须是描述性的,这样测试未通过时,才知道是哪种行为未通过 13 """ 能够正确地处理像 Wolfgang Amadeus Mozart 这样的姓名吗? """ 14 formatted_name = get_formatted_name( 15 'wolfgang', 'mozart', 'amadeus') 16 self.assertEqual(formatted_name, 'Wolfgang Amadeus Mozart') 17 18 unittest.main()
3.运行结果(测试通过)
1 .. 2 ---------------------------------------------------------------------- 3 Ran 2 tests in 0.000s 4 5 OK
针对类的测试
1.要测试的类
survey.py
1 class AnonymousSurvey(): 2 """ 收集匿名调查问卷的答案 """ 3 4 def __init__(self, question): 5 self.question = question #存储一个问题 6 self.responses = [] #创建一个空列表,用于存储答案 7 8 def show_question(self): 9 """ 打印调查问题 """ 10 print(question) 11 12 def store_response(self, new_response): 13 """ 在答案列表中添加新答案 """ 14 self.responses.append(new_response) 15 16 def show_results(self): 17 """ 将存储在列表中的答案都打印出来 """ 18 print("Survey results:") 19 for response in responses: 20 print('- ' + response)
2.编写测试用例
test_survey.py
1 import unittest #导入unittest 2 from survey import AnonymousSurvey #导入要测试的类 3 4 class TestAnonmyousSurvey(unittest.TestCase): 5 """ 针对 AnonymousSurvey 类的测试 """ 6 7 def test_store_single_response(self): 8 """ 测试单个答案会被妥善地存储 """ 9 question = "What language did you first learn to speak?" 10 my_survey = AnonymousSurvey(question) #创建实例 11 my_survey.store_response('English') #调用方法 store_response() 存储单个答案 English 12 13 self.assertIn('English', my_survey.responses) 14 15 def test_store_three_responses(self): 16 """ 测试三个答案会被妥善地存储 """ 17 question = "What language did you first learn to speak?" 18 my_survey = AnonymousSurvey(question) 19 responses = ['English', 'Spanish', 'Mandarin'] 20 for response in responses: 21 my_survey.store_response(response) 22 23 for response in responses: 24 self.assertIn(response, my_survey.responses) 25 26 unittest.main()
3.运行结果(测试通过)
1 .. 2 ---------------------------------------------------------------------- 3 Ran 2 tests in 0.000s 4 5 OK
1.方法 setUp()
如果在 TestCase 类中包含了方法 setUp() , Python 将先运行它,再运行各个以 test_ 打头的方法。
所以如果每个方法中都要创建同一个实例,那么直接在方法 setUp() 中创建这些对象,就可以在每个测试方法中使用它们。
1 import unittest 2 from survey import AnonymousSurvey 3 4 class TestAnonymousSurvey(unittest.TestCase): 5 """ 针对 AnonymousSurvey 类的测试 """ 6 7 def setUp(self): 8 """ 创建一个调查对象和一组答案,供使用的测试方法使用 """ 9 question = "What language did you first learn to speak?" 10 self.my_survey = AnonymousSurvey(question) #创建一个调查对象 11 self.responses = ['English', 'Spanish', 'Mandarin'] #创建一个答案列表 12 13 def test_store_single_response(self): 14 """ 测试单个答案会被妥善地存储 """ 15 self.my_survey.store_response(self.responses[0]) 16 self.assertIn(self.responses[0], self.my_survey.responses) 17 #存储这两样东西的变量名包含前缀 self (即存储在属性中),因此可在这个类的任何地方使用。 18 19 def test_store_three_responses(self): 20 """ 测试三个答案会被妥善地存储 """ 21 for response in self.responses: 22 self.my_survey.store_response(response) 23 for response in self.responses: 24 self.assertIn(response, self.my_survey.responses) 25 26 unittest.main() 27 28 #编写测试类时,可在 setUp() 方法中创建一系列实例并设置它们的属性,再在测试方法中直接使用这些实例。
2.运行结果分析
1 #运行测试用例时,每完成一个单元测试, Python 都打印一个字符: 2 3 ''' . 测试通过 4 E 测试引发错误 5 F 测试导致断言失败 '''
实例
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 """ 4 @desc: 测试126邮箱的登陆功能 5 1.使用公共方法public.login 6 2.将测试数据放在xml文件中,使用数据驱动(/test_data/login.xml) 7 3.这里使用xml.dom.minidom读取xml数据 8 """ 9 import unittest 10 import xml.dom.minidom 11 import os 12 import sys 13 from selenium import webdriver 14 15 cur_dir = os.getcwd() 16 sys.path.append(cur_dir.split(r'\test_case')[0]) 17 18 from public import login 19 20 fpath = cur_dir.split('test_case')[0] + 'test_data' + os.path.sep + 'login.xml' 21 22 # 打开 xml 文档 23 dom = xml.dom.minidom.parse(fpath) 24 25 # 得到文档元素对象 26 root = dom.documentElement 27 28 29 class TestLogin(unittest.TestCase): 30 def setUp(self): 31 self.driver = webdriver.Firefox() 32 self.driver.implicitly_wait(30) 33 logins = root.getElementsByTagName('url') 34 self.base_url = logins[0].firstChild.data 35 self.verificationErrors = [] 36 37 # 用例1:用户名、密码为空 38 def test_null(self): 39 driver = self.driver 40 driver.get(self.base_url) 41 # 读取xml中的数据 42 logins = root.getElementsByTagName('null') 43 # 获得 null 标签的 username、password 属性值 44 username = logins[0].getAttribute("username") 45 password = logins[0].getAttribute("password") 46 prompt_info = logins[0].firstChild.data 47 # 登录 48 login.login(self, username, password) 49 # 获取断言信息进行断言 50 text = driver.find_element_by_xpath("//div[@class='error-tt']/p").text 51 self.assertEqual(text, prompt_info) 52 53 # 用例2:用户名为空 54 def test_user_null(self): 55 driver = self.driver 56 driver.get(self.base_url) 57 logins = root.getElementsByTagName('user_null') 58 # 获得 user_null 标签的 username、passwrod 属性值 59 username = logins[0].getAttribute("username") 60 password = logins[0].getAttribute("password") 61 prompt_info = logins[0].firstChild.data 62 # 登录 63 login.login(self, username, password) 64 # 获取断言信息进行断言 65 text = driver.find_element_by_xpath("//div[@class='error-tt']/p").text 66 self.assertEqual(text, prompt_info) 67 68 # 用例3:密码为空 69 def test_pwd_null(self): 70 driver = self.driver 71 driver.get(self.base_url) 72 logins = root.getElementsByTagName('pwd_null') 73 # 获得 pwd_null 标签的 username、passwrod 属性值 74 username = logins[0].getAttribute("username") 75 password = logins[0].getAttribute("password") 76 prompt_info = logins[0].firstChild.data 77 # 登录 78 login.login(self, username, password) 79 # 获取断言信息进行断言 80 text = driver.find_element_by_xpath("//div[@class='error-tt']/p").text 81 self.assertEqual(text, prompt_info) 82 83 # 用例4:错误的用户名和密码 84 def test_error(self): 85 driver = self.driver 86 driver.get(self.base_url) 87 logins = root.getElementsByTagName('error') 88 # 获得 error 标签的 username、passwrod 属性值 89 username = logins[0].getAttribute("username") 90 password = logins[0].getAttribute("password") 91 prompt_info = logins[0].firstChild.data 92 # 登录 93 login.login(self, username, password) 94 # 获取断言信息进行断言 95 text = driver.find_element_by_xpath("//div[@class='error-tt']/p").text 96 self.assertEqual(text, prompt_info) 97 98 def tearDown(self): 99 self.driver.quit() 100 self.assertEqual([], self.verificationErrors) 101 102 103 if __name__ == "__main__": 104 unittest.main()
文章参考自:Python编程:从入门到实践.pdf
来源:https://www.cnblogs.com/longeryi/p/10444300.html