selenium + python + unitTest 介绍
好与不好希望能帮忙点一赞,谢谢了!
unitTest简介
Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作。
在说unittest之前,先说几个概念:
TestCase :测试用例,python中的一个继承了unittest.TestCase的class。
TestSuite :多个测试用例集合在一起,就是TestSuite
TestLoader :是用来加载TestCase到TestSuite中的
TestRunner :是来执行测试用例的,测试的结果会保存到TestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息
unitTest 之 HelloWord
继承unittest.TestCase,这是一个测试用例
import unittest
class MyTest(unittest.TestCase):
def setUp(self):
print('每个测试用例执行之前做操作')
def tearDown(self):
print('每个测试用例执行之后做操作')
# 必须使用 @classmethod 装饰器, 所有test运行完后运行一次
@classmethod
def tearDownClass(cls):
print('所有test运行完后运行一次')
# 必须使用@classmethod 装饰器,所有test运行前运行一次
@classmethod
def setUpClass(cls):
print('所有test运行前运行一次')
# 测试用例
def test_a_run(self):
print("test_a_run runing...")
# TODO TEST CASE CODE
self.assertEqual(1, 1)
def test_b_run(self):
print("test_b_run runing...")
# TODO TEST CASE CODE
# 断言方法,还有很多,先用着,一会介绍。
self.assertEqual(2, 2) # 测试用例
if __name__ == '__main__':
# 运行所有的测试用例
unittest.main()
函数测意思都在代码里了,需要注意的是 setUp tearDown ,setUpClass ,tearDownClass 这四个函数名称不能随便写,只能是这几个名字。
其中setUpClass ,tearDownClass 函数必须使用@classmethod注解
测试用例函数,必须以test开头,执行顺序以函数名称的字典排序一致。
生成测试用例执行报表
HTMLTestRunner
这是一个.py 文件,下载完成后放到工程文件夹里就好了
下载地址:
链接:https://pan.baidu.com/s/1CKlhx6Q11MTrHkMBQLcTfg
提取码:bcs8
代码:符加注释:
if __name__ == '__main__':
test_suite = unittest.TestSuite() # 创建一个测试集合
test_suite.addTest(unittest.makeSuite(MyTest)) #使用makeSuite方法添加所有的测试方法
fp = open('D:\\res3.html', 'wb') # 打开一个保存结果的html文件
# 生成执行用例的对象
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='api测试报告', description='测试情况')
runner.run(test_suite) # 执行测试套件
quit(0) # 退出系统
Xmlrunner
这是一个python 插件,安装方法: pip install xmlrunner
代码:符加注释:
if __name__ == '__main__':
test_suite = unittest.TestSuite() # 创建一个测试集合
test_suite.addTest(unittest.makeSuite(MyTest)) #使用makeSuite方法添加所有的测试方法
# 生成执行用例的对象
runner = xmlrunner.XMLTestRunner(output='D:\\')#指定报告放的目录
runner.run(test_suite)
quit(0) # 退出系统
测试报告不就是要看着方便吗,HTMLTestRunner 输出的已经很不错了,各种情况一目了然。
多个测试用例集合执行
第一步:新建多个文件
# Test_1.py
import unittest
class MyTest1(unittest.TestCase):
def setUp(self):
print('MyTest1每个测试用例执行之前做操作')
def tearDown(self):
print('MyTest1每个测试用例执行之后做操作')
@classmethod
def tearDownClass(cls):
print('MyTest1所有test运行完后运行一次')
@classmethod
def setUpClass(cls):
print('MyTest1所有test运行前运行一次')
def test_a_run(self):
print("test_a_run runing...")
def test_b_run(self):
print("test_b_run runing...")
def test_c_run(self):
print("test_c_run runing...")
# Test_2.py
import unittest
class MyTest1(unittest.TestCase):
def setUp(self):
print('MyTest1每个测试用例执行之前做操作')
def tearDown(self):
print('MyTest1每个测试用例执行之后做操作')
@classmethod
def tearDownClass(cls):
print('MyTest1所有test运行完后运行一次')
@classmethod
def setUpClass(cls):
print('MyTest1所有test运行前运行一次')
def test_d_run(self):
print("test_d_run runing...")
def test_e_run(self):
print("test_e_run runing...")
def test_f_run(self):
print("test_f_run runing...")
# run.py
import unittest
import HTMLTestRunner
if __name__ == '__main__':
suite = unittest.TestSuite() # 创建测试套件
# 找到某个目录下所有的以test开头的Python文件里面的测试用例
all_cases = unittest.defaultTestLoader.discover('.', 'test_*.py')
for case in all_cases:
suite.addTests(case) # 把所有的测试用例添加进来
fp = open('D:\\resall.html', 'wb')
runner = HTMLTestRunner.HTMLTestRunner(stream=fp, title='all_tests', description='所有测试情况')
runner.run(suite)
运行run.py 结果
unitTest 函数依赖处理
什么是依赖:
就是case1 没有执行,case2…case3…caseN 都不执行。
这么说有点笼统了,打个比方吧,case1是注册用户,case2是登录用户,case3 是登录后查看个人信息。那么case1注册的时候失败了,我们还有必要执行case2登录吗?更不用说后面的case了,就算是执行了,给出的异常也是NoSuchElementException的异常,完全没有必要,看着还不方便,影响整体美观。
解决方法代码:
unitTest 没有处理依赖关系装饰器,只能自己写个装饰器来冒充一下。每行代码的意思都在注释里了,不解释了!
def dependon(depend=None): # 定义一个 装饰器 参数 被依赖的函数名称
def wraper_func(test_func): # 默认传参:被修饰的函数
@functools.wraps(test_func)
def inner_func(self): # 判断函数
if depend == test_func.__name__: # 判断依赖的函数,是否和自身是否是一个函数
raise ValueError("{} cannot depend on itself".format(depend))
failures = str([fail[0] for fail in self._outcome.result.failures]) # 获得所有断言失败的函数
errors = str([error[0] for error in self._outcome.result.errors]) # 获得所有发生错误的函数
skipped = str([error[0] for error in self._outcome.result.skipped])# 获得所有已经跳过的函数
flag = (depend in failures) or (depend in errors) or (depend in skipped) # 判断依赖的函数是否在发生错误的函数中
test = unittest.skipIf(flag, 'Skip because def:{} is not running'.format(depend))(test_func) #交给unittest.skipIf函数处理
return test(self) # 返回 unittest.skipIf 处理结果
return inner_func # 返回 inner_func 处理结果
return wraper_func # 返回 wraper_func 处理结果
依赖用法:
def test_a_run(self):
print("test_a_run runing...")
# TODO TEST CASE CODE
self.assertEqual(1, 1)
@dependon("test_a_run")
def test_b_run(self):
print("test_b_run runing...")
# TODO TEST CASE CODE
# 断言方法,还有很多,先用着,一会介绍。
self.assertEqual(2, 2) # 测试用例
在需要依赖的方法上面 加上@dependon(“被依赖方法名称”)就OK了。很简单的。但是只能依赖一个函数。总比没有强。
好与不好希望能帮忙点一赞,谢谢了!