Interface automatic test, one key quick verification of all fields of interface return value

Hello, I'm erhei

A set of software testing related resources is presented here:

  • Software testing related tools
  • Software testing practice set
  • In depth automated testing
  • Learning Python
  • Python coding specification
  • Large factory interview questions and resume template

Pay attention to my official account: two free programmers can receive them.
Communication group: 642830685

In order to ensure the effectiveness of the interface test, we have to check and assert the response fields returned by the interface when we carry out the daily automatic test. When the number of fields returned by the interface itself is small, the interface assertion operation is generally easy to implement. However, when the number of returned fields of the interface is particularly large and the structure is particularly complex, for example, when the number of response fields reaches hundreds or thousands, how to quickly verify all returned fields? I believe this kind of problem puzzles many small partners who are carrying out interface testing.

Today, I would like to share some ideas on how to quickly audit all fields of the return value of the interface, hoping to help you~

In fact, there are two common solutions to the above problems:

  • Customize and develop verification rule library according to business verification requirements
  • Leverage existing third-party libraries

Today, let's talk about how to solve it with the help of the existing third-party library: quickly verify all the fields returned by the API interface. Since most of today's interfaces are based on Restful API, in the subsequent introduction, we assume that the format of interface response body takes JSON as an example.

To meet the above implementation requirements, there are many third-party library schemes, such as deepdiff, difflib, JSON diff and json_tools, etc. these three libraries have their own focus. This article focuses on how to use the deepdiff library to solve the problem of quickly verifying the return fields of the interface.

1, Meet me, DeepDiff introduction

Deepdiff module is often used to check whether two objects are consistent and find out the differences. Three classes are provided, deepdiff, DeepSearch and DeepHash. The official website address is: https://deepdiff.readthedocs.io/en/latest/ , the latest version is V5 five

Main components:

  • DeepDiff: compare two objects. The objects can be iteratable objects such as fields and strings. For the deep differences of objects, recursively find all changes.

  • DeepSearch: searches for other objects in objects

  • DeepHash: perform hash processing according to the content of the object

The original intention of DeepDiff is to find out the differences between different data. We can compare JSON, XML text classes and pictures. After using it, we can directly use it as the assertion of the test, which also provides a new verification idea from another perspective.

2, DeepDiff use

After reading the above introduction, I believe you are still confused and don't know how to start. Next, let's further experience the functions and functions of Deepdiff through several cases.

Before use, install:

pip install deepdiff

2.1 case 1: comparing two JSON
Compare JSON differences with Deepdiff:

import pytest
import requests
import pprint
from deepdiff import DeepDiff

class TestDemo(object):

    def test_case_01(self):
        a = {"Object": {
            "code": "0",
            "message": "success"
        },
            "code": "0",
            "message": "success"
        }

        b = {"Object": {
            "code": "0",
            "message": "failure"
        },
            "message": "success",
            "timestamp": "1614301293"
        }

        pprint.pprint(DeepDiff(a, b))

The purpose of the above case is to compare the difference between a and b. the output of result difference is:

.{'dictionary_item_added': [root['timestamp']],
 'dictionary_item_removed': [root['code']],
 'values_changed': {"root['Object']['message']": {'new_value': 'failure',
                                                  'old_value': 'success'}}}

In the above output results, all differences are actually obtained according to the returned json. It mainly compares the value between objects, changes between types before and after, and deletion or addition. key outputs the results.

It mainly includes the following four situations:

  • 1,type_changes: key of type change
  • 2,values_changed: the key whose value has changed
  • 3,dictionary_item_added: Dictionary key added
  • 4,dictionary_item_removed: the field key is deleted

2.2 case 2: compare interface response

With the foundation of case 1, further, we change the locally defined variable value to call the interface (which is more in line with the actual interface test), initiate the request, obtain the response, and assert it in combination with Deepdiff.

Core idea: first define the expected response structure (meaning that you have to know what the expected result is in advance), and then automatically compare the two through Deepdiff according to the actual returned structure.

import pytest
import requests
import pprint
from deepdiff import DeepDiff


class TestDemo(object):

    def setup_class(self):
        self.response = requests.get('http://www.httpbin.org/json').json()

    def test_case_02(self):
        expected_reps = {'slideshow': {'author': 'Yours Truly', 'date': 'date of publication',
                                       'slides': [{'title': 'Wake up to WonderWidgets!', 'type': 'all'}, {
                                           'items': ['Why <em>WonderWidgets</em> are great',
                                                     'Who <em>buys</em> WonderWidgets'], 'title': 'Overview',
                                           'type': 'all'}], 'title': 'Sample Slide Show'}}
        pprint.pprint(DeepDiff(expected_reps, self.response))

Since the actual returned structure is exactly the same as the expected structure data to be verified, the output result of the above code is: {}, that is, there is no difference between the two. (it also means that the actual and expected results are consistent)

On this basis, if we put the above expected_reps expects the author in the structure body to be changed from Yours Truly to Yours, and then execute it again, and the output result is:

{'values_changed': {"root['slideshow']['author']": {'new_value': 'Yours Truly',
                                                    'old_value': 'Yours'}}}

From the above output results, we can obviously get three messages:

The value in the structure returned by the interface has changed. Through values_changed is marked
Specify which field value has changed, such as root ['slideshow'] ['author'].
Change the specific content. For example, the actual return value is Yours Truly, while the expected value is Yours.
After reading this, I believe you have some feelings about the use of Deepdiff in interface testing. But then you will definitely ask questions. The values returned by some interfaces are not fixed, such as verification. For example, for a timestamp field, the value of the returned field is different every time the interface is called. For this kind of field, we only know the data rules, but the value of the data itself cannot be determined at the beginning. How can we use it in combination with Deepdiff? Don't worry, look down again.

2.3 case 3: regular search matching

To solve the above problems, you can use the regular search matching function in Deep Search. If your interface returns a deeply nested structure object, and then you want to check whether the specified element (key and value) exists, Deep Search will be a good choice.

Before use, you need to import from deep diff import grep. The example source code is as follows:

def test_case_03(self):
    datas = {"mikezhou": age":18, "city": "china", "info": {"author": {"tag": "mikezhou"}}}
    reuslt = datas | grep("mike*",use_regexp=True)
    print(reuslt)

For example, if you want to check whether there is a field or value starting with mike in the returned structure, and if the specified element exists, return its path; If it does not exist, an empty dictionary is returned. The above output results are as follows:

.{'matched_paths': ["root['mikezhou']"], 'matched_values': ["root['info']['author']['tag']"]}

Although the above example is simple, if you are smart enough, you should be able to Get the core idea from it: for some dynamic unpredictable values, you can match and verify with the help of regular expressions. The specific verification depends on how your regular expressions are described.

3, Last tip: DeepDiff blacklist

When making interface test assertions, sometimes the object order is different, but the actual situation is that the two values are still the same, or when checking the full field, you want to skip some special field verification (like the blacklist, specify the fields that do not need verification). In order to solve this kind of problem, Deepdiff also provides trusted parameters, You only need to add when comparing:

ignore order(Ignore sorting)
ignore string case(ignore case)
exclude_paths You can exclude parameters from the blacklist. The prototype is as follows:
result = DeepDiff(result, expected, view='tree',ignore_order=True,ignore_string_case=True)

Example:

def test_case_05(self):
        expected_reps = {"datas": {
            "code": "200",
            "message": "success"
        },
            "code": "201",
            "message": "success"
        }

        actual_reps = {"datas": {
            "code": "201",
            "message": "failure"
        },
            "message": "Success",
            "timestamp": "1614301293"
        }

        pprint.pprint(DeepDiff(expected_reps, actual_reps, ignore_order=True,ignore_string_case=True,exclude_paths={"root['timestamp']"}))
The above example code ignores the collation and case problems, and specifies exclusion timestamp Field verification. The specific output results are as follows:

{'dictionary_item_removed': [root['code']],
 'values_changed': {"root['datas']['code']": {'new_value': '201',
                                              'old_value': '200'},
                    "root['datas']['message']": {'new_value': 'failure',
                                                 'old_value': 'success'},
                    "root['message']": {'new_value': 'Success',
                                        'old_value': 'success'}}}

4, Summary

Through the above case introduction, I believe you have a basic understanding of the use of DeepDiff. In the interface automation test, the advantages of using DeepDiff are as follows:

During interface testing, you can directly use the expected structure (or interface contract) to automatically compare with the actual returned structure (fields and values) to determine whether it is the same, and you can write a lot less code.
The same is true when comparing database data. After using SQL to find out the results, it can be directly turned into JSON and compared with the expected JSON.
This article aims to help you provide some solutions to the full field verification of interface test from another perspective, more about the use skills of Deepdiff and the full field solutions with better solutions (there are many more). You are welcome to actively explore.

Finally: [tutorials that may help you]


These materials should be the most comprehensive and complete war preparation warehouse for friends doing [software testing]. This warehouse has also accompanied me through the most difficult journey. I hope it can also help you! Everything should be done as soon as possible, especially in the technology industry. We must improve our technical skills.

Pay attention to my WeChat official account: [programmer two black] free access.

My learning and communication group: 642830685. There are technical cows in the group to communicate and share~

If my blog is helpful to you and you like my blog content, please click "like", "comment" and "collect" for three times!

Recommended reading

High paid programmers can't escape the 35 year old level... How can we save ourselves when our ability is divorced from our age

After graduating from college, I began to sell... Unwilling to be content with the current situation, the self-help way of changing to professional testing

From selling the crown to unemployment, I finally chose software testing. Looking back, I'm very lucky!

Keywords: software testing Testing API testing

Added by runnee on Sat, 29 Jan 2022 14:24:28 +0200