针对单个函数的测试
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