概念
unittset是python自带的单元测试框架,用来做单元测试
对测试的作用:自动化脚本(用例代码)执行框架
用来管理运行多个测试用例
作用
1. 组织多个用例去执行
2. 提供丰富的断言方法(自动化)
3. 生产测试报告
组成部分
TestCase (测试用例)是一个代码文件 用来书写 测试用例的代码 (核心!!!
TestSuite (测试套件)管理、组装多个TestCase
TestRunner (测试执行) 执行TestSuite
TestLoader (测试加载) 对TestSuite功能的补充
Fixture (测试夹具)写在TestCase中,是一种代码结构,在每个方法执行前后都会执行的内容
举例:
TestCase模块的书写方法
import unittest #导包
class TestDemo(unittest.TestCase): #定义测试类,需继承unittest模块中testcase
def test_method1(self): #测试方法 必须以test_ 开头
print('测试方法1')
def test_method2(self):
print('测试方法2')
执行方法:
放在类名后 会执行类中的所有测试方法
放在方法名后 只执行当前方法
TestSuite/Testrunner书写
# 导包
import unittest
from testcase1 import TestDemo1
from testcase2 import TestDemo2
# 创建对象
suite = unittest.TestSuite()
# 使用套件对象添加用力方法
# 套件对象.addTest(测试类名('方法名'))
suite.addTest(TestDemo1('test_method1'))
suite.addTest(TestDemo1('test_method2'))
suite.addTest(TestDemo2('test_method1'))
suite.addTest(TestDemo2('test_method1'))
# 实例化运行对象
runner = unittest.TextTestRunner()
# 使用运行对象去执行套件对象
runner.run(suite)
写法2
# 使用套件对象添加用例方法
# 将一个测试类中的所有方法进行添加
# 套件对象.addTest(unittest.makeSuite(测试类名))
suite.addTest(unittest.makeSuite(TestDemo1))
suite.addTest(unittest.makeSuite(TestDemo2))
.表示用例通过
F表示用例不通过
E 表示用例代码有问题
练习:
1.在tool模块中定义函数add,对两个数字进行求和
2.书写testcase代码对add()进行测试
#tools
def add(a, b):
return a+b
import unittest
from tools import add
class TestAdd(unittest.TestCase):
def test_method1(self):
if add(1 , 2) ==3:
print('测试通过')
else:
print('测试不通过')
def test_method2(self):
if add(10,20) == 30:
print('测试通过')
else:
print('测试不通过')
import unittest
from test import TestAdd
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))
runner = unittest.TextTestRunner()
runner.run(suite)
TestLoader (测试加载) 使用
对testsuite功能的补充,用来组装测试用例
1.导包
2.实例化测试加载对象并添加用例
unittest.TestLoader().discover('用例所在的路径','用例的代码文件名')
路径 -- 建议相对路径
代码文件名可以使用*
3.实例化 运行对象
4.运行对象执行套件对象
import unittest
suite = unittest.TestLoader().discover('./case', '*.py')
runner = unittest.TextTestRunner()
runner.run(suite)
后两行合并
unittest.TextTestRunner().run(suite)
Fixture (测试夹具) 的语法
是一种代码结构, 在某些特定情况下,会自动执行
方法级别
在每个测试方法执行前后都会自动调用的结构
方法执行之前
def setup(self):
每个测试方法执行之前会执行
pass
用例方法
方法执行之后
def tearDown(self):
每个测试方法执行之前会执行
pass
类级别
在每个测试类中所有方法执行前后都会自动调用的结果
类中所有方法之前
@classmethod
def setupClass(cls):
pass
类中所有方法之后
@classmethod
def tearDownClass(cls):
pass
以上两种级别,前后方法不需要同时出现,根据用例代码的需要自行选择使用
Fixture的使用
import unittest
class TsetLogin(unittest.TestCase):
def setUp(self) -> None:
print('输入网址')
def tearDown(self) -> None:
print('关闭当前页面')
@classmethod
def setUpClass(cls) -> None:
print('-----1.打开浏览器')
@classmethod
def tearDownClass(cls) -> None:
print('-----5.关闭浏览器')
def test_1(self):
print('请输入正确用户名和密码,点击登录1')
def test_2(self):
print('请输入正确用户名和密码,点击登录2')
断言
程序代替人工判断程序执行结果是否符合预期
结果只有 true false
unittest中使用方法 self.断言方法
assertEqual
self.assertEqual(预期结果,实际结果)
相等,用例通过
不相等,用例不通过,抛出异常
assertIn
self.assertIn(预期结果,实际结果)
判断预期结果是否包含在实际结果中
包含,用例通过
不包含,用例不通过,抛出异常
assertIn('admin' , ‘adminnnn’) 包含
assertIn('admin' , ‘addddmin’) 不包含
参数化
使用 变量 来代替具体的测试数据,使用传参方法将测试数据传给方法
参数化的使用
1.导包 (两个 unittest/pa
2.定义测试类
3.书写测试方法 (测试数据用变量代替)
4.组织测试数据并传参
import unittest
from parameterized import parameterized
from tools import login
data = [
('admin','123456','登陆成功')
('root','123456','登陆失败')
('admin','123123','登陆失败')
]
class TestLogin(unittest.TestCase):
@parameterized.expand(data)
def test_login(self,username,password, expect):
self.assertEqual(expect,login(username,password))
跳过
对一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行,装饰器完成
代码书写在TestCase中完成
直接跳过
@unittest.skip(‘跳过的原因’)
根据条件判断 测试函数是否通过,判断条件成立,跳过
@unittest.skipIf (‘跳过的原因’)
import unittest
version = 31
class TestDemo(unittest.TestCase):
@unittest.skip('跳过')
def test_1(self):
print('测试方法1')
@unittest.skipIf(version >=30, '不用测试')
def test_2(self):
print('测试方法2')
def test_3(self):
print('测试方法3')