0

New-ish to python and I'm stumped on this. I literally cannot seem to find a clear and correct answer anywhere online. I honestly feel stupid because this is a pretty basic python skill.

My issue: I've been tasked with writing a python test suite of asyncronous api requests chained together. I need to fire the requests, save values from the response json, then pass those values into subsequent requests.

Below is a list of what I WANT the test to do, and what I would expect it to do based on how I've written the test file:

  1. Send GET to /users endpoint
  2. Save first customerId from response payload as customer_id
  3. Send POST to /customer/{customer_id}/addresses endpoint to create new customer address
  4. Save addressId from response payload as address_id
  5. Send PUT to /orders/{customer_id} endpoint to update order with the address_id from step #3.

Example Code: (This is the same code I have on my machine, but I've sanitized the file with fake info.

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

The result of executing this test file ends up looping through the file in a weird order rather than doing what I would expect it to do. Why do I have to call an earlier function just to access the variable I've already extracted from the json and assigned to a variable in an earlier function?

1 Answer 1

2

Unfortunately, it's not advised to design your tests this way. Testcases should be completely independent of one another and have no side effects. The order of execution should not matter. The Pytest documentation among other sources makes reference to this (and takes steps to disallow violating this principle). I can also recommend the book "The Art of Software Testing" by Glenford J Myers.

As such, to make this test work, you're going to have to place it all in one method... If you'd like to be more explicit about the point of failure (even though pytest does a pretty good job already), you'll want to break this test up into multiple cases, but mock the data you're not explicitly testing at each stage.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the kind, concise, and helpful reply. I need to revisit my python fundamentals pluralsight courses. Thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.