• 八、pytest(用例筛选/断言/测试报告/数据驱动)


    一、用例筛选

    unittest  手动添加测试用例:   suite.addTests( )

    pytest     在需要筛选的用例的上添加@pytest.mark.smoke 

    • 在pytest.ini文件中加上标签名:smoke

    • 在TestLogin类上面加@pytest.mark.smoke

    • terminal中运行 pytest -m "smoke"

    标记整个类:类上面加 @pytest.mark.tagname

    标记的组合:

    - and  必须同时具备两个标签,pytest -m "demo and error"

    - or  只需要满足其中的一个标签,就会运行   pytest -m "demo or error"

    - not    "success and not demo"

    import pytest
    from futureloan_web.middleware.MiddleHandler import MidInitHandler
    from middleware.pages.login import LoginPages
    from data.login_data import login_error,login_success,login_invalid
    
    class TestLogin():
        '''登录'''
        handler = MidInitHandler()
    
        @pytest.mark.error
        @pytest.mark.parametrize("test_info", login_error)
        def test_login_error(self,test_info,driver):
            login_page = LoginPages(driver)
            actual = login_page.get().login_fail(
                username=test_info["username"],
                password=test_info["password"],
            ).get_error_message()
    
            # 实际结果和预期结果比对,日志记录,错误处理
            try:
                assert actual == test_info["expected"]
                self.handler.logger.info("测试用例通过")
            except AssertionError as e:
                self.handler.logger.error("测试用例不通过")
                raise e
    
    
        @pytest.mark.success
        @pytest.mark.parametrize("test_info", login_success)
        def test_login_success(self,test_info,driver):
            login_page = LoginPages(driver)
            actual = login_page.get().login_success(
                username=test_info["username"],
                password=test_info["password"],
            ).get_account_name()
    
            # 实际结果和预期结果比对,日志记录,错误处理
            try:
                assert actual == test_info["expected"]
                self.handler.logger.info("测试用例通过")
            except AssertionError as e:
                self.handler.logger.error("测试用例不通过")
                raise e
    
        @pytest.mark.error
        @pytest.mark.parametrize("test_info", login_invalid)
        def test_login_invalid(self,test_info,driver):
            """登录未授权"""
            login_page = LoginPages(driver)
            actual = login_page.get().login_fail(
                username=test_info["username"],
                password=test_info["password"]
            ).get_invalid_message()
    
            try:
                assert actual == test_info["expected"]
            except AssertionError as e:
                self.handler.logger.error("测试用例不通过")
                raise e

    注意:用例标记的时候,标签如果有逻辑运算,一定要加双引号

    一个类或者是方法或者是函数,都可以加多个标签,直接在他们的上面打多个标签即可 

    @pytest.mark.smoke 
    @pytest.mark.error 
    def test_demo_no_class(self): 
        pass

    二、断言

     --unittest断言使用asserTrue/assertEqual等系列,如assertTrue(v == resp[k])

    --pytest断言使用内置的关键字 assert,如assert   v == resp

    try:
       assert actual == test_info["expected"]
    except AssertionError as e:
       self.handler.logger.error("测试用例不通过")
       raise e

    三、测试报告

     安装:pip install pytest-html

    执行:pytest -m "demo" --html=reports.html

    时间戳生成测试报告:使用脚本方式运行:run.py

    "运行测试用例"
    import pytest
    import datetime
    ts = datetime.datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    
    if __name__ == '__main__':
        pytest.main(["--html={}report.html".format(ts)])

    如果是多个参数: pytest.main(['--html={}.html'.format(ts),"-m demo"])

    用例的执行顺序:从上到下

    四、数据驱动

    用unittest框架去测试

    import unittest
    import ddt
    from lenom.aa import ExcelHandler
    
    def login(username=None, password=None):
        """登录"""
        if (not username) or (not password):
            # 用户名或者密码为空
            return {"msg": "empty"}
        if username == 'yuz' and password == '123456':
            # 正确的用户名和密码
            return {"msg": "success"}
        return {"msg": "error"}
    
    cases = ExcelHandler('cases.xlsx').read_data('login')
    
    @ddt.ddt
    class TestLogin(unittest.TestCase):
    
        @ddt.data(*cases)
        def test_login(self,case_info):
            data = eval(case_info['data'])
            username = data["username"]
            password = data["password"]
            expected_response = case_info["expected"]
            actual_response = login(username, password)
            self.assertTrue(expected_response == actual_response['msg'])

    用pytest 进行数据驱动

    import pytest
    from data.login_data import login_success,login_error
    from middleware.pages.login import LoginPage
    from middleware.MiddleHandler import MidInitHandler
    
    
    class TestLogin:
        """登录"""
        handler = MidInitHandler()
    
        @pytest.mark.parametrize("test_info", login_error)
        def test_login_fail(self,test_info,driver):
            """登录失败"""
            login_page = LoginPage(driver)
            actual = login_page.get().login_fail(
                username=test_info["username"],
                password=test_info["password"],
            ).get_error_message()
            try:
                assert test_info["expected"] in actual
                self.handler.logger.info("测试用例通过:{}".format(test_info["title"]))
            except Exception as e:
                self.handler.logger.error("测试用例不通过:{}".format(test_info["title"]))
                raise e

    注意:两个test_info名称必须一致

              在使用pytest.mark.paramatrize 做数据驱动的时候,pytest 和 unittest 不兼容

         如果你想使用 pytest 的数据驱动,就不要继承 unittest.TestCase

         如果你想使用 unittest写用例,  就要用 unittest 的数据驱动

  • 相关阅读:
    菜根谭#188
    菜根谭#187
    Single value range only allowed in SystemVerilog
    LUTs, Flip-Flop, Slice
    FPGA 的 RAM 的 区别
    GPU core clock, shader clock ???
    更改Mac的Terminal 格式
    GPU share memory 的应用 (主要内容转载)
    Mac text edit & pdf reader
    Programming Font
  • 原文地址:https://www.cnblogs.com/zhangjx2457/p/13800098.html
Copyright © 2020-2023  润新知