unittest 测试函数、测试类

别说谁变了你拦得住时间么 提交于 2020-01-27 22:07:44

针对单个函数的测试

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

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!