【问题标题】:How to write clean pytest chain api tests如何编写干净的 pytest 链 api 测试
【发布时间】:2021-03-15 14:41:22
【问题描述】:

python 的新手,我对此感到困惑。从字面上看,我似乎无法在网上的任何地方找到明确而正确的答案。老实说,我觉得自己很愚蠢,因为这是一项非常基本的 Python 技能。

我的问题: 我的任务是编写一个链接在一起的异步 api 请求的 python 测试套件。我需要触发请求,保存响应 json 中的值,然后将这些值传递给后续请求。

下面列出了我希望测试做什么,以及根据我编写测试文件的方式我期望它做什么:

  1. 发送GET/users端点
  2. 将响应负载中的第一个 customerId 保存为 customer_id
  3. POST 发送到/customer/{customer_id}/addresses 端点以创建新的客户地址
  4. 将响应负载中的addressId 保存为address_id
  5. PUT 发送到/orders/{customer_id} 端点以使用步骤#3 中的address_id 更新订单。

示例代码: (这与我机器上的代码相同,但我用虚假信息清理了文件。

import requests
import json

    def first_request_get(self):
        url = 'https://api.example.net/users'

        headers = {'Content-Type': 'application/json',
                   'Authorization': 'Bearer asdfasdfasdfasdfasdfasdfasdf'
                   }

        payload = {}

        resp = requests.get(url, headers=headers, data=json.dumps(payload))

        json_str = json.dumps(payload)

        resp_body = resp.json()
        customer_id = resp_body['customer'][0]['id']
        assert resp_body['customer'][0]['id'] is not None
        assert resp.status_code == 200
        return customer_id

    def second_request_post(self):
        customer_id = self.first_request_get()
        url = 'https://api.example.net/customers/{}/addresses'.format(customer_id)

        headers = {'Content-Type': 'application/json',
                   'Authorization': 'Bearer asdfasdfasdfasdfasdfasdfasdf'
                   }

        payload = {"address1": "285 Beandip Ln",
                   "city": "Lincoln",
                   "province": "Nebraska",
                   "zip": "68510",
                   }

        resp = requests.post(url, headers=headers, data=json.dumps(payload))

        resp_body = resp.json()
        address_id = resp_body['address']['id']
        print('address_id == ')
        print(address_id)

        assert resp.status_code == 200
        assert resp_body['address']['id'] is not None
        return address_id

    def third_request_put(self):
        address_id = self.second_request_post()
        customer_id = self.first_request_get()
        url = 'https://api.example.net/orders/{}'.format(customer_id)

        headers = {'Content-Type': 'application/json',
                   'Authorization': 'Bearer asdfasdfasdfasdfasdfasdfasdf'
                   }

        payload = {"address_id": address_id,
                   "next_charge_scheduled_at": "2022-01-31T00:00:00",
                   "price": 6.85,
                   "quantity": 2,
                   }

        resp = requests.put(url, headers=headers, data=json.dumps(payload))

        resp_body = resp.json()
        subscription_id = resp_body['order']['id']
        print('order_id == ')
        print(subscription_id)
        assert resp_body['order']['id'] is not None
        assert resp.status_code == 200
        return subscription_id

执行此测试文件的结果最终会以奇怪的顺序循环文件,而不是按照我的预期执行。为什么我必须调用较早的函数才能访问我已经从 json 中提取并分配给较早函数中的变量的变量?

【问题讨论】:

    标签: python api https automated-tests pytest


    【解决方案1】:

    很遗憾,不建议以这种方式设计测试。 测试用例应该完全相互独立并且没有副作用。执行顺序应该无关紧要。 Pytest documentation 在其他来源中提到了这一点(并采取措施禁止违反这一原则)。 我还可以推荐 Glenford J Myers 的《软件测试的艺术》一书。

    因此,要使此测试正常运行,您必须将其全部放在一个方法中... 如果您想更明确地了解故障点(即使 pytest 已经做得很好了),您需要将此测试分解为多个案例,但要模拟您未明确测试的数据每个阶段。

    【讨论】:

    • 感谢您的友好、简洁和有益的回复。我需要重新学习我的 python 基础复数课程。再次感谢。
    猜你喜欢
    • 2020-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-12
    • 1970-01-01
    • 2016-04-24
    • 2011-02-15
    • 1970-01-01
    相关资源
    最近更新 更多