Unittest

作者: 开心的小哈 | 来源:发表于2022-08-09 22:49 被阅读0次

    测试框架

    基于 Python 语言的自动化测试框架 最知名的 有如下 3 款 测试框架:unittest,pytest,robotframework
    前两款框架主要(或者说很大程度上)是 聚焦 在 白盒单元测试
    而 robotframework 主要聚焦在 系统测试。

    unittest

    1. 定义class使用Test开头,继承unittest.TestCase
    2. 定义test开头的方法

    演示代码

    import unittest
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    class TestCase(unittest.TestCase):
        driver = None
        def testPass(self):
            driver = webdriver.Edge(r'C:\Users\sj176\Downloads\edgedriver_win64\msedgedriver.exe')
            self.driver = driver
            self.driver.get('https://www.baidu.com')
    

    运行方式
    取决于右上角的运行环境,点击右键运行它默认会使用unittest环境运行,如果使用main运行则会走main方法否则不走
    unittest运行用例的一个很大的坑:

    1. 命令行方式运行:python -m unittest 模块名.py 执行整个模块,或者使用python -m unittest 模块名.方法名执行某个方法
    2. main方式运行:建议再另写一个文件,写:
    import unittest
    if __name__ == '__main__':
        print('------------------')
        unittest.main()
    

    Unittest框架

    概念UnitTest是Python自带的一个单元测试框架,用它来做单元测试.
    自带的框架:不需要安装,直接导报使用即可
    第三方框架如果想使用需要进行安装如pytest
    对于测试来说,unittest框架的作用是自动化脚本(用例代码)执行框架(使用unittest框架来管理 运行 多个测试用例)

    • 为什么使用UnitTest框架
    1. 能够组织多个用例去执行
    2. 提供丰富的断言方法
    3. 能够生成测试报告
    • UnitTest核心要素
    1. TestCase测试用例 最基本的操作用例
    2. TestSuite测试套件 用来管理,组装,打包TestCase用例的
    3. TestRunner测试执行,用来执行TestSuite(测试套件)
    4. TestLoader测试加载,功能是对TestSuite(测试套件)功能的补充
    5. Fixture测试夹具,书写在TestCase测试用例代码中,是一种代码结构,可以在每个方法前后都会执行的内容

    TestCase测试用例

    是一个代码文件,在代码文件中来书写真正的用例代码
    代码文件名必须按照标识符的规则来书写
    步骤:

    1. 导报(unittest)
    2. 定义测试类
    3. 在测试类中书写测试方法,方法名必须以test_开头
    4. 运行测试用例

    代码:

    import unittest
    
    class TestDemo(unittest.TestCase):
        def test_method1(self):
            print('测试方法1')
        def test_method2(self):
            print('测试方法2')
    
        def test_method3(self):
            print('测试方法2')
    
    # 执行方法,点击执行按钮或者输入
    

    TestSuite和TestRunner

    使用步骤

    1. 导报(unittest)
    2. 实例化(创建对象)套件对象
    3. 使用套件对象添加用例方法
    4. 实例化运行对象
    5. 使用运行对象执行套件对象

    代码
    方式一:
    使用方法进行执行

    import unittest
    from Test1.SeleniumD import TestDemo
    
    suite=unittest.TestSuite()
    suite.addTest(TestDemo('test_method1'))
    suite.addTest(TestDemo('test_method2'))
    runner=unittest.TextTestRunner()
    runner.run(suite)
    

    方式二:
    使用对象进行执行

    import unittest
    
    from Test1.SeleniumD import TestDemo
    from Test1.SeleniumD2 import TestDemo2
    
    suite=unittest.TestSuite()
    suite.addTest(unittest.makeSuite(TestDemo))
    suite.addTest(unittest.makeSuite(TestDemo2))
    runner=unittest.TextTestRunner()
    runner.run(suite)
    

    结果打印

    .......
    ----------------------------------------------------------------------
    Ran 7 tests in 0.000s
    
    OK
    测试方法1
    测试方法1
    测试方法2
    测试方法3
    测试方法11
    测试方法22
    测试方法33
    

    其中.代表用例通过,F用例不通过,E用例代码有问题异常了

    TestLoader(测试加载)

    使用步骤

    1. 导包
    2. 实例化测试加载对象并添加用例--->得到的是suite对象
    3. 实例化运行对象
    4. 运行对象执行套件对象

    代码实现

    import unittest
    # unittest.TestLoader().discover('用例所在的路径','用例的代码文件名')
    suite=unittest.TestLoader().discover('./Test1','Se*.py')
    runner=unittest.TextTestRunner()
    runner.run(suite)
    

    执行./Test1目录下的Se*.py测试文件

    Fixture(测试夹具)

    方法级别
    在每个测试方法前后执行一次

    class TestDemo2(unittest.TestCase):
        def setUp(self) -> None:
            print("setUp")
    
        def tearDown(self) -> None:
            print("tearDown")
        def test_method1(self):
            print('测试方法11')
        def test_method2(self):
            print('测试方法22')
    
        def test_method3(self):
            print('测试方法33')
    结果:
    setUp
    测试方法11
    tearDown
    setUp
    测试方法22
    tearDown
    setUp
    测试方法33
    

    类级别
    在每个class前后执行一次

    class TestDemo2(unittest.TestCase):
        @classmethod
        def setUpClass(cls) -> None:
            print('setUpClass')
        @classmethod
        def tearDownClass(cls) -> None:
            print('tearDownClass')
        def test_method1(self):
            print('测试方法11')
        def test_method2(self):
            print('测试方法22')
    
        def test_method3(self):
            print('测试方法33')
    结果:
    setUpClass
    测试方法11
    测试方法22
    测试方法33
    tearDownClass
    

    模块级别
    在每个代码文件前后执行一次

    import unittest
    
    def setUpModule():
        print('setupModule')
    
    # 执行方法,点击执行按钮或者输入
    def tearDownModule():
        print('teardownModule')
    
    class TestDemo2(unittest.TestCase):
    
        def test_method1(self):
            print('测试方法11')
        def test_method2(self):
            print('测试方法22')
    
        def test_method3(self):
            print('测试方法33')
    class TestDemo3(unittest.TestCase):
    
        def test_method1(self):
            print('测试方法11')
        def test_method2(self):
            print('测试方法22')
    
        def test_method3(self):
            print('测试方法33')
    
    结果:
    setupModule
    测试方法11
    测试方法22
    测试方法33
    测试方法11
    测试方法22
    测试方法33
    teardownModule
    

    断言

    什么是断言:让机器替代人来判断结果是否正确,断言结果:True,False
    断言方法

    1. assertTrue(expr,msg=None):验证expr是true,如果为false,则false
    2. assertFalse(expr,msg=None):验证expr是false,如果为true,则false
    3. assertEqual(expr,msg=None):验证expr是==actual,不等于则false
    4. assertNotEqual(expr,msg=None):验证expr是!=actual相等则false
    5. assertNone(expr,msg=None):验证expr是None,不是则false
    6. assertNotNone(expr,msg=None):验证expr不是None,是则false
    7. assertIn(expr,container,msg=None):验证是否expr in container
    8. assertNotIn(expr,msg=None):验证是否expr not in container

    assertIn('admin','adminnnnnn') 包含
    assertIn('admin','ad1minnnnnn') 不包含
    代码使用

    class TestDemo2(unittest.TestCase):
    
        def test_method1(self):
            self.assertEqual('登录成功','登录成功啦')
        def test_method2(self):
            self.assertIn('登录成功','登录成功啦')
    
        def test_method3(self):
            self.assertEqual('登录成功','登录成功')
    

    点击运行按钮运行如果想看测试报告可以点击控制台,左上角有个导出报告按钮,点击导出即可;

    参数化

    unittest框架本身是不支持参数化,要想使用参数化,需要安装插件来完成
    需要安装pip install parameterized
    如何验证是否安装成功使用pip list 查看是否存在
    使用步骤

    1. 导包
    2. 定义测试类
    3. 书写测试方法(用到的测试数据使用变量代替)
    4. 组织测试数据并传参

    代码

    import unittest
    from parameterized import parameterized
    
    data=[
        ('登录成功','登录成功'),
        ('登录成功', '登录成功'),
        ('登录成功', '登录成功1'),
    ]
    
    
    class TestLogin(unittest.TestCase):
        @parameterized.expand(data)
        def testLogin1(self,expect,retal):
            self.assertEqual(expect,retal)
    

    结果:

    C:\Users\sj176\AppData\Local\Programs\Python\Python310\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2022.1.2\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --target SeleniumD2.py::TestLogin
    Testing started at 22:16 ...
    Launching pytest with arguments SeleniumD2.py::TestLogin --no-header --no-summary -q in C:\Users\sj176\PycharmProjects\Demo3\Test1
    
    ============================= test session starts =============================
    collecting ... collected 3 items
    
    SeleniumD2.py::TestLogin::testLogin1_0__ 
    SeleniumD2.py::TestLogin::testLogin1_1__ 
    SeleniumD2.py::TestLogin::testLogin1_2__ PASSED                          [ 33%]PASSED                          [ 66%]FAILED                          [100%]
    SeleniumD2.py:11 (TestLogin.testLogin1_2__)
    '登录成功1' != '登录成功'
    
    Expected :'登录成功'
    Actual   :'登录成功1'
    <Click to see difference>
    
    a = (<SeleniumD2.TestLogin testMethod=testLogin1_2__>,)
    
        @wraps(func)
        def standalone_func(*a):
    >       return func(*(a + p.args), **p.kwargs)
    
    ..\..\..\AppData\Local\Programs\Python\Python310\lib\site-packages\parameterized\parameterized.py:533: AssertionError
    
    
    
    
    ========================= 1 failed, 2 passed in 0.07s =========================
    
    Process finished with exit code 1
    
    
    
    
    

    跳过

    对于一些未完成的或者不满足的测试条件的测试函数和测试类,不想执行,可以使用跳过装饰器来完成跳过该函数或这测试类
    直接跳过
    @unittest.skip('跳过原因')
    根据条件判断是否跳过,判断条件成立-跳过
    @unittest.skipIf('判断条件','跳过的原因')

    import unittest
    
    version=111
    class TestDemo(unittest.TestCase):
        @unittest.skip('这个测试方法不能使用了')
        def test_method1(self):
            print('测试方法1')
        @unittest.skipIf(version>=30,'版本号大于等于30不用测试')
        def test_method2(self):
            print('测试方法2')
    
        def test_method3(self):
            print('测试方法3')
    
    # 执行方法,点击执行按钮或者输入
    
    

    测试报告

    自带的测试报告
    只有单独运行TestCase的代码才会生成测试报告
    生成第三方的测试报告
    安装pip install BeautifulReport
    安装完成后注意如果使用右键执行不会输出测试报告应为执行方式是unittest需要使用python进行执行
    python SeleniumD.py

    # time :2021/1/22 15:29
    # Author :Maynard
    
    from BeautifulReport import BeautifulReport  # 需要导入BeautifulReport
    import unittest
    class TestDemoCase(unittest.TestCase):
        def setUp(self) -> None:
            pass
    
        def tearDown(self) -> None:
            pass
    
        def testassertdemo(self):
            self.assertEqual(1, 1)
    
    def suite():
        # 创建一个测试套件
        suite = unittest.TestSuite()
        # 将测试用例加载到测试套件中
        loader = unittest.TestLoader() # 创建一个用例加载对象
        suite.addTest(loader.loadTestsFromTestCase(TestDemoCase))
        return suite
    
    if __name__ == '__main__':
        br = BeautifulReport(suite())
        br.report(filename='testdemoreport.html',description='测试报告',log_path='.',report_dir='.')
    
    
    

    相关文章

      网友评论

          本文标题:Unittest

          本文链接:https://www.haomeiwen.com/subject/hqpvwrtx.html