单元测试 unittest
接口测试的本质:就是测试类里面的函数,通过数据驱动
单元测试的本质:测试函数,代码级别,通过代码级别测试
单元测试的框架:unittest+接口 pytest +web-->接口
pytest+jenjins +allure
测试步骤
1:写用例 TestCase
2:执行用例 1) TestSuite 存储用例 2)TestLoader 找用例,加载用例,顾虑到TestSuite
3:对比实际结果和期望结果 判定用例是否通过 #断言Assert
4:出具测试报告 TextTestRunner
写一个测试类,对calc_class.py文件中 MathMethod模块和DivMethod模块里的类,进行单元测试。calc_class.py如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 16:11
# @File : calc_class.py
class MathMethod:
def __init__(self, a, b):
self.a = a
self.b = b
# 加法
def add(self):
return self.a + self.b
# 乘法
def multi(self):
return self.a + self.b
class DivMethod:
def __init__(self, a, b):
self.a = a
self.b = b
# 除法
def div(self):
return self.a/ self.b
1、继承了unittest里边的TestCase专门用来写用例
1)一个用例就是一个函数,不能传参,只有self关健字
2)所有的用例( 所有的函数 都是test开头,test_ )
3)unittest执行顺序是按Ascci码排序运算
test_class.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 16:20
# @Site :
# @File : test_class.py
import unittest
from calc_class import MathMethod,DivMethod
# 写一个测试类,对写的math method模块里的类,进行单元测试
# 继承了unittest里边的TestCase专门用来写用例
class TestMathMethod(unittest.TestCase):
# 1:一个用例就是一个函数,不能传参,只有self关健字
# 2:所有的用例(所有的函数 都是test开头,test_)
def test_add_two_positive(self):
res = MathMethod(1, 1).add()
print("1+1相加的结果是", res)
self.assertEqual(3, res, "两数相加出错了")
def test_add_two_negative(self):
res = MathMethod(-1, -2).add()
print("-1和-2相加的结果是", res)
self.assertEqual(-3, res, "两数相加出错了")
class TestDivMethod(unittest.TestCase):
def test_div_two_positive(self):
res = DivMethod(2, 1).div()
print("2除以1是", res)
self.assertEqual(2, res, "两数相除出错了")
if __name__ == '__main__':
unittest.main()
2、suite = unittest.TestSuite()#存储用例
方法一:一条一条用例的添加, 下边的例子只添加了一个用例:验证两个正数相加 suite.addTest suite.addTest(TestMathMethod('test_add_two_positive'))
import unittest
from test_class import TestMathMethod
suite = unittest.TestSuite()#存储用例
# 方法一:只执行一条用例,两个正数相加
# suite.addTest
suite.addTest(TestMathMethod('test_add_two_positive'))
# 执行
runner = unittest.TextTestRunner()
runner.run(suite)
方法二:TestLoader 创建一个加载器 loader = unittest.TestLoader() #创建一个加载器 1)suite.addTest(loader.loadTestsFromTestCase(TestMathMethod)) #从测试类中的用例去寻找,将测试类TestMathMethod中的方法全部添加至suite中
import unittest
from test_class import TestMathMethod
suite = unittest.TestSuite()#存储用例
# 方法一:只执行一条用例,两个正数相加
# suite.addTest
# suite.addTest(TestMathMethod('test_add_two_positive'))
# 方法二:TestLoader
# 创建一个加载器
loader = unittest.TestLoader()
# 从测试类中去寻找用例,然后加载到suite中
suite.addTest(loader.loadTestsFromTestCase(TestMathMethod))
# 执行
runner = unittest.TextTestRunner()
runner.run(suite)
2)suite.addTest(loader.loadTestsFromModule(test_class)) #从测试类中的用例去寻找,将模块中的所有类TestMathMethod和TestDiveMethod中的方法全部添加至suite中
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 17:12
# @File : run_class.py
import unittest
# from test_class import TestMathMethod
import test_class
suite = unittest.TestSuite()#存储用例
# 方法一:只执行一条用例,两个正数相加
# suite.addTest
# suite.addTest(TestMathMethod('test_add_two_positive'))
# 方法二:TestLoader
# 创建一个加载器
loader = unittest.TestLoader()
# 1)从测试类中去寻找用例,然后加载到suite中
# suite.addTest(loader.loadTestsFromTestCase(TestMathMethod))
# 2)从模块里去找用例,然后将模块下的用例添加至suite中
# 会将test_class中的两个类都执行
suite.addTest(loader.loadTestsFromModule(test_class))
# 执行
runner = unittest.TextTestRunner()
runner.run(suite)
3、执行
runner = unittest.TextTestRunner()
runner.run(suite)
unittest.TextTestRunner() 不带参数的时候,生成的报告会直接打印在控制台中
# 带参数,会在生成指定的文件,并将报告输出到此文件中,有中文时,要设置encoding='UTF-8' file = open("test.txt", "w+", encoding='UTF-8') runner = unittest.TextTestRunner(stream=file, verbosity=2) runner.run(suite)
verbosity = 2的时候 用例执情况最详细,0的时候最简单 verbosity 的取值状态可以是 0、1、2这三种情况
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 17:12
# @File : run_class.py
import unittest
# from test_class import TestMathMethod
import test_class
suite = unittest.TestSuite()#存储用例
# 方法一:只执行一条用例,两个正数相加
# suite.addTest
# suite.addTest(TestMathMethod('test_add_two_positive'))
# 方法二:TestLoader
# 创建一个加载器
loader = unittest.TestLoader()
# 1)从测试类中去寻找用例,然后加载到suite中
# suite.addTest(loader.loadTestsFromTestCase(TestMathMethod))
# 2)从模块里去找用例,然后将模块下的用例添加至suite中
# 会将test_class中的两个类都执行
suite.addTest(loader.loadTestsFromModule(test_class))
# 执行
# 不带参数的时候,生成的测试报告会直接打印在控件台上
# runner = unittest.TextTestRunner()
# 带参数,会在生成指定的文件,并将报告输出到此文件中,有中文时,要设置encoding='UTF-8'
file = open("test.txt", "w+", encoding='UTF-8')
runner = unittest.TextTestRunner(stream=file, verbosity=2)
runner.run(suite)
file.close()
测试报告
更好的代码式:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 17:12
# @File : run_class.py
import unittest
# from test_class import TestMathMethod
import test_class
suite = unittest.TestSuite()#存储用例
# 方法一:只执行一条用例,两个正数相加
# suite.addTest
# suite.addTest(TestMathMethod('test_add_two_positive'))
# 方法二:TestLoader
# 创建一个加载器
loader = unittest.TestLoader()
# 1)从测试类中去寻找用例,然后加载到suite中
# suite.addTest(loader.loadTestsFromTestCase(TestMathMethod))
# 2)从模块里去找用例,然后将模块下的用例添加至suite中
# 会将test_class中的两个类都执行
suite.addTest(loader.loadTestsFromModule(test_class))
# 执行
# 不带参数的时候,生成的测试报告会直接打印在控件台上
# runner = unittest.TextTestRunner()
# 带参数,会在生成指定的文件,并将报告输出到此文件中,有中文时,要设置encoding='UTF-8'
# file = open("test.txt", "w+", encoding='UTF-8')
# runner = unittest.TextTestRunner(stream=file, verbosity=2)
# runner.run(suite)
# file.close()
# 上下文管理器,会在执行结束后,自己去close文件,不需要手动去处理
with open("test.txt", "w+", encoding='UTF-8') as file:
runner = unittest.TextTestRunner(stream=file, verbosity=2)
runner.run(suite)
print(file.closed)
4、断言
断言里的msg,是在用例执行失败后,才会打印出来。
在断言里边加一个异常处理:
添加了异常处理的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/4/1 16:20
# @Author : lixiaomei
# @Site :
# @File : test_class.py
import unittest
from calc_class import MathMethod,DivMethod
# 写一个测试类,对写的math method模块里的类,进行单元测试
# 继承了unittest里边的TestCase专门用来写用例
class TestMathMethod(unittest.TestCase):
# 1:一个用例就是一个函数,不能传参,只有self关健字
# 2:所有的用例(所有的函数 都是test开头,test_)
def setUp(self):
print("我要开始执行测试用例了")
def tearDown(self):
print("我已经执行完测试用例了")
# setUp每个用例执行之前,都会执行setUp,如果有操作必须在用例之前准备好,就放到setUp里
# teardown每个用例执行结束后,都会执行,如果有操作必须在执行用例完毕后要清除掉,就放到teardown里
def test_add_two_positive(self):
res = MathMethod(1, 1).add()
print("1+1相加的结果是", res)
try:
self.assertEqual(3, res, "两数相加出错了") #断言里的msg是用例执行失败后,才会打印出来
except AssertionError as e:
print("出错啦!断言错误是{0}".format(e))
raise e #异常处理完,要将异常抛出去
def test_add_two_negative(self):
res = MathMethod(-1, -2).add()
print("-1和-2相加的结果是", res)
try:
self.assertEqual(-3, res, "两数相加出错了")
except AssertionError as e:
print("出错啦!断言错误是{0}".format(e))
raise e
class TestDivMethod(unittest.TestCase):
def test_div_two_positive(self):
res = DivMethod(2, 1).div()
print("2除以1是", res)
try:
self.assertEqual(2, res, "两数相除出错了")
except AssertionError as e:
print("出错啦!断言错误是{0}".format(e))
raise e
if __name__ == '__main__':
unittest.main()
setUp每个用例执行之前,都会执行setUp,如果有操作必须在用例之前准备好,就放到setUp里 teardown每个用例执行结束后,都会执行,如果有操作必须在执行用例完毕后要清除掉,就放到teardown里