系统学习Python——单元测试unittest:内置装饰器

分类目录:《系统学习Python》总目录
相关文章:
· 单元测试unittest:框架结构
· 单元测试unittest:测试固件
· 单元测试unittest:编写测试用例
· 单元测试unittest:执行测试用例
· 单元测试unittest:用例执行次序
· 单元测试unittest:内置装饰器
· 单元测试unittest:命令行执行测试
· 单元测试unittest:批量执行测试文件
· 单元测试unittest:测试断言
· 单元测试unittest:测试报告


在自动化测试过程中,我们可能会遇到这样的场景:在某些情况下,测试用例虽然不需要执行,但是我们又不愿意删掉它。下面来看看unittest提供的装饰器功能。

无条件跳过装饰器

下面的代码借助@unittest.skip('skip info')装饰器,演示无条件跳过执行某个方法:

import unittest


class MyTestClassOne(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print('setUpClass')

    def setUp(self):
        print('setUp')

    def test_001(self):
        print('test_first')
        self.assertEqual(0, 0)

    @unittest.skip('skip info')
    def test_002(self):
        print('test_second')
        self.assertEqual(0, 0)

    def test_003(self):
        print('test_third')
        self.assertEqual(0, 0)

    def test_004(self):
        print('test_fourth')
        self.assertEqual(0, 0)

    def tearDown(self):
        print('tearDown')

    @classmethod
    def tearDownClass(cls):
        print('tearDownClass')

运行结果如下:

============================= test session starts =============================
collecting ... collected 4 items

testclass.py::MyTestClassOne::test_001 setUpClass
setUp
test_first
tearDown

testclass.py::MyTestClassOne::test_002 SKIPPED (skip info) 
Skipped: skip info

testclass.py::MyTestClassOne::test_003
setUp
test_third
tearDown

testclass.py::MyTestClassOne::test_004
setUp
test_fourth
tearDown
tearDownClass


======================== 3 passed, 1 skipped in 0.03s =========================

Process finished with exit code 0

满足条件跳过装饰器

下面的代码借助@unittest.skipIf(condition, 'info')装饰器,演示当满足某个条件时,跳过执行某个方法:

import unittest


class MyTestClassOne(unittest.TestCase):
    i = 10
    @classmethod
    def setUpClass(cls):
        print('setUpClass')

    def setUp(self):
        print('setUp')

    def test_001(self):
        print('test_first')
        self.assertEqual(0, 0)

    @unittest.skipIf(i > 1, 'info')
    def test_002(self):
        print('test_second')
        self.assertEqual(0, 0)

    def test_003(self):
        print('test_third')
        self.assertEqual(0, 0)

    def test_004(self):
        print('test_fourth')
        self.assertEqual(0, 0)

    def tearDown(self):
        print('tearDown')

    @classmethod
    def tearDownClass(cls):
        print('tearDownClass')

if __name__ == '__main__':
    unittest.main()

因为变量i = 1,满足i > 0的条件,所以跳过执行test_002用例,运行结果如下:

============================= test session starts =============================
collecting ... collected 4 items

testclass.py::MyTestClassOne::test_001 setUpClass
PASSED                            [ 25%]setUp
test_first
tearDown

testclass.py::MyTestClassOne::test_002 SKIPPED (info)                    [ 50%]
Skipped: info

testclass.py::MyTestClassOne::test_003 PASSED                            [ 75%]setUp
test_third
tearDown

testclass.py::MyTestClassOne::test_004 PASSED                            [100%]setUp
test_fourth
tearDown
tearDownClass


======================== 3 passed, 1 skipped in 0.03s =========================

Process finished with exit code 0
不满足条件跳过

下面的代码借助@unittest.skipUnless(a==5,‘info’)装饰器,演示当不满足某个条件时,跳过执行某个方法。

import unittest


class MyTestClassOne(unittest.TestCase):
    i = -1
    @classmethod
    def setUpClass(cls):
        print('setUpClass')

    def setUp(self):
        print('setUp')
        self.i = 1

    def test_001(self):
        print('test_first')
        self.assertEqual(0, 0)


    def test_002(self):
        print('test_second')
        self.assertEqual(0, 0)


    def test_003(self):
        print('test_third')
        self.assertEqual(0, 0)

    @unittest.skipUnless(i > 0, 'info')
    def test_004(self):
        print('test_fourth')
        self.assertEqual(0, 0)

    def tearDown(self):
        print('tearDown')

    @classmethod
    def tearDownClass(cls):
        print('tearDownClass')

if __name__ == '__main__':
    unittest.main()

因为i < 0不满足条件,所以跳过test_004用例,运行结果如下:

============================= test session starts =============================
collecting ... collected 4 items

testclass.py::MyTestClassOne::test_001 
testclass.py::MyTestClassOne::test_002 
testclass.py::MyTestClassOne::test_003 
testclass.py::MyTestClassOne::test_004 

======================== 3 passed, 1 skipped in 0.03s =========================

Process finished with exit code 0
setUpClass
setUp
test_first
tearDown
setUp
test_second
tearDown
setUp
test_third
tearDown
SKIPPED (info) 
Skipped: info
tearDownClass
### Python代码单元测试教程和最佳实践 #### 单元测试的重要性 单元测试是软件开发过程中不可或缺的一部分,它能够验证单个模块的功能是否按预期工作。对于Python开发者而言,良好的单元测试可以显著提高代码质量并减少Bug的发生率。 #### 测试覆盖率的概念 测试覆盖率是一种度量标准,用于衡量测试是否覆盖了代码中的各个部分。这一指标可以帮助识别未被充分检验的部分,进而改进测试套件以增强程序稳定性和健壮性[^1]。 #### 基础框架unittest简介 `unittest` 是Python自带的标准库之一,提供了丰富的功能支持创建结构化的测试案例集。下面是一个简单的例子展示如何利用 `unittest` 进行基本函数的测试: ```python import unittest def add(a, b): """返回两个数相加的结果""" return a + b class TestAddFunction(unittest.TestCase): def test_add_positive_numbers(self): self.assertEqual(add(1, 2), 3) if __name__ == '__main__': unittest.main() ``` #### pytest框架介绍及其优势 除了内置的 `unittest` 外,`pytest` 是另一个非常流行的第三方测试框架,具有更简洁直观的语法以及强大的插件生态系统。以下是使用 `pytest` 的相同示例: ```python # content of test_sample.py def add(a, b): """返回两个数相加的结果""" return a + b def test_add_positive_numbers(): assert add(1, 2) == 3 ``` 要运行上述测试只需在命令行输入 `pytest` ,该工具会自动发现所有匹配模式(如test_*.py)下的测试文件并执行它们。 #### 提高测试效率的方法——参数化测试 为了使测试更加灵活高效,在面对大量相似场景时可以通过参数化的方式一次性定义多个数据点来进行批量验证。这里给出基于 `@pytest.mark.parametrize()` 装饰器实现的例子: ```python @pytest.mark.parametrize( "input_x,input_y,output", [ (0, 0, 0), (-1, 1, 0), (2, 3, 5) ] ) def test_add(input_x, input_y, output): assert add(input_x, input_y) == output ``` 此方法允许一次性的配置多组不同的输入输出组合,极大地提升了编写重复性测试工作的便捷程度。 #### 集成持续集成/部署(CI/CD)管道 将自动化构建与发布流程相结合可以在每次提交新版本之前确保现有功能正常运作,并及时捕捉潜在问题。GitHub Actions、GitLab CI 和 Travis CI 等平台都提供简单易用的服务接口来设置CI环境。 #### 使用mock对象模拟外部依赖关系 当待测组件涉及到网络请求或其他难以控制的因素时,借助 `unittest.mock` 或者专门设计用来做Mocking的库比如 `responses` 可以为这些交互行为创造虚拟替身,从而专注于核心逻辑本身而不受外界干扰影响。 #### 记录日志辅助调试过程 适当加入日志打印语句有助于追踪复杂业务流内部状态变化情况;特别是在遇到异常状况时能快速定位原因所在。Python的日志模块(`logging`)非常适合完成这项任务,而且可以根据实际需求调整不同级别的消息显示策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

von Neumann

您的赞赏是我创作最大的动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值