unitTest框架执行顺序
import unittest
'''
执行顺序:1.先执行setup,再执行测试用例,最后执行teardown
2.执行多少测试用例,setup和teardown就执行多少边
'''
class F1(unittest.TestCase):
def setUp(self):
print('执行setUp')
def tearDown(self):
print('执行teardown')
def test_01(self):
print('test01')
def test_02(self):
print('test02')
def test_03(self):
print('test03')
if __name__ == '__main__':
unittest.main(verbosity=2)
verbosity意义
0 代表得到执行的测试总数和全局结果
1 代表得到成功的显示,失败的显示
2 代表得到详细的信息
TestSuite套件
说明:(翻译:测试套件)多条测试用例集合在一起,就是一个TestSuite
使用:1. 实例化: suite = unittest.TestSuite() (suite:为TestSuite实例化的名称)
2. 添加用例:suite.addTest(ClassName(“MethodName”)) (ClassName:为类名;MethodName:为方法名)
3. 添加扩展:suite.addTest(unittest.makeSuite(ClassName)) (搜索指定ClassName内test开头的方法并添加到测试套件中)
例子:
#实例化
suite = unittest.TestSuite()
#添加用例
# suite.addTest(F1("test_01"))
# suite.addTest(F1("test_02"))
#扩展,添加测试类中所有的测试用例
# suite.addTest(unittest.makeSuite(F1))
#执行测试套件
# runner = unittest.TextTestRunner()
# runner.run(suite)
TextTestRunner
说明:TextTestRunner是用来执行测试用例和测试套件的 使用:
1. 实例化: runner = unittest.TextTestRunner()
2. 2. 执行: runner.run(suite) # suite:为测试套件名称
例子:
#实例化
suite = unittest.TestSuite()
#添加用例
# suite.addTest(F1("test_01"))
# suite.addTest(F1("test_02"))
#扩展,添加测试类中所有的测试用例
# suite.addTest(unittest.makeSuite(F1))
#执行测试套件
# runner = unittest.TextTestRunner()
# runner.run(suite)
TestLoader
说明:
用来加载TestCase到TestSuite中,即加载满足条件的测试用例,并把测试用例封装成测试套件。
使用unittest.TestLoader,通过该类下面的discover()方法自动搜索指定目录下指定开头的.py文件 ,
并将查找到的测试用例组装到测试套件;
用法:
suite = unittest.TestLoader().discover(test_dir, pattern=‘test*.py’)
自动搜索指定目录下指定开头的.py文件,并将查找到的测试用例组装到测试套件
test_dir: 为指定的测试用例的目录
pattern:为查找的.py文件的格式,默认为’test*.py’
也可以使用unittest.defaultTestLoader 代替 unittest.TestLoader()
运行:
runner = unittest.TextTestRunner() runner.run(suite)
import unittest
#指定已test开头的测试用例
#suit = unittest.TestLoader().discover("../case")
#扩展,指定已tpshop开头的用例
suit = unittest.TestLoader().discover("../case",pattern="tpshop*.py")
#扩展defaultTestLoader等价于TestLoader(),底层调用的都是TestLoader()
suit = unittest.defaultTestLoader.discover("../case")
unittest.TextTestRunner().run(suit)
Fixture
Fixture控制级别:
- 方法级别
1). 初始化(前置处理): def setUp(self) --> 首先自动执行
2). 销毁(后置处理): def tearDown(self) --> 最后自动执行
3). 运行于测试方法的始末,即:运行一次测试方法就会运行一次setUp和tearDown - 类级别
1). 初始化(前置处理): @classmethod def setUpClass(cls): --> 首先自动执行
2). 销毁(后置处理): @classmethod def tearDownClass(cls): --> 最后自动执行
3). 运行于测试类的始末,即:每个测试类只会运行一次setUpClass和tearDownClass - 模块级别
1). 初始化(前置处理): def setUpModule() --> 首先自动执行
2). 销毁(后置处理): def tearDownModule() --> 最后自动执行
3). 运行于整个模块的始末,即:整个模块只会运行一次setUpModule和tearDownModule
例子
import unittest
#Fixture控制级别: 1. 方法级别 2. 类级别 3. 模块级别
class F1(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("setUpClass")
@classmethod
def tearDownClass(cls):
print("tearDownClass")
def setUp(self):
print('执行setUp')
def tearDown(self):
print('执行teardown')
def test_01(self):
print('test01')
def test_02(self):
print('test02')
def test_03(self):
print('test03')
def test_04(self):
print('test04')
if __name__ == '__main__':
unittest.main(verbosity=2)
断言
1.assertTrue(expr, msg=None) 验证expr是true,如果为false,则fail
2 assertFalse(expr, msg=None) 验证expr是false,如果为true,则fail
3 assertEqual(expected, actual, msg=None) 验证expected==actual,不等则fail 【掌 握】
4 assertNotEqual(first, second, msg=None) 验证first != second, 相等则fail
5 assertIsNone(obj, msg=None) 验证obj是None,不是则fail
6 assertIsNotNone(obj, msg=None) 验证obj不是None,是则fail
7 assertIn(member, container, msg=None) 验证是否member in container【掌握】
8 assertNotIn(member, container, msg=None) 验证是否member not in container
例子:
import unittest
class F1(unittest.TestCase):
def test_03(self):
# flag = True
#flag = False
# self.assertTrue(flag)
#self.assertFalse(flag)
#判断两个字符是否相等
#self.assertEqual("你好,斑马","你好,奥马")
#self.assertEqual("你好,斑马", "你好,斑马")
#判断后边的字符串是否包含前边的字符串
#self.assertIn("hellow bana","hellow banaa")
#self.assertIn("hellow bana", "hellow bana wah")
#判断是否为none
#flag = None
#self.assertIsNone(flag)
#self.assertIsNotNone(flag)
例子
import time import unittest from selenium import webdriver class TestLogin(unittest.TestCase): def setUp(self): self.driver = webdriver.Firefox() self.driver.get("http://localhost") self.driver.implicitly_wait(10) self.driver.maximize_window() def test_login(self): # 点击登录按钮 self.driver.find_element_by_link_text("登录").click() # 输入用户名 self.driver.find_element_by_id("username").send_keys("13012345678") # 输入密码 self.driver.find_element_by_id("password").send_keys("123456") # 点击登录按钮 self.driver.find_element_by_css_selector("[name='sbtbutton']").click() # 获取错误提示信息 msg = self.driver.find_element_by_css_selector(".layui-layer-content").text print("msg=", msg) try:# 断言 self.assertIn("验证码不能为空", msg) except AssertionError as e: # 保存截图 img_path = "./imgs/img{}.png".format(time.strftime("%Y%m%d-%H%M%S")) self.driver.get_screenshot_as_file(img_path) raise e
参数化
pip install parameterized
导包:from parameterized import parameterized 使用@parameterized.expand装饰器可以为测试函数的参数进行参数化
import unittest from parameterized
import parameterized
# 求和
def add(x, y):
return x + y
# 构建测试数据
def build_data():
return [(1, 1, 2), (1, 0, 1), (0, 0, 0)]
class TestAdd(unittest.TestCase):
@parameterized.expand([(1, 1, 2), (1, 0, 1), (0, 0, 0)])
def test_add_1(self, x, y, expect):
print("x={} y={} expect={}".format(x, y, expect))
result = add(x, y)
self.assertEqual(result, expect)
data = [(1, 1, 2), (1, 0, 1), (0, 0, 0)]
@parameterized.expand(data)
def test_add_2(self, x, y, expect):
print("x={} y={} expect={}".format(x, y, expect))
result = add(x, y)
self.assertEqual(result, expect)
@parameterized.expand(build_data)
def test_add_3(self, x, y, expect):
print("x={} y={} expect={}".format(x, y, expect))
result = add(x, y) self.assertEqual(result, expect)
跳过用例
# 直接将测试函数标记成跳过
@unittest.skip('代码未完成')
# 根据条件判断测试函数是否跳过
@unittest.skipIf(condition, reason)
import unittest
version = 30
class Test_Skip(unittest.TestCase):
# @unittest.skip("方法暂未实现")
def test_01(self):
print('zheshi01')
@unittest.skipIf(version>25,"新版本大于25跳过")
def test_02(self):
print('zheshi02')
HTMLTestRunner【重点】
实现:
- 复制HTMLTestRunner.py文件到项目文件夹
- 导入HTMLTestRunner、unittest包
- 生成测试套件 suite = unittest.TestSuite() suite.addTest(TestLogin(“test_login”)) suite = unittest.defaultTestLoader.discover(test_dir, pattern=“test*.py”)
- 设置报告生成路径和文件名 file_name = “./report/report.html”
- 打开报告 with open(file_name,‘wb’) as f:
- 实例化HTMLTestRunner对象:
runner = HTMLTestRunner(stream=f,[title],[description])
参数说明:
stream:文件流,打开写入报告的名称及写入编码格式)
title:[可选参数],为报告标题,如XXX自动化测试报告
description:[可选参数],为报告描述信息;比如操作系统、浏览器等版本 7. 执行:runner.run(suite)
例子:
import unittest
import time
from TEST002.HTMLTestRunner import HTMLTestRunner
suit = unittest.defaultTestLoader.discover("../case",pattern="test*.py")
report_dir = "../report/{}.html".format(time.strftime("%Y_%m_%d %H_%M_%S"))
with open(report_dir,'wb')as f:
HTMLTestRunner(stream=f,verbosity=2,title="XX项目测试报告",description="操作系统win7").run(suit)