unittest框架的基本使用
unittest框架的基本使用
测试用例 Case
unittest.TestCase类
通过继承unittest.TestCase进行编写,继承unittest.TestCase的类会被框架识别为测试用例。
# 导入unittest模块
import unittest
# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
def test_001(self):
print('001')
if __name__ == '__main__':
unittest.main()
运行结果中,001被打印,因为调用了 Test1 类中的test_001方法,
类 Test1 继承 TestCase类,是 TestCase类的子类
unittest.main()
- unittest.main()是最简单的测试执行方式
# 导入unittest模块
import unittest
# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
def test_001(self):
print('001')
def test_002(self):
print('002')
if __name__ == '__main__':
unittest.main()
运行结果
- 调用unittest.main()方法后,继承自unittest.TestCase类的类会被自动识别为测试用例并且被调用。
# 导入unittest模块
import unittest
# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
def test_001(self):
print('001')
def test_002(self):
print('002')
class Test2(unittest.TestCase):
def test_001(self):
print('201')
def test_002(self):
print('202')
if __name__ == '__main__':
unittest.main()
类Test1 和类Test2 中的方法都被调用了
setUp、TearDown
setUp和TearDown是用于事前和事后做相关处理动作的,就是前面说的Test Fixture,会在每个测试用例运行前后被框架自动调用
# 导入unittest模块
import unittest
# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
def setUp(self):
print('hello')
def tearDown(self):
print('bye')
def test_001(self):
print('001')
def test_002(self):
print('002')
if __name__ == '__main__':
unittest.main()
运行结果如下图所示,每调用一次 test 方法前,都会先调用 setUp方法(测试前准备的环境的搭建),执行完 test 方法后,调用了TearDown方法(测试后环境的还原)
setUp()用于初始化一些参数,在测试用例执行前自动被调用,tearDown()用于清理,在测试用例执行后被调用
test方法
所有以test开头的方法会被框架自动识别为测试用例,并自动调用执行,不是以test开头的不会被调用
# 导入unittest模块
import unittest
# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
def test_001(self):
print('001')
def test_002(self):
print('002')
def mytest_003(self):
print('003')
if __name__ == '__main__':
unittest.main()
运行结果中,003没有被打印,因为 方法 mytest_003 不是以 test 开头
注意:若鼠标光标位于指定函数后,点击运行,则默认只调用了一条函数
测试套件 suit
一般测试用例都会放到一个文件夹下,例如这里将注册和登录的测试用例放到 testCase文件夹 下
test_register.py
import unittest
import requests
register_url = 'http://127.0.0.1:8000/axf/register/'
headers ={"Content-Type":"application/json","token":"BAIDUID=2E929BA0197B330B0CBC2F4706F85F50"}
success_data = {"mobile_phone":"17379745548","pwd":"12345678"}
fail_data = {"mobile_phone":"sm17379745548","pwd":"12345678"}
def visit( url,params=None, data=None, json=None, **kwargs):
res = requests.post(url,json=data,headers=headers)
return res.json()
class TestRegister(unittest.TestCase):
def setUp(self):
print('start')
def tearDown(self):
print('bye')
def test_register_success(self):
res =visit(url=register_url,data=success_data,headers=headers)
self.assertEqual(res,'register success')
def test_register_fail(self):
res =visit(url=register_url,data=fail_data,headers=headers)
self.assertEqual(res,'register fail')
if __name__ == '__main__':
unittest.main()
test_login.py
import unittest
import requests
login_url = 'http://127.0.0.1:8000/axf/login/'
headers ={"Content-Type":"application/json","token":"BAIDUID=2E929BA0197B330B0CBC2F4706F85F50"}
success_data = {"mobile_phone":"17379745548","pwd":"12345678"}
fail_data = {"mobile_phone":"17379745548","pwd":"123456789"}
def visit( url,params=None, data=None, json=None, **kwargs):
res = requests.post(url,json=data,headers=headers)
return res.json()
class TestLogin(unittest.TestCase):
def setUp(self):
print('start')
def tearDown(self):
print('bye')
def test_login_success(self):
res =visit(url=login_url,data=success_data,headers=headers)
self.assertEqual(res,'login success')
def test_login_fail(self):
res =visit(url=login_url,data=fail_data,headers=headers)
self.assertEqual(res,'login fail')
if __name__ == '__main__':
unittest.main()
加载器 Loader
收集测试用例:TestLoader
加载器,加载测试用例
放到测试集合(测试套件)TestSuit
- 1、初始化 TestLoader
- 2、查找测试用例,加载
unittest.TestLoader.discover()
run_test.py
import os
import unittest
# 1、初始化 TestLoader
testloader = unittest.TestLoader()
# 2、查找测试用例,加载
# 当前文件路径
dir_path = os.path.dirname(os.path.abspath(__file__))
# 测试测试集合(测试套件)文件所在路径
case_path = os.path.join(dir_path,'testCase')
# 测试集合
suit = testloader.discover(case_path)
'''
.discover(path,demo*.py)
在path 路径下查找测试用例,若用例文件不是以test开头,需通过正则方式匹配指定的文件名称
'''
'''
# print(suit)
打印结果
<unittest.suite.TestSuite tests=
[<
unittest.suite.TestSuite tests=
[< unittest.suite.TestSuite tests=
[<test_login.TestLogin testMethod=test_login_fail>, <test_login.TestLogin testMethod=test_login_success>]>]>,
< unittest.suite.TestSuite tests=
[< unittest.suite.TestSuite tests=
[<test_regster.TestLogin testMethod=test_register_fail>, <test_regster.TestLogin testMethod=test_register_success>]>]
>]
>
可以发现,加载了四个测试用例 test_login_fail,test_login_success,test_register_fail,test_register_success
都是以test 开头
'''
unittest.TestLoader.loadTestsFromModule()
上面的方式是加载所有以 test开头的py文件里的测试用例,如果只想加载某个py文件、或者几个py文件,还可通过以下方式,指定某些模块放到测试套件中,再进行加载
import os
import unittest
from class_unittest.testCase import test_login, test_regster
# 1、初始化 TestLoader
testloader = unittest.TestLoader()
# 2、查找测试用例,加载
suit_login = testloader.loadTestsFromModule(test_login)
suit_regster = testloader.loadTestsFromModule(test_regster)
suit_total = unittest.TestSuite()
suit_total.addTests(suit_login)
suit_total.addTests(suit_regster)
此时,suit_total里的内容是和 suit里的一样的
unittest.TestLoader.loadTestsFromTestCase()
同样,除了指定模块,还能指定py文件里的测试类
import os
import unittest
from class_unittest.testCase.test_login import TestLogin
from class_unittest.testCase.test_regster import TestRegister
# 1、初始化 TestLoader
testloader = unittest.TestLoader()
# 2、查找测试用例,加载
suit_class_login = testloader.loadTestsFromTestCase(TestLogin)
suit_class_regster = testloader.loadTestsFromTestCase(TestRegister)
suit_total = unittest.TestSuite()
suit_total.addTests(suit_class_login )
suit_total.addTests(suit_class_regster )
运行器
unittest.TextTestRunner()
run_test.py
import os
import unittest
# 1、初始化 TestLoader
testloader = unittest.TestLoader()
# 2、查找测试用例,加载
# 当前文件路径
dir_path = os.path.dirname(os.path.abspath(__file__))
# 测试测试集合(测试套件)文件所在路径
case_path = os.path.join(dir_path,'testCase')
# 测试集合
suit = testloader.discover(case_path)
# 运行测试用例且生成测试报告
# 测试报告路径
report_path = os.path.join(dir_path,'report')
if not os.path.exists(report_path):
os.mkdir(report_path)
# 测试报告文件路径
file_path = os.path.join(report_path,'test_report.txt')
with open(file_path,"w",encoding="utf-8") as f:
# 初始化运行器,是以普通文本生成测试报告
runner = unittest.TextTestRunner(f,verbosity=2)
# 运行测试用例
runner.run(suit)
只需要执行run.py 文件,即可执行所有测试用例并生成测试报告
verbosity=2 作用是测试报告的等级为2
txt文件中的内容,是这样的
test_login_fail (test_login.TestLogin) ... ok
test_login_success (test_login.TestLogin) ... ok
test_register_fail (test_regster.TestLogin) ... ok
test_register_success (test_regster.TestLogin) ... ok
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
如果verbosity=1,txt文件中的内容,是这样的
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
4个点表示都通过,这种自带的测试报告的内容,太low了
所以,为了使生成的测试报告更高级一点,通常采用 HMTLTestRunner 生成测试报告
HMTLTestRunner
HMTLTestRunner 不是 unittest 框架自带的,需要自己去下载安装,而且安装的方式也不是通过 pip 命令安装
HMTLTestRunner 是一个别人写好的模块,它的本质是一个 py文件
通常我们在写自动化测试框架的时候,都是直接将这个py文件放到项目文件夹下,然后调用这个py文件
当然,如果嫌弃这种方式麻烦,不想每次写一个自动化测试框架都复制该文件,也可以将改文件放到python安装目录下的lib目录或者site-packages目录下,采用放到公共库中的方式
而相关的代码,其实思路是和 unittest.TextTestRunner() 生成文本格式的测试报告是一样的
run_test.py
import os
import unittest
# 调用 HTMLTestRunnerNew.py 文件中 HTMLTestRunner
from class_unittest.HTMLTestRunnerNew import HTMLTestRunner
# 1、初始化 TestLoader
testloader = unittest.TestLoader()
# 2、查找测试用例,加载
# 当前文件路径
dir_path = os.path.dirname(os.path.abspath(__file__))
# 测试测试集合(测试套件)文件所在路径
case_path = os.path.join(dir_path,'testCase')
# 测试集合
suit = testloader.discover(case_path)
# 运行测试用例且生成测试报告
# 测试报告路径
report_path = os.path.join(dir_path,'report')
if not os.path.exists(report_path):
os.mkdir(report_path)
# html格式测试报告文件路径
file_path = os.path.join(report_path,'test_report.html')
# HTMLTestRunner是通过二进制编码格式读写的,所以这里方式为 "wb"
with open(file_path,"wb") as f:
# 初始化运行器,是以普通文本生成测试报告
runner = HTMLTestRunner(f)
# 运行测试用例
runner.run(suit)
运行之后,生成了test_report.html文件,打开该文件,查看html格式的测试报告内容
按住 Ctrl ,鼠标点击 HTMLTestRunner,查看 HTMLTestRunnerNew.py 文件中源码内容
这里可以去更改一些参数内容,比如 title指的是测试报告的标题,description是指测试报告的描述,tester是指测试的测试人员
with open(file_path,"wb") as f:
# 初始化运行器,是以普通文本生成测试报告
runner = HTMLTestRunner(f,title='简单的html测试报告',description='这个一个html格式的测试报告',tester='bobo')
# 运行测试用例
runner.run(suit)