python自动化测试框架——unittest、pytest
Unittest由4部分组成TestFixture(测试固件)、TestCase(测试用例)、TestSuite(测试套件)、 TestRunner(测试执行)
命名规范:
-
测试类:类名必须以Test开头(如TestMath),否则默认的测试发现机制(discover)可能无法识别。
-
测试方法:方法名必须以test_开头(如test_add),否则不会被自动加载。
-
非测试方法:非测试方法(如辅助函数)不应以test_开头。
-
测试模块: 以test_xx.py开头或xx_test.py结尾
一、TestFixture 测试固件
用于测试用例执行前作准备和测试用例执行后做清理工作
setUp(): 测试用例执行前的准备工作,执行每个测试用例的前置条件
tearDown(): 测试用例执行后的善后工作,执行每个测试用例的后置条件
setUpClass(): 结合@classmethod 装饰器一起使用,所有测试用例的前置条件
tearDownClass(): 结合@classmethod 装饰器一起使用,所有测试用例的后置条件
方法执行顺序: setupClass -> setup ->test_02 -> teardown -> setup -> test_03 -> teardown -> teardownClass
import unittest
# 单元测试框架unittest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
class MyTestCase(unittest.TestCase):
# 类方法只执行一次
@classmethod
def setUpClass(cls) -> None:
# cls 指当前类对象MyTestCase
# 这里可以初始化WebDriver实例
print('setupClass')
@classmethod
def tearDownClass(cls) -> None:
# 这里可以添加退出浏览器
print('tearDownClass')
# 执行测试用例之前做的
def setUp(self) -> None:
print('setup...')
# 执行测试用例之后做的
def tearDown(self) -> None:
print('teardown...')
if __name__ == '__main__':
# 方法执行顺序: setupClass -> setup ->test_02 -> teardown -> setup -> test_03 -> teardown -> teardownClass
unittest.main()
二、TestCase 测试用例
1.继承unittest.TestCase的测试类的方法名必须要以test开头才能被执行
2.每个测试用例都会执行setup(),teardown()方法
3.测试用例方法执行顺序: 0~9,A~Z,ASCll码字母
import unittest
# 单元测试框架unittest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
class MyTestCase(unittest.TestCase):
# 类方法只执行一次
@classmethod
def setUpClass(cls) -> None:
# cls 指当前类对象MyTestCase
# 这里可以初始化WebDriver实例
print('setupClass')
@classmethod
def tearDownClass(cls) -> None:
# 这里可以添加退出浏览器
print('tearDownClass')
# 执行测试用例之前做的
def setUp(self) -> None:
print('setup...')
def test_03(self):
print('test_03')
# 断言方法:等于
self.assertEqual(1 + 2, 3)
# 每个测试用例都会执行setup,teardown方法
def test_02(self):
print('test_02')
# 断言方法:大于等于
self.assertGreaterEqual(5, 4)
# 继承unittest.TestCase的测试类的方法名必须要以test开头才能被执行
def aaa(self):
print('aaa')
# 执行测试用例之后做的
def tearDown(self) -> None:
print('teardown...')
if __name__ == '__main__':
# 方法执行顺序: setupClass -> setup ->test_02 -> teardown -> setup -> test_03 -> teardown -> teardownClass
# 测试用例方法执行: 0~9,A~Z,ASCll码字母
unittest.main()
5.断言Assert(Unittest提供的断言)
| assertEqual(a,b) | 判断a等于b |
| assertNotEqual(a,b) | 判断a不等于b |
| assertIs(a,b) | 判断a是b |
| assertIsNot(a,b) | 判断a不是b |
| assertIsNone(a) | 判断a是None |
| assertIsNotNone(a) | 判断a不是None |
| assertIn(a,b) | 判断a在b中,包含相等 |
| assertNotIn(a,b) | 判断a不在b中 |
| assertGreater(a,b) | 判断a大于b |
| assertGreaterEqual(a,b) | 判断a大于等于b |
| assertLess(a,b) | 判断a小于b |
| assertLessEqual(a,b) | 判断a小于等于b |
三、TestSuit 测试套件
import unittest
class TestSuit(unittest.TestCase):
def test_1(self):
print('test1')
def test_2(self):
print('test2')
def test_3(self):
print('test3')
TestSuite可以组织多个测试用例,也可以将多个测试套件组织在一起
1.TestSuite 直接构建测试集
map(function,iterable,...) 第一个参数function表示以参数序列中的每一个元素调用function函数,返回包含每次function函数返回值的新列表,这样讲可能有点官方不好理解,换个讲法->
map()函数会对可迭代对象(iterable)中的每个元素应用指定的函数(function):
funtion: 一个接受参数的函数(或可调用对象,这里使用的是测试类对象TestSuit)
iterable:一个可迭代对象(如列表、元组,这里使用的是['test_3','test_1'])
TestSuit在被调用时,可以通过传递方法名来创建特定测试方法的实例。
if __name__ == '__main__':
# 构造测试集
suit = unittest.TestSuite(map(TestSuit,['test_3','test_1']))
# 等效于:
test_cases = [TestSuit('test_3'), TestSuit('test_1')]
suit = unittest.TestSuite(test_cases)
# 测试执行
unittest.TextTestRunner().run(suit)
2.addTest() 构建测试集
if __name__ == '__main__':
# 构造测试集
suit = unittest.TestSuite()
# 一次只能添加一个测试用例
suit.addTest(TestSuit('test_1'))
suit.addTest(TestSuit('test_3'))
# 执行测试用例
unittest.TextTestRunner().run(suit)
3.addTests() 构建测试集
将测试用例添加进测试集,与addTest()方法不同的是,addTests()允许一次添加多条测试用例
if __name__ == '__main__':
# 构造测试集
suit = unittest.TestSuite()
# 如果这里提供测试类没有的测试方法,将会报AttributeError
suit.addTests(map(TestSuit,['test_1','test_3']))
# 执行测试用例
unittest.TextTestRunner().run(suit)
四、TestLoader 测试加载
将测试用例TestCase添加到测试套件TestSuit中
1.unittest.TestLoader().loadTestsFromTestCase(testCaseClass) 返回测试类中所包含的所有测试用例的套件
import unittest
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 1, 2)
def test_sub(self):
self.assertEqual(3 - 1, 2)
if __name__ == '__main__':
# 加载 TestMath 类中的所有测试方法
suite = unittest.TestLoader().loadTestsFromTestCase(TestMath)
unittest.TextTestRunner().run(suite)
2.unittest.TestLoader().loadTestsFromModule(module) 返回给定模块中所包含的所有测试用例的套件
# 文件: test_math.py
import unittest
class TestMath(unittest.TestCase):
def test_add(self):
self.assertEqual(1 + 1, 2)
class TestString(unittest.TestCase):
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
if __name__ == '__main__':
# 加载模块中的所有测试类
suite = unittest.TestLoader().loadTestsFromModule(test_math) # 假设模块已导入
unittest.TextTestRunner().run(suite)
3.unittest.TestLoader().loadTestsFromName(name,module=None) 返回一组给定字符串说明符的所有测试用例,名称可以为模块、测试用例类、测试用例类中的测试方法,或其中可调用的对象,返回一个TestCase或TestSuite实例
if __name__ == '__main__':
# 加载特定测试方法
suite = unittest.TestLoader().loadTestsFromName('TestMath.test_add', module=test_math)
unittest.TextTestRunner().run(suite)
4.unittest.TestLoader().loadTestsFromNames(names,module=None) 返回使用给定序列找到的所有测试用例的套件说明符的字符串
if __name__ == '__main__':
# 加载多个测试方法或类
names = ['TestMath.test_add', 'TestString.test_upper']
suite = unittest.TestLoader().loadTestsFromNames(names, module=test_math)
unittest.TextTestRunner().run(suite)
5.unittest.TestLoader().getTestCaseNames(testCaseclass) 返回在testCaseclass中找到的方法名的排序序列
class TestMath(unittest.TestCase):
def test_add(self): pass
def test_sub(self): pass
def helper(self): pass # 不会被识别为测试方法
names = unittest.TestLoader().getTestCaseNames(TestMath)
print(names) # 输出: ['test_add', 'test_sub']
6.unittest.TestLoader().discover(start_dir,pattern='test*.py',top_level_dir=None) 从 Python文件中获取测试用例,递归扫描目录,自动发现所有匹配pattern的测试文件
if __name__ == '__main__':
unittest.TestLoader().discover(start_dir='./', pattern="test*.py")
unittest.TextTestRunner().run(discover)
五、TestRunner 测试运行
verbosity 用来控制输出错误报告的详细程度,有3个等级:
0: 只显示全局执行结果和执行结果中用例的总数
1:默认值,显示全局执行结果和执行结果中用例的总数,并且对每一条用例的执行结果都有标注
2:显示全局执行结果和执行结果中用例的总数,并输出每一个用例的详细结果
if __name__ == '__main__':
unittest.TestLoader().discover(start_dir='./', pattern="test*.py")
unittest.TextTestRunner(verbosity=2).run(discover)
六、skip装饰器
1.@unittest.skip(reason): 无条件跳过,reason可用来描述跳过的原因
2.@unittest.skipIf(condition,reason): 有条件跳过,当condition条件满足时跳过该条测试用例
3.@unittest.skipUnless(condition,reason): 有条件跳过,当condition条件不满足时跳过该条测试用例
4.@unittest.expectedFailure 用于标记期望执行失败的测试方法,如果该测试方法执行失败,则被认为成功,如果执行成功,则认为失败
不想营造篇幅太长,想了解pytest框架,点击下方连接
python自动化测试框架——pytest
https://blog.csdn.net/lrk__/article/details/149903366?sharetype=blogdetail&sharerId=149903366&sharerefer=PC&sharesource=lrk__&spm=1011.2480.3001.8118
更多推荐


所有评论(0)