0

I'm practicing API testing and I'm wondering what the correct approach to dividing tests into test cases is.

For example, GET gives me a JSON which is a list of items and I want to check a few things in one of the values for each item in the list:

  • make sure it's not null
  • that it is a float
  • that the value is greater than 10

This is what I've come up with:

def test_demo():
    response = requests.get(url)
    for item in response.json():
        val = item["score"]
        assert val is not None
        assert type(val) is float
        assert val > 10.0

Is this the correct way to do it?

Is a for loop is the correct way of checking every item in a list?

Is it a good practice to have 3 assertions in one test or if I should divide each one of them into a different test?

If every test uses the same API endpoint, is it a good idea to store it in a variable at the beginning of the script?

2 Answers 2

1

These are good questions to have, especially while you are learning.

Is this the correct way to do it?

No. I mean, it's fine to get something working quickly, but you should utilize a test library and test runner for full features of setting up a test framework.

Is a for loop the correct way of checking every item in a list?

It depends. If the entire response data is different, then no. If the response data is all the same, then you could do it that way. Keep in mind, loops are slower than if you just access the data of the response variable directly.

Is it a good practice to have 3 assertions in one test or if I should divide each one of them into a different test?

Yes, you can have more than one assertion per test! People who say "one assertion per test" are working in a very old modality or might just be used to unit testing. Oftentimes, you design a test and it has multiple attributes you want to verify. Just ensure that the things you assert make sense with the test.

If every test uses the same API endpoint, is it a good idea to store it in a variable at the beginning of the script?

Yes, this is one way to do it. You want to save the response you get into a variable. The benefits are:

  • you don't make multiple API calls
  • faster performance since you're now reading saved data

Commonly, you want to setup your tests using features of your test library/runner. I recommend reading up on setup and teardown functions like beforeAll, beforeEach, afterAll, afterEach. You can call the API in the beforeAll method, save it to a variable to use in other methods.

One last thing to note: you usually don't want to validate content/data since it's always changing. APIs are often CRUD in nature, so a good test would be to follow the CRUD methodology: create new data, read the data, update the data, delete the data. This gives you full control over the data to test and a good level of confidence in a working system! (I say usually but there are times when it is necessary. Like a lot of things in tech, the answer is about context, not a hard and fast "rule.")

0

For starters, the check for null is not necessary, as the other checks validate that you have a float type (which is not a null).

Secondly, the problem with your implementation is that it will stop as soon as one error occurs, leaving all other items in unchecked.

For this, you can use soft assertions.

With the softtest library, you can do like this:

response = requests.get(url)
for item in response.json():
   val = item["score"]
   self.soft_assert(self.assertTrue, isinstance(val, float), f"The type of ${item} score is not float")
   self.soft_assert(self.assertTrue, val > 10.0, f"The value of f${item} score is not greater than 10")

self.assert_all()

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.