zoukankan      html  css  js  c++  java
  • unittest测试基本操作

    一、unittest中的四大金刚

    TestCase:测试用例,通过继承unittest.TestCase,实现用例的继承,在UnitTest中,一个testcase的实例就是一个测试用例。测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown),(注:测试用例都是通过开头以tes来识别的)
    TestSuite:测试套件,也就是上面的测试用例集
    TestFixture:setUp(前置条件),tearDown(后置条件),用于初始化测试用例以及清除和释放资源
    TestRunner:运行器,一般通过runner来调用suite去执行测试
    二、unittest的初级使用

    1.代码演示:

    # 第一步:导入unittest模块
    import unittest
     
     
    # 第二步: 创建一个测试类,被继承unittest.TestCase
    class unittest_demo(unittest.TestCase):
     
    # 第三步:重写setUp和tearDown方法(如果有初始化条件和结束条件)、
     
        # 这是TestCases执行前的初始化
        @classmethod
        def setUpClass(cls):
            print("TestCases Begin...")
     
        # 这是TestCases执行后的回收操作
        @classmethod
        def tearDownClass(cls):
            print("TestCases End...")
     
        # 这是每个test case执行前的初始化
        def setUp(self):
            print("Begin...")
     
        # 这是每个test case执行后的测试回收
        def tearDown(self):
            print("End...")
     
    # 第四步:定义测试函数,函数名以test_开头。测试用例
        def test_1(self):
            print("this it the first case")
     
        def test_2(self):
            print("this is the second case")
     
        def test_3(self):
            # 第四步:在函数体中使用断言来判断测试结果是否符合预期结果
            self.assertEqual(3, 3, msg="条件不成立")
            print("this is tne third case")
     
     
    # 第五步:调用unittset.main()方法运行测试用例--------无此方法也是可以运行
    if __name__ == 'main':
        unittest.main(verbosity=1)
    ————————————————
    版权声明:本文为CSDN博主「小曹老师真可爱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/ahjd123czy/java/article/details/104973336


    2.执行结果:

     

    说明:可以看出setUpClass(cls)在测试用例前执行一次,tearDownclass(cls)在测试用例执行后执行一次,是以测试类为单位。而setUp(self)跟tearDown(self)都是每个测试函数执行前、后各执行一次,是以测试函数为单位。

    疑问:1.为什么类前置条件括号中为cls,而测试函数前置条件括号中为self?

    答:self表示一个具体的实例本身,cls表示这个类本身

               2.为什么setUpClass方法前面要用装饰器@classmethod?

    答:

    三、unittest中数据驱动

    在设计用例的时候,有些用例只是参数数据的输入不一样,比如登录这个功能,操作过程但是一样的。如果用例重复去写操作过程会增加代码量,对应这种多组数据的测试用例,可以用数据驱动设计模式,一组数据对应一个测试用例,用例自动加载生成。

    第一种:直接以list方式传递

    ddt中最基本的应用l:在class前定义@ddt,用于表示要使用ddt,再基于实际的应用,选择对应的装饰器。

    如@ddt.data():用于设定参数,解析方式为,解析一个,传参一个

       @ddt.unpack():用于解析参数

    1.实战演习:

    # 第一步:导入ddt模块
    import unittest
    import ddt
    
    
    # 测试类前加修饰@ddt.ddt
    @ddt.ddt
    class unittest_ddt_demo(unittest.TestCase):
    def setUp(self):
    print("Begin''''")
    
    def tearDown(self):
    print("End''''")
    
    # case前加修饰@ddt.data(),运行后会自动加载成两个单独的用例
    @ddt.data(["张三", "pw1"], ["李四", "pw2"])
    # @ddt.unpack
    def test_1(self, username, password):
    print("username:",username,"---","password:",password)
    
    def test_2(self):
    print("无数据驱动测试")
    
    
    if __name__ == 'main':
    unittest.main(verbosity=1)


    2.运行结果:

     

    说明:发现报错了,根据错误提示可以看出,少传参数了,因为数据解析时把["张三", "pw1", "OK"]单成一个整体,及认为是第一个参数username的值,所以我们这里要自己解析参数,故添加装饰器@ddt.unpack,最终运行结果为:

    第二种:以函数方式传输

    1.实战演习:

    # 第一步:导入ddt模块
    import unittest
    import ddt
    
    
    def readFile():
    params = []
    file = open('params.txt', 'r', encoding='utf-8')
    for line in file.readlines():
    params.append(line.strip('
    ').split(','))
    return params
    
    
    # 测试类前加修饰@ddt.ddt
    @ddt.ddt
    class unittest_ddt_demo(unittest.TestCase):
    def setUp(self):
    print("Begin''''")
    
    def tearDown(self):
    print("End''''")
    
    # case前加修饰@ddt.data(),运行后会自动加载成两个单独的用例
    @ddt.data(*readFile())
    @ddt.unpack
    def test_1(self, username, password):
    print("username:", username, "---", "password:", password)
    
    def test_2(self):
    print("无数据驱动测试")
    
    
    if __name__ == 'main':
    unittest.main(verbosity=1)
    
    """
    params.txt文件内容为:
    username=张三,password=pw1
    username=李四,password=pw2
    """


    2.运行结果:

     

    第三种:以文件方式传输

    1.文件格式:

     

    2.实战演习:

    # 第一步:导入ddt模块
    import unittest
    import ddt
    import yaml
    
    # file = open('test.yml', encoding="utf-8")
    # res = yaml.load(file)
    # print(res)
    
    
    # 测试类前加修饰@ddt.ddt
    @ddt.ddt
    class unittest_ddt_demo(unittest.TestCase):
    def setUp(self):
    print("Begin''''")
    
    def tearDown(self):
    print("End''''")
    
    # case前加修饰@ddt.data(),运行后会自动加载成两个单独的用例
    @ddt.file_data('test.yml')
    # @ddt.unpack
    def test_1(self, **kwargs):
    print('传入的参数值为:', kwargs)
    print("最终的测试结果是:username:", kwargs.get('username'), "---", "password:", kwargs.get('password'))
    
    def test_2(self):
    print("无数据驱动测试")
    
    
    if __name__ == 'main':
    unittest.main(verbosity=1)
    
    """
    运行结果:
    Begin''''
    传入的参数值为: {'username': '张三', 'password': 'pass1'}
    最终的测试结果是:username: 张三 --- password: pass1
    End''''
    Begin''''
    传入的参数值为: {'username': '李四', 'password': 'pass2'}
    最终的测试结果是:username: 李四 --- password: pass2
    End''''
    Ran 3 tests in 0.014s
    OK
    Begin''''
    无数据驱动测试
    End''''
    """
    备注:基于复杂的情况,可能要对读取的文件进行拆包读取等

    四:unittest中断言

    断言是一个自动化的灵魂,断言做的好不好,能不能一阵见血,实在太重要了,是整个测试流程的核心部分。这里找到一篇很好的断言总结

    链接:https://www.cnblogs.com/ruichow/p/12083833.html

    五:unittest中运行测试用例集

    四种运行方式均可以:

    import unittest
    from test_unittest.fortest import *
    import HTMLTestRunner
    
    #方法一:
    # 创建一个测试套件 list
    # suite = unittest.TestSuite()
    
    # 添加测试用例(子元素)到测试套件(集合)
    # suite.addTest(unittest_demo('test_case1'))
    # suite.addTest(unittest_demo('test_case2'))
    
    # 套件通过TextTestResult对象进行运行~unittest.main()
    # runner = unittest.TextTestRunner()
    # runner.run(suite)
    
    #方法二:
    # case = [unittest_demo('test_case1'),unittest_demo('test_case2')]
    # suite = unittest.TestSuite()
    # suite.addTests(case)
    # runner = unittest.TextTestRunner()
    # runner.run(suite)
    
    #方法三:
    # test_dir = './'
    # discover = unittest.defaultTestLoader.discover(start_dir=test_dir, pattern='for*.py')
    # runner = unittest.TextTestRunner()
    # runner.run(discover)
    
    #方法四:
    # suite = unittest.TestSuite()
    # suite.addTests(unittest.TestLoader().loadTestsFromName('fortest.unittest_demo'))
    # runner = HtmlTestRunner.HTMLTestRunner(output='MyUnitTest')
    # runner.run(suite)


    六:生成HTML和XML格式的测试报告

    第一步:下载HTMLTestRunner.py文件,修改后放在python安装目录的Lib目录下

    第二步:修改HTMLTestRunner.py文件,因为该文件是基于Python2语法写的,不适于Python3

    第三步:修改点:参照链接:https://blog.csdn.net/SCF_1104/article/details/86033979

      备注:美化后的报告:https://github.com/findyou/HTMLTestRunnerCN

    1.简单执行:
    
    from test_unittest.fortest import *
    import HtmlTestRunner
    import os
    
    report_path = './report/'
    report_file = report_path + 'report.html'
    if not os.path.exists(report_path):
    os.mkdir(report_path)
    else:
    pass
    with open(report_file, 'wb') as report:
    suite = unittest.TestSuite()
    suite.addTests(unittest.TestLoader().loadTestsFromName('fortest.unittest_demo'))
    runner = HtmlTestRunner.HTMLTestRunner(verbosity=2, output="./reports/", report_title='Test Report',
    descriptions=True, report_name='unittest study')
    runner.run(suite)
    report.close()
    """
    HTMLTestRunner可用参数:
    def __init__(self, output="./reports/", verbosity=2, stream=sys.stderr,
    descriptions=True, failfast=False, buffer=False,
    report_title=None, report_name=None, template=None, resultclass=None,
    add_timestamp=True, open_in_browser=False,
    combine_reports=False, template_args=None):
    """

    2.测试报告:

     

    七:可能会遇到的问题:

    1.导入模块之后,还是提示HtmlTestRunner模块不存在:

    第一:将HTMLTestRunner.py拷贝到python安装目录的Libsite-packages,注意不要搞错位置了

    第二:如果第一操作过还不行,那么:如果在PyCharm中使用import HTMLTestRunner报错,需要设置项目的python解释器为自己安装的python
     

  • 相关阅读:
    webform--常用的控件
    .net嵌入c#代码(投票练习)
    webform之session传值(临时数据的存储)与扩展属性 --(购物车练习)
    ASP.NET aspx页面中 写C#脚本; ASP.NET 指令(<%@%>);
    LinQ操作
    什么是C# Lambda表达式?形如:p=>p.abc
    winform基础
    3D计算机图形学读书笔记—Wat版本
    计算机图形学的领域与分类
    NetBeans中文乱码解决办法
  • 原文地址:https://www.cnblogs.com/jodie2019/p/13035288.html
Copyright © 2011-2022 走看看