美文网首页
python自动化测试 第 8 章.单元测试unittest模块

python自动化测试 第 8 章.单元测试unittest模块

作者: 失忆的蝴蝶 | 来源:发表于2021-12-04 12:37 被阅读0次

    py文件名不要用大写英文字母开头,因为在Linux系统中是区分大小写的,而在Windows系统是不区分大小写的,为了代码也能在Linux系统顺利运行,所以一般不使用大写字母开头命名py文件和包

    1、在当前脚本调试代码__name__

    在脚本下方使用if __name__ == '__main__'语句可以运行当前脚本代码。

    • __name__是模块的特殊变量
    • 当直接执行当前模块的时候__name__就等于'__main__'
      所以,if __name__ == '__main__'这个语句成立,可以执行这个条件下的语句
    • 当被其他模块导入的时候__name__ = 模块名
      所以,if __name__ == '__main__'这个语句不成立,不会执行这个条件下的语句
    def login_check(username, password):
        """
        登录校验的函数
        :param username: 账号
        :param password: 密码
        :return:
        """
        if 6 <= len(password) <= 18:
            if username == 'python34' and password == 'lemonban':
                return {"code": 0, "msg": "登录成功"}
            else:
                return {"code": 1, "msg": "账号或密码不正确"}
        else:
            return {"code": 1, "msg": "密码长度在6-18位之间"}
    
    print(__name__) # 输出__main__
    
    if __name__ == '__main__':
        # 这个里面的代码只有直接执行当前脚本的时候才会运行,
        # 别的代码导入当前脚本,不执行
        print('我执行了')
    

    2、unittest模块

    2.1使用步骤

    先看下面代码,再逐步分析

    import unittest
    from login import login_check
    
    
    class TestLogin(unittest.TestCase):
        """
        测试登录功能
        """
        def test_login_ok(self, username, password):
            """
            账号和密码都正确
            :return:
            """
            # 1、测试数据
            test_data = {"username": "tony", "password": "aabbcc123"}
            # 2、期望数据
            expect_data = {"code": 1, "msg": "账号或密码不正确"}
            # 3、执行函数
            res = login_check(**test_data)
            # 4、断言
            self.assertEqual(expect_data, res)
    
    
    if __name__ == '__main__':
        # 5. 调用unittest.main()来执行测试用例
        unittest.main()
    
    • 1、导入unitest模块和待测试函数
    import unittest
    from login import login_check
    
    • 2、创建测试类,并继承unittest.TestCase
    class TestLogin(unittest.TestCase):
        """
        测试登录功能
        """
    
    • 3、创建测试函数
    def test_login_ok(self, username, password):
            """
            账号和密码都正确
            :return:
            """
    

    3.1 创建测试数据

    test_data = {"username": "tony", "password": "aabbcc123"}
    

    3.2 创建期望数据

    expect_data = {"code": 1, "msg": "账号或密码不正确"}
    

    3.3 执行函数

    res = login_check(**test_data)
    

    3.4 断言

    self.assertEqual(expect_data, res)
    
      1. 调用unittest.main()来执行测试用例
    if __name__ == '__main__':
        #  调用unittest.main()来执行测试用例
        unittest.main()
    

    2.2 利用main模块来执行测试用例

    2.2.1收集测试套件(两个方法:手动收集和自动收集)

    方法一:手动收集(不常用)

    第一步:实例化测试套件
    ts = unittest.TestSuite()
    
    第二步:收集测试套件
    • 手动收集测试套件(addTest与addTests)
      • addTest一个个添加测试套件 语法:测试套件addTest(测试用例类名('单元测试方法名'))
    ts.addTest(TestStrUpper('test_str_upper')) 
    #TestStrUpper 测试用例类名
    #'test_str_upper'   是  '单元测试方法名'
    
    • addTest一次添加多个测试套件 语法:以列表的形式输入 -->测试用例类名('单元测试方法名')
    ts.addTests([TestLogin('test_login_ok'), TestLogin('test_login_password_err')])
    

    看下代码汇总效果:

    ts = unittest.TestSuite()
    # 一个个收集测试套件
    # 单元测试的语法: 测试用例类名('单元测试方法名')
    ts.addTest(TestStrUpper('test_str_upper'))
    ts.addTests([TestLogin('test_login_ok'), TestLogin('test_login_password_err')])
    print(ts)
    

    输入结果如下:

    <unittest.suite.TestSuite tests=[<test_demo.TestStrUpper testMethod=test_str_upper>, 
    <test_case.TestLogin testMethod=test_login_ok>, <test_case.TestLogin testMethod=test_login_password_err>]>
    

    addTest收集了一个测试套件,addTests收集了两个测试套件,所以print(ts)的输出结果中看到一共收集了三个测试套件。
    但是此方法太麻烦,每个测试用例都要收到添加,不科学,所以此方法不常用;常用自动收集测试套件方法,就是下面介绍的第二个方法

    方法二:自动收集(常用)

    自动收集又分为两种情况,第一种是通过收集器TestLoader对象,通过模块、测试用例类、测试方法名来收集测试用例,这样也是需要导入模块、测试用例类或者测试方法名

    情况1(不常用):通过模块、测试用例类、测试方法名来收集测试用例

    - 第一步:实例化收集器TestLoader
    - 第二步:通过TestLoader收集测试用例

    image.png
    import unittest
    import test_case
    # TestLoader对象,收集器
    td = unittest.TestLoader()  # 第一步:实例化收集器TestLoader
    ts = td.loadTestsFromModule(test_case)#第二步:通过TestLoader收集测试用例
    print(ts)
    
    情况2(常用):通过目录自动收集测试用例

    TestLoader有个discover方法:
    - start_dir 开始查找的目录 递归的去所有目录下查找,开始目录下的所有文件夹中的文件(目录下一定要有__init__.py)
    - pattern 查找模块名的规则 test*.py 以test开头的模块,收集里面的测试用例
    - top_level_dir 项目的顶层目录
    一般只传开始目录一个参数 start_dir
    代码如下:

    td = unittest.TestLoader()
    ts = td.discover('.') # .表示当前目录
    print(ts, type(ts))
    

    测试用例收集顺序(也是测试用例执行顺序)规则:

    • 按照ascii码的顺序:先按照模块名进行收集,再按照在模块中类里的测试函数名
      可以在test后面添加数字来指定哪个模块、函数来收集、执行测试用例:
      模块:test01.py -- test02.py -- test03*.py,可以按照这个方式来指定顺序来收集测试用例
      模块中类的测试函数名:test01_login_password_less5(self) -- test02_login_username_err(self) -- test03_login_password_err(self):

    python3中文件夹中没有__int__.py文件也认为此文件夹也是一个包,但是unitest例外,如果文件夹中没有__int__.py文件,就不认为它是一个包,所以使用discover方法查找测试用例时,如果开始目录下的文件夹没有__int__.py文件就不会查找此文件夹。

    2.2.2执行测试

    • 实例化运行器
    • 传入测试套件

    1、文本测试运行器执行测试用例(不常用)

    #用文本测试运行器实例化运行器
    runner = unittest.TextTestRunner()
    # 传入测试套件
    runner.run(ts)
    

    总结一下main模块中的代码

    import unittest  #导入unittest模块
    if __name__ == '__main__':
      td = unittest.TestLoader()  #实例化测试套件
      ts = td.discover('.')  #通过测试套件,用目录查找的方式收集测试用例
      runner = unittest.TextTestRunner()  #实例化运行器
      runner.run(ts)  #传入测试套件运行
    

    2、HTMLTestRunnner运行器执行测试用例

    需要HTMLTestRunnerNew模块

    import unittest
    from HTMLTestRunnerNew import HTMLTestRunner
    if __name__ == '__main__':
        td = unittest.TestLoader()
        ts = td.discover('.')
        with open(r'D:\Pycharm_workspace\day15u\report.html', 'wb') as f:
            runner = HTMLTestRunner(stream=f, title='第一份测试报告', description='测试登录功能', tester='Leo')
            runner.run(ts)
    

    3、BeautifulReport运行器执行测试用例(常用)

    import unittest
    from BeautifulReport import BeautifulReport
    if __name__ == '__main__':
        td = unittest.TestLoader()
        ts = td.discover('.')
        # 实例化,并传入测试套件
        br = BeautifulReport(ts)
        br.report(filename='bf_测试报告.html', description='测试登录功能', report_dir=r'D:\Pycharm_workspace\day15u')
    

    3、测试脚手架

    unittest中的TestCase提供的一系列方法,它会在测试用例测试前,测试后执行

    3.1在每个测试用例前都执行

    1. setUP 在每个单元测试函数开始前执行
    2. tearDown 在每个测试函数结束后执行

    3.2在整个测试用例类开始执行前执行

    是类方法,需要装饰器

    class TestLogin(unittest.TestCase):
        """
        测试登录功能
        """
        def setUp(self) -> None:
            """
            测试函数前置
            :return:
            """
            print("每个函数执行前都执行")
    
        def tearDown(self) -> None:
            """
            测试函数后置
            :return:
            """
            print("每个函数执行后都执行")
    
        @classmethod
        def setUpClass(cls) -> None:
            """
            测试类前置
            :return:
            """
            print('在整个测试用例类开始测试前执行')
    
        @classmethod
        def tearDownClass(cls) -> None:
            """
            测试类后置
            :return:
            """
            print('在整个测试用例类结束测试后执行')
    
        def test_login_ok(self):
            """
            账号和密码都正确
            :return:
            """
    

    相关文章

      网友评论

          本文标题:python自动化测试 第 8 章.单元测试unittest模块

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