zoukankan      html  css  js  c++  java
  • fixture参数化精简测试代码

    一、前言

      Pytest测试框架中的fixture,可以将自动化测试用例中的前置、后置部分分离出来放入其中,然后在写测试用例的时候只需要写测试逻辑相关的代码,提高代码的复用性,同时也有利于代码的维护。

      本文重点介绍的是fixture参数化,关于fixture的基础知识可以查看这个链接:https://www.cnblogs.com/zdx20/p/14948134.html

    二、测试场景介绍

      我们以下面App自动化测试,订酒店的测试场景为例,来说明:

      上图中有三个测试场景:

       1、编辑姓名;

       2、编辑手机号;

       3、编辑身份证。

      这三个场景主要的测试逻辑都在酒店的编辑订单页,通过fixture参数化功能可以很好的精简测试代码。

     三、fixture和fixture参数化

         1、按照上面的流程编写自动化测试用例:

    import pytest
    
    login_data = [{"user_name": "xiaowang", "pwd": 123456, "date": 1, "name": "小王"}]
    
    @pytest.mark.parametrize("test_data", login_data)
    def test_hotel(test_data):
        # 登录App
        print("
    " + "1、登录App, 账号和密码是:", test_data["user_name"], test_data["pwd"])
        # 酒店首页选择入住日期
        print("2、酒店首页选择日期:{}号".format(test_data["date"]))
        # 酒店列表选择酒店
        print("3、选择想要预订的酒店和房型")
        # 编辑酒店页面,输入入住人姓名
        print("4、输入入住人姓名:", test_data["name"])
        # 断言下单结果
        print("5、恭喜,酒店预订成功了!!!")

      上面的用例就是没有使用前置/后置分离代码,虽然可以完成UI自动化测试的一个测试场景任务,但是后续用例多了维护会非常头疼,而且不具有扩展性。

      2、fixture的前置、后置

      在每条用例中都需要登录App,然后执行测试过程,最后断言测试结果。我们可以将登录,和测试结果断言剥离出来放在fixture当中,这样同类型的测试场景就可以直接调用。

    import pytest
    
    hotel_data = [{"date": 1, "name": "小王"}]
    
    @pytest.fixture()
    def fix_login():
        # 登录App
        print("
    " + "1、前置条件--登录App, 账号和密码是:", "xiaowang", 123456)
        yield
        # 断言下单结果
        print("5、后置条件--恭喜,酒店预订成功了!!!")
    
    @pytest.mark.parametrize("test_data", hotel_data)     # 测试数据的参数化
    def test_hotel(test_data, fix_login):
        # 酒店首页选择入住日期
        print("2、酒店首页选择日期:{}号".format(test_data["date"]))
        # 酒店列表选择酒店
        print("3、选择想要预订的酒店和房型")
        # 编辑酒店页面,输入入住人姓名
        print("4、输入入住人姓名:", test_data["name"])

     执行结果如下:

     1、前置条件--登录App, 账号和密码是: xiaowang 123456
     2、酒店首页选择日期:1号
     3、选择想要预订的酒店和房型
     4、输入入住人姓名: 小王
     5、后置条件--恭喜,酒店预订成功了!!!

      上面的测试用例方法中,测试数据是通过@pytest.mark.parametrize()传入的,有几组测试数据就会生成几条测试用例,详细的使用方法可以查看“前言”部分提到的链接。

      3、fixture参数化

      通过fixture我们将用例的前置和后置条件摘出来了,但是前置条件登录的数据是固定的,通用性不强,需要将fixture的测试数据也参数化。

      fixture参数化传参的方法与用例的传参是一样的,也是使用@pytest.mark.parametrize()传入,但是需要加一个参数:indirect=True,指定将参数传入fixture测试夹具中。fixture测试夹具的方法中使用request接受传入的参数,然后通过request.param使用具体的数据。

    import pytest
    
    login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
    test_data = [{"date": 1, "name": "小王"}]
    
    @pytest.fixture()
    def fix_login(request):
        # 接收传入的数据
        test_info = request.param
        # 登录App
        print("
    " + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
        yield
        # 断言下单结果
        print("5、后置条件--恭喜,酒店预订成功了!!!")
    
    @pytest.mark.parametrize("fix_login", login_data, indirect=True)       # fixture测试夹具的参数化
    @pytest.mark.parametrize("test_info", test_data)                       # 测试用例的参数化
    def test_hotel(test_info, fix_login):
        # 酒店首页选择入住日期
        print("2、酒店首页选择日期:{}号".format(test_info["date"]))
        # 酒店列表选择酒店
        print("3、选择想要预订的酒店和房型")
        # 编辑酒店页面,输入入住人姓名
        print("4、输入入住人姓名:", test_info["name"])

      上面登录的前置条件中,传入了两组账号、密码数据,那么在执行用例时,同一个用例场景会分别使用两个账号测试一遍。

      同时等到两个执行结果:

         fixture参数化,需要注意接收参数的标识符,用例中调用测试夹具的标识符,以及测试夹具的方法名要一致。

       现在测试场景只写了一个:编辑姓名,后面的编辑手机号、编辑身份证号两个场景,直接套用现有的测试用例即可。

      4、拆分多个fixture

      前面提到我们需要测试的三个酒店场景,前面几个步骤“酒店首页”、“酒店列表页”都是一样的,而且后续还有其他用例也需要用到“酒店首页”或者“酒店列表页”,因此我们需要不同页面的前置条件来满足不同测试场景,这就有了很多个测试夹具,不利于代码的维护。我们可以按照一个页面一个前置夹具的方法来细分测试场景,写用例时按照顺序去调用即可。

    import pytest
    
    login_data = [{"user_name": "xiaowang", "pwd": 1234}]
    test_data = [{"date": 11, "name": "小王", "result_data": "通过"}]
    
    @pytest.fixture()
    def fix_login(request):
        # 接收传入的数据
        test_info = request.param
        # 登录App
        print("
    " + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
    
    @pytest.fixture()
    def home_page(request):
        # 接收传入的数据
        test_info = request.param
        # 酒店首页选择入住日期
        print("2、酒店首页选择日期:{}号".format(test_info["date"]))
    
    @pytest.fixture()
    def list_page():
        # 酒店列表选择酒店
        print("3、选择想要预订的酒店和房型")
    
    @pytest.fixture()
    def result(request):
        yield
        # 接收传入的数据
        test_info = request.param
        # 断言下单结果
        print("5、后置条件--恭喜,酒店预订成功了,结果:{}!!!".format(test_info["result_data"]))
    
    @pytest.mark.parametrize("result", test_data, indirect=True)
    @pytest.mark.parametrize("home_page", test_data, indirect=True)
    @pytest.mark.parametrize("fix_login", login_data, indirect=True)
    @pytest.mark.parametrize("test_info", test_data)
    def test_name(test_info, fix_login, home_page, list_page, result):
        # 编辑酒店页面,输入入住人姓名
        print("4、输入入住人姓名:", test_info["name"])

      执行结果如下:

      1、前置条件--登录App, 账号和密码是: xiaowang 1234
      2、酒店首页选择日期:11号
      3、选择想要预订的酒店和房型
      4、输入入住人姓名: 小王
      5、后置条件--恭喜,酒店预订成功了,结果:通过!!!

      ###注意:在测试用例方法中同时调用多个fixture夹具时,一定要按照测试逻辑顺序来,执行用例时会按照测试夹具调用先后顺序执行。

      4.1、fixture测试夹具添加顺序

      测试用例方法中调用测试夹具时需要注意先后顺序,不然测试逻辑会混乱。如果你不想在调用时出现这个问题,可以在编写多个测试夹具时,测试夹具之间按照逻辑先后顺序调用,这样在写用例时就不用考虑先后顺序问题,而且不需要传参的测试夹具不用调用也能执行。

     测试用例方法调用:

    、使用params参数

      1、fixture的params参数

      fixture测试夹具的参数化除了上面用到的@pytest.mark.parametrize(),还有一种是直接在测试夹具的fixture中传参,使用params=即可。

    import pytest
    
    login_data = [{"user_name": "xiaowang", "pwd": 1234}, {"user_name": "zhaosi", "pwd": 6789}]
    test_data = [{"date": 1, "name": "小王"}]
    
    @pytest.fixture(params=login_data)          # fixture测试夹具的参数化
    def fix_login(request):
        # 接收传入的数据
        test_info = request.param
        # 登录App
        print("
    " + "1、前置条件--登录App, 账号和密码是:", test_info["user_name"], test_info["pwd"])
        yield
        # 断言下单结果
        print("5、后置条件--恭喜,酒店预订成功了!!!")
    
    @pytest.mark.parametrize("test_info", test_data)          # 测试用例的参数化
    def test_hotel(test_info, fix_login):
        # 酒店首页选择入住日期
        print("2、酒店首页选择日期:{}号".format(test_info["date"]))
        # 酒店列表选择酒店
        print("3、选择想要预订的酒店和房型")
        # 编辑酒店页面,输入入住人姓名
        print("4、输入入住人姓名:", test_info["name"])

      fixture的参数化就介绍到这里。

  • 相关阅读:
    POJ 1015 Jury Compromise【DP】
    POJ 1661 Help Jimmy【DP】
    HDU 1074 Doing Homework【状态压缩DP】
    HDU 1024 Max Sum Plus Plus【DP,最大m子段和】
    占坑补题。。最近占的坑有点多。。。
    Codeforces 659F Polycarp and Hay【BFS】
    Codeforces 659E New Reform【DFS】
    Codeforces 659D Bicycle Race【计算几何】
    廖大python实战项目第四天
    廖大python实战项目第三天
  • 原文地址:https://www.cnblogs.com/zdx20/p/15203408.html
Copyright © 2011-2022 走看看