import unittest
print(dir(unittest))
['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner', '_TextTestResult', '__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__unittest', 'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'load_tests', 'loader', 'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util']
核心要素
- TestCase
- TestSuite
- TextTestRunner
- Fixture
- TestLoader
TestCase(测试用例)
一个TestCase就是一条测试用例
使用:
1. 导包:import unittest --> 导入unitest框架
2. 继承:unittest.TestCase --> 新建测试类继承unittest.TestCase
提示:
1). 测试用例:在自动化测试中,一条用例就是一个完整的测试流程;
2). 测试方法名称命名必须以test开头;
(原因:unittest.TestCase类批量运行的方法是搜索执行test开头的方法)
# 1、导包
# 2、自定义测试类
# 3、在测试类中书写测试方法 采用print 简单书写测试方法
# 4、执行用例
import unittest
# 2、自定义测试类,需要继承unittest模块中的TestCase类即可
class TestDemo(unittest.TestCase):
# 书写测试方法,测试用例代码,书写要求,测试方法必须test_ 开头
def update(self):
print("更新操作")
def test_method1(self):
print('测试方法1-1')
def test_method2(self):
self.update()
print('测试方法1-2')
说明:def 定义的test_ 是测试用例,只有执行 if __name__ == '___main___' 的时候会执行测试用例,其他普通函数则不执行,通过 self 来调用执行。
TestSuite(测试套件)
多条测试用例集合在一起,就是一个TestSuite
使用:
1. 实例化: suite=unittest.TestSuite()
(suite:为TestSuite实例化的名称)
2. 添加用例:suite.addTest(ClassName(“MethodName”))
(ClassName:为类名;MethodName:为方法名)
3. 添加扩展:suite.addTest(unittest.makeSuite(ClassName))
(搜索指定ClassName内test开头的方法并添加到测试套件中)
提示:
1). 一条测试用例(.py)内,多个方法也可以使用测试套件
2). TestSuite需要配合TextTestRunner才能被执行
# 1、导包
# 2、实例化(创建对象)套件对象
# 3、使用套件对象添加用例方法
# 4、实例化对象运行
# 5、使用运行对象去执行套件对象
import unittest
from unittest_Demo2 import TestDemo
from unittest_Demo1 import Demo
suite = unittest.TestSuite()
# 将⼀个测试类中的所有⽅法进⾏添加
# 套件对象.addTest(unittest.makeSuite(测试类名))
suite.addTest(unittest.makeSuite(TestDemo))
suite.addTest(unittest.makeSuite(Demo))
# 4、实例化运行对象
runner = unittest.TextTestRunner();
# 5、使用运行对象去执行套件对象
# 运⾏对象.run(套件对象)
runner.run(suite)
TextTestRunner(测试执行)
是用来执行测试用例套件
使用:
1. 实例化: runner=unittest.TextTestRunner()
(runner:TextTestRunner实例化名称)
2. 执行: runner.run(suite)
(suite:为测试套件名称)
Fixture(固定装置)
是一个概述,对一个测试用例环境的搭建和销毁就是一个Fixture;
方法级别
使用:
1. 初始化(搭建):def setUp(self) --> 首先执行
(setUp:此方法继承于unittest.TestCase)
2. 结束(销毁): def tearDown(self) --> 最后执行
(tearDown:此方法继承于unittest.TestCase)
提示:
1. 必须继承unittest.TestCase类,setUp、tearDown才是一个Fixture;
2. setUp:一般做初始化工作,比如:实例化浏览器、浏览器最大化、隐式等待设置
3. tearDown:一般做结束工作,比如:退出登录、关闭浏览器
4. 如果一个测试类有多个test开头方法,则每个方法执行之前都会运行setUp、结束时运行tearDown
# 初始化
def setUp(self):
# 每个测试方法执行之前执行的函数
pass
# 释放
def tearDown(self):
# 每个测试方法执行之后执行的函数
pass
类级别
在整个类中 执行之前执行之后各一次
- def setUpClass() ,类中所有方法之前
- def tearDownClass(),类中所有方法之后
特性:测试类运行之前运行一次setUpClass ,类运行之后运行一次tearDownClass
注意:类方法必须使用 @classmethod修饰
@classmethod
def setUpClass(cls):
print('-----------1.打开浏览器')
@classmethod
def tearDownClass(cls):
print('------------5、关闭浏览器')
# 导入unittest模块
import unittest
# 创建单元测试类,继承unittest.TestCase
class testCase(unittest.TestCase):
def setUp(self):
print("case执行前")
def tearDown(self):
print("case执行后")
@classmethod
def setUpClass(cls):
print("对象执行前")
@classmethod
def tearDownClass(cls):
print("对象执行后")
def test_01(self):
print("test01")
def test_02(self):
print("test02")
if __name__ == '__main__':
unittest.main()
结果
E:\venv\practice_1_36\Scripts\python.exe "D:\tool\PycharmProfessional\PyCharm 2021.3.3\plugins\python\helpers\pycharm\_jb_unittest_runner.py" --target 1.testCase
Testing started at 16:13 ...
Launching unittests with arguments python -m unittest 1.testCase in E:\work_code\practice\LearnUnittest
对象执行前
Ran 2 tests in 0.002s
OK
case执行前
test01
case执行后
case执行前
test02
case执行后
对象执行后
Process finished with exit code 0
TestLoader(测试加载)
使用unittest.defaultTestLoader()类,通过该类下面的discover()方法自动搜索指定目录下指定开头的.py文件,并将查找到的测试用例组装到测试套件;
用法:
test_dir = ‘./’
disconver = unittest.TestLoader.discover(test_dir, pattern=‘iweb_*.py’)
(test_dir为要指定的目录 ./为当前目录;pattern:为查找的.py文件的格式 )
运行:
runner=unittest.TextTestRunner()
runner.run(disconver)
写法:
1. suite = unittest.TestLoader().discover("指定搜索的目录文件","指定字母开头模块文件")
2. suite = unittest.defaultTestLoader.discover("指定搜索的目录文件","指定字母开头模块文件") 【推荐】
注意:
如果使用写法1,TestLoader()必须有括号。
# 1. 导包
# 2. 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
# 3. 实例化 运行对象
# 4. 运行对象执行套件对象
import unittest
# 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
# unittest.defaultTestLoader.discover('用例所在的路径', '用例的代码文件名')
# 测试路径:相对路径
# 测试文件名:可以使用 * 通配符,可以重复使用
suite = unittest.defaultTestLoader.discover('./Case', 'cs*.py')
runner = unittest.TextTestRunner()
runner.run(suite)
TestLoader与TestSuite区别
- 共同点:
都是测试套件
- 不同点:
实现方式不同
- TestSuite: 要么添加指定的测试类中所有test开头的方法,要么添加指定测试类中指定某个test开头的方法
- TestLoader: 搜索指定目录下指定字母开头的模块文件中以test字母开头的方法并将这些方法添加到测试套件中,最后返回测试套件
断言
在unittest中使用断言,需要通过 self.断言方法
断言方法
跳过
unittest测试用例跳过执行
跳过执行测试用例共有四种写法
- @unittest.skip(reason) :跳过测试用例,reason 为测试被跳过的原因
- @unittest.skipIf(condition, reason) :当 condition 为真时,跳过测试用例
- @unittest.skipUnless(condition, reason) :跳过测试用例,除非 condition 为真
- @unittest.expectedFailure:把测试用例标记为预计失败;如果测试不通过,会被认为测试成功;如果测试通过了,则被认为是测试失败
# 导入unittest模块
import sys
import unittest
class testCase(unittest.TestCase):
# 直接跳过
@unittest.skip("直接跳过")
def test_skip(self):
self.fail("shouldn't happen")
# 满足condition则跳过
@unittest.skipIf(1 < 2, "满足condition则跳过")
def test_skipIf(self):
print("skip if")
# 不满足condition则跳过
@unittest.skipUnless(sys.platform.startswith("win"), "需要window平台才不会跳过")
def test_skipUnless(self):
print("skip Unless")
# 预计该测试用例会测试失败
@unittest.expectedFailure
def test_fail(self):
self.assertEqual(1, 0, "broken")
结果:
E:\venv\practice_1_36\Scripts\python.exe "D:\tool\PycharmProfessional\PyCharm 2021.3.3\plugins\python\helpers\pycharm\_jb_unittest_runner.py" --target 2.testCase
Testing started at 16:41 ...
Launching unittests with arguments python -m unittest 2.testCase in E:\work_code\practice\LearnUnittest
Ran 5 tests in 0.003s
OK (skipped=3, expected failures=1)
Process finished with exit code 0
Expected failure: Traceback (most recent call last):
File "D:\tool\python36\lib\unittest\case.py", line 59, in testPartExecutor
yield
File "D:\tool\python36\lib\unittest\case.py", line 605, in run
testMethod()
File "E:\work_code\practice\LearnUnittest\2.py", line 25, in test_fail
self.assertEqual(1, 0, "broken")
File "D:\tool\PycharmProfessional\PyCharm 2021.3.3\plugins\python\helpers\pycharm\teamcity\diff_tools.py", line 33, in _patched_equals
old(self, first, second, msg)
File "D:\tool\python36\lib\unittest\case.py", line 829, in assertEqual
assertion_func(first, second, msg=msg)
File "D:\tool\python36\lib\unittest\case.py", line 822, in _baseAssertEqual
raise self.failureException(msg)
AssertionError: 1 != 0 : broken
Skipped: 调用unittest的skipTest,在方法体内满足某些条件则跳过该case
Skipped: 直接跳过
Skipped: 满足condition则跳过
skip Unless
语法规则
1.用例类必须继承于unittest.TestCase
2.所有的测试用例,必须以test开头
3.运行的顺序与代码的位置无关,按照 ASCII 升序排列, 0-9,A-Z,a-z(除非测试套件指定添加)