• UnitTest框架


    目标:

    1.掌握UnitTest框架的基本使用方法

    2.掌握断言的使用方法

    3.掌握如何实现参数化

    4.掌握测试报告的生成

    1.定义

    (1)框架(framework):为解决一类事情的功能集合。(需要按照框架的规定(套路) 去书写代码)

    (2)UnitTest框架:UnitTest是Python自带的一个单元测试框架,用它来做单元测试。

    自带的框架(官方): 不需要单外安装, 只要安装了 Python,就可以使用random, json, os, time
    第三方框架: 想要使用 需要先安装后使用(pytest)selenium , appium, requests 
    单元测试框架: 主要用来做单元测试, 一般单元测试是开发做的.
    对于测试来说, unittest 框架的作用是自动化脚本(用例代码) 执行框架(使用unittest框架 来管理运行多个测试用例的)

    2.UnitTest核心要素

    1.TestCase(测试用例)-》核心
    每个 TestCase(测试用例) 都是一个代码文件
    ​
    2.TestSuite(测试套件)
    用来管理组装(打包)多个 TestCase(测试用例) 的
    ​
    3.TestRunner(测试执行,测试运行)
    用来执行TestSuite(测试套件)的
    ​
    4.TestLoader(测试加载)
    对 TestSuite(测试套件) 功能的补充,
    ​
    5.Fixture(测试夹具)
    书写在 TestCase(测试用例) 代码中, 是一个代码结构, 可以在每个方法执行前后都会执行的内容

    1.TestCase(测试用例)代码文件书写

    步骤:
    1. 导包 (unittest)
    2. 自定义测试类
    3. 在测试类中书写测试方法
    4. 执行用例
    ​
    # 1.导包
    import unittest
    ​
    # 2.自定义测试类 (需要继承unittest模块中的TestCase类)
    class TestDome(unittest.TestCase):
        # 3.书写测试方法 即:用例代码(目前没有真正的用例代码,使用print代替)
        #书写要求,测试方法必须以test_开头
        def test_method1(self):
            print('测试方法1')
    ​
        def test_method2(self):
            print('测试方法2')
    ​
    # 4.执行用例
    # 1 将光标放在 类名的后边 运行, 会执行类中的所有的测试方法
    # 2 将光标放在 方法名的后边 运行, 只执行当前的方法

    2.TestSuite(测试套件) & TestRunner(测试执行)代码书写

    步骤:
    1. 导包(unittest)
    2. 实例化(创建对象)套件对象
    3. 使用套件对象添加用例方法
    4. 实例化运行对象
    5. 使用运行对象去执行套件对象
    ​
    # 1.导包(unittest)
    import unittest
    #后面添加用例方法的时候导的包
    from testcase1 import TestDome1
    from testcase2 import TestDome2
    ​
    # 2.实例化(创建对象)套件对象
    suite = unittest.TestSuite()
    ​
    # 3. 使用套件对象添加用例方法
    # 方式一, 套件对象.addTest(测试类名('方法名'))   # 建议测试类名和方法名直接去复制,不要手写
    suite.addTest(TestDome1('test_method1'))
    suite.addTest(TestDome1('test_method2'))
    suite.addTest(TestDome2('test_method1'))
    suite.addTest(TestDome2('test_method2'))
    ​
    # 4. 实例化运行对象
    runner = unittest.TextTestRunner()
    # 5. 使用运行对象去执行套件对象
    # 运行对象.run(套件对象)
    runner.run(suite)

    3.TestLoader(测试加载)

    步骤:
    1. 导包
    2. 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
    3. 实例化 运行对象
    4. 运行对象执行套件对象
    ​
    # 1.导包
    import unittest
    ​
    # 2.实例化加载对象并添加使用
    # unittest.TestLoader().discover('用例所在路径','用例代码文件名')
    # 用例代码路径:推荐使用相对路径;用例代码文件名:可使用*通配符
    suite = unittest.TestLoader().discover('./case','test*.py')
    ​
    # 3, 实例化运行对象
    # runner = unittest.TextTestRunner()
    # # 4, 执行
    # runner.run(suite)
    ​
    # 可以将 3 4 步 变为一步
    unittest.TextTestRunner().run(suite)

    4.Fixture(测试工具)

    对一个测试用例环境的初始化和销毁就是一个Fixture
    Fixture控制级别:
    1.方法级别(掌握)
    2.类级别(掌握)
    3.模块级别(了解)
    ​
    1.方法级别:在每个测试方法(用例代码) 执行前后都会自动调用的结构
    # 方法执行之前
    def setUp(self):
        每个测试方法执行之前都会执行
        pass
    # 方法执行之后
    def tearDown(self):
        每个测试方法执行之后都会执行
        pass
        
    ​
    2.类级别:在每个测试类中所有方法执行前后 都会自动调用的结构(在整个类中 执行之前执行之后个一次)
    # 类级别的Fixture 方法, 是一个 类方法
    # 类中所有方法之前
    @classmethod
    def setUpClass(cls):
        pass
    # 类中所有方法之后
    @classmethod
    def tearDownClass(cls):
        pass
        
    ​
    3.模块级别:代码文件,在每个代码文件执行前后执行的代码结构
    # 模块级别的需要写在类的外边直接定义函数即可
    # 代码文件之前
    def setUpModule():
        pass
    # 代码文件之后
    def tearDownModule():
        pass
    ​

    3.UnitTest断言

    1.定义:

    断言:让程序代替人工自动的判断预期结果和实际结果是否相符。

    断言的结果有两种:
    True, 用例通过 ; False, 代码抛出异常, 用例不通过
    在 unittest 中使用断言, 都需要通过 self.断言方法来试验

    3.断言常用方法:

    assertEqual:
    self.assertEqual(预期结果, 实际结果) # 判断预期结果和实际结果是否相等
    1. 如果相等, 用例通过
    2. 如果不相等,用例不通过, 抛出异常
    assertIn:
    self.assertIn(预期结果, 实际结果) # 判断预期结果是否包含在实际结果中
    1. 包含 ,用例通过
    2. 不包含, 用例不通过, 抛出异常
    assertIn('admin', 'admin') # 包含
    assertIn('admin', 'adminnnnnnnn') # 包含
    assertIn('admin', 'aaaaaadmin') # 包含
    assertIn('admin', 'aaaaaadminnnnnnn') # 包含
    assertIn('admin', 'addddddmin') # 不是包含

    4.参数化

    通过参数的方式来传递数据,从而实现数据和脚本分离,并且可以实现用例的重复执行。
    unittest测试框架,本身不支持参数化,但是可以通过安装unittest扩展插件parameterized来实现
    工作中场景:
    1. 测试数据一般放在 json 文件中
    2. 使用代码读取 json 文件,提取我们想要的数据 ---> [(), ()] or [[], []]
    ​
    cmd窗口安装或者在pycharm的终端安装
    安装插件:pip install parameterized
    (pip 是 Python 中包(插件) 的管理工具, 使用这个工具下载安装插件)
    验证:pip list # 查看到 parameterized
    新建一个 python 代码文件, 导包验证:from pa... import pa...
    ​
    参数化代码书写
    步骤:
    1. 导包 unittest/ pa
    2. 定义测试类
    3. 书写测试方法(用到的测试数据使用变量代替)
    4. 组织测试数据并传参

    例子2:
    data.json文件内容如下:
    [
        {
            "desc": "正确的用户名和密码",
            "username": "admin",
            "password": "123456",
            "expect": "登录成功"
        },
        {
            "desc": "错误的的用户名",
            "username": "root",
            "password": "123456",
            "expect": "登录失败"
        },
        {
            "desc": "错误的的密码",
            "username": "admin",
            "password": "123123",
            "expect": "登录失败"
        }
    ]
    ​
    # 1. 导包 unittest/ pa
    import json
    import unittest
    from parameterized import parameterized
    from tools import login
    # 组织测试数据 [(), (), ()] or [[], [], []]
    def build_data():
        with open('data.json', encoding='utf-8') as f:
            result = json.load(f) # [{}, {}, {}]
            data = []
            for i in result: # i {}
                data.append((i.get('username'),i.get('password'),i.get('expect')))
            return data
    # 2. 定义测试类
    class TestLogin(unittest.TestCase):
        # 3. 书写测试方法(用到的测试数据使用变量代替)
        @parameterized.expand(build_data())
        def test_login(self, username, password, expect):
            self.assertEqual(expect, login(username, password))
    # 4. 组织测试数据并传参(装饰器 @)

    5.跳过

    对于一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行

    使用方式:
    # 直接将测试函数标记成跳过
    @unittest.skip('跳过额原因')
    # 根据条件判断测试函数是否跳过 , 判断条件成立, 跳过
    @unittest.skipIf(判断条件, '跳过原因')
    ​
    示例代码:
    import unittest
    # version = 30
    version = 29
    class TestDemo(unittest.TestCase):
        @unittest.skip('没有什么原因,就是不想执行')
        def test_1(self):
            print('测试方法 1')
        @unittest.skipIf(version >= 30, '版本大于等于 30, 不用测试')
        def test_2(self):
            print('测试方法 2')
        def test_3(self):
            print('测试方法3')

    6.测试报告

    自带的测试报告
    只有单独运行 TestCase 的代码,才会生成测试报告

    生成第三方的测试报告
    1. 获取第三方的 测试运行类模块 , 将其放在代码的目录中
    2. 导包 unittest
    3. 使用 套件对象, 加载对象 去添加用例方法
    4. 实例化 第三方的运行对象 并运行 套件对象
    ​
    # 1. 获取第三方的 测试运行类模块 , 将其放在代码的目录中
    # 2. 导包 unittest
    import unittest
    from HTMLTestRunner import HTMLTestRunner
    # 3. 使用 套件对象, 加载对象 去添加用例方法
    suite = unittest.defaultTestLoader.discover('.', 'pa1.py')
    # 4. 实例化 第三方的运行对象 并运行 套件对象
    # HTMLTestRunner()
    #pa1.py涉及的参数如下
    # stream=sys.stdout, 必填,测试报告的文件对象(open ), 注意点,要使用 wb 打开
    # verbosity=1, 可选, 报告的详细程度,默认 1 简略, 2 详细
    # title=None, 可选, 测试报告的标题
    # description=None 可选, 描述信息, Python 的版本, pycharm 版本
    # file = 'report.html' # 报告的后缀是.html
    file = 'report1.html' # 报告的后缀是.html
    with open(file, 'wb') as f:
        # runner = HTMLTestRunner(f) # 运行对象
        runner = HTMLTestRunner(f, 2, '测试报告', 'python 3.6.8 ') # 运行对象
        #运行对象执行套件, 要写在 with 的缩进中
        runner.run(suite)
        
        
    1. 组织用例文件(TestCase 里边), 书写参数化, 书写断言, 书写 Fixture, 书写 跳过, 如果单个测试测试文
    件, 直接运行, 得到测试报告, 如果有多个测试文件, 需要组装运行生成测试报告
    2. 使用 套件对象组装, 或者使用 加载对象组装
    3. 运行对象 运行
    3.1 运行对象 = 第三方的运行类(文件对象(打开文件需要使用 wb 方式))
    3.2 运行对象.run(套件对象)
    ​
    import unittest
    from HTMLTestRunnerCN import HTMLTestReportCN
    # 组装用例方法
    suite = unittest.defaultTestLoader.discover('.', '*pa1.py')
    # 实例化运行对象
    with open('report_cn.html', 'wb') as f:
        runner = HTMLTestReportCN(f)
        runner.run(suite)

    要有一个第三方的类库:HTMLTestRunner:用来执行测试用例并生成HTML格式的测试报告

  • 相关阅读:
    Cinema 4D初学者终极指南
    js 代理事件理解及应用场景
    unity shaderGraph实例-物体线框显示
    如何提升JSON.stringify()的性能?
    python的全局变量和局部变量
    acwing算法基础之数据结构--栈和队列
    基于SSM的罪犯信息管理系统
    30岁了,还能转行做测试/开发程序员吗?下定决心开始干......
    【动态规划】求解编辑距离问题
    文件系统系列专题之 Btrfs
  • 原文地址:https://blog.csdn.net/weixin_61275790/article/details/134493796