Improve the efficiency of interface automation testing: use JMESPath to implement assertions and data extraction!

Preface

When automating interfaces, assertions are indispensable. How to quickly and skillfully extract assertion data becomes the key, and of course it can also improve the efficiency of writing use cases. The author came into contact with it at work JMESPath, so how to use it? Look down with doubts.

JMESPathWhat is it?

JMESPath is a concise and powerful query language for querying and transforming JSON data. It provides a flexible way to extract the required data from complex JSON structures and supports various operations and functions to meet different query needs.

JMESPathhow to use?

Before using JMESPath to query JSON data, we need to install  jmespath the library. The installation command is as follows:

pip install jmespath

simple path expression

Suppose we have the following JSON data:

data = {
    "name": "Alice",
    "age": 25,
    "email": "[email protected]"
}

We want to extract "name"the value of the attribute from it. Using JMESPath we can write the following code:

import jmespath
​
expression = "name"
result = jmespath.search(expression, data)
​
print(result)  # 输出:Alice

Here, we define a path expression "name"and then use jmespath.search()a function to apply the expression datato the data. The result will be stored in resultthe variable and output as "Alice".

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

Nested property access

When JSON data has a nested structure, you can use dots  . to connect multiple attribute names to indicate deep attribute access. Consider the following JSON data:

data = {
    "person": {
        "name": "Alice",
        "age": 25,
        "email": "[email protected]"
    }
}

To extract "name"attributes, we can use the following path expression:

expression = "person.name"
result = jmespath.search(expression, data)
​
print(result)  # 输出:Alice

Here, we concatenate the property name  "person" with  "name" a dot  . to represent deep property access.

Complex nested queries

Let's say we have a more complex JSON data containing student information and their course grades, like this:

data = {
    "students": [
        {
            "name": "Alice",
            "courses": [
                {"name": "Math", "score": 95},
                {"name": "English", "score": 88}
            ]
        },
        {
            "name": "Bob",
            "courses": [
                {"name": "Math", "score": 75},
                {"name": "English", "score": 92}
            ]
        }
    ]
}

Now, let's say we want to get each student's math score. This can be achieved with the following expression:

expression = "students[].courses[?name == 'Math'].score"

Execute the query again and print the results:

result = jmespath.search(expression, data)
print(result)

The output will be a list containing each student's math score:

[[95], [75]]

list index

For list properties in JSON, you can use square brackets  [index] to specify the index position to retrieve the data. Suppose we have the following JSON data:

data = {
    "fruits": ["apple", "banana", "cherry"]
}

We want to extract the second element, ie "banana". The following path expressions can be used:

expression = "fruits[1]"
result = jmespath.search(expression, data)
​
print(result)  # 输出:banana

Here, we use square brackets  [1] to specify the index position, which means extracting the second element.

filter

JMESPath provides a filter function that allows us to filter out data that meets the requirements based on specific conditions. Filters use square brackets  [?]followed by the filter criteria. Consider the following JSON data:

data = {
    "users": [
        {"name": "Alice", "age": 25},
        {"name": "Bob", "age": 30},
        {"name": "Charlie", "age": 28}
    ]
}

We want to extract user objects who are older than 25 years old. You can filter using the following path expressions:

expression = "users[?age > `25`]"
result = jmespath.search(expression, data)
​
print(result)

The output is:

[    {"name": "Bob", "age": 30},    {"name": "Charlie", "age": 28}]

Here, we use a filter  [?age > 25]to select only user objects that meet the conditions.

merge operation

JMESPath also supports merge operators  []for merging multiple query results into a single list. Suppose we want to get all course names for all students. [] This can be achieved using the merge operator  :

data = {
    "students": [
        {
            "name": "Alice",
            "courses": [
                {"name": "Math", "score": 95},
                {"name": "English", "score": 88}
            ]
        },
        {
            "name": "Bob",
            "courses": [
                {"name": "Math", "score": 75},
                {"name": "English", "score": 92}
            ]
        }
    ]
}

Get all course names for all students:

expression = "students[].courses[].name"
result = jmespath.search(expression, data)
print(result)

The output is:

['Math', 'English', 'Math', 'English']

Sort and slice

JMESPath also supports sorting and slicing of query results. Suppose we want to sort students by age in descending order.  This can be achieved using the sorting function  sort() and the reverse ordering function  :reverse()

data = {
    "students": [
        {"name": "Alice", "age": 20},
        {"name": "Bob", "age": 22},
        {"name": "Charlie", "age": 21}
    ]
}

Get a list of students sorted by age in descending order:

expression = "students | sort_by(@, &age) | reverse(@)"
​
result = jmespath.search(expression, data)
print(result) # [{'name': 'Bob', 'age': 22}, {'name': 'Charlie', 'age': 21}, {'name': 'Alice', 'age': 20}]

slice

data = {
    "fruits": ["apple", "banana", "cherry"]
}

Get the first element using slicing

import jmespath
​
data = {
    "fruits": ["apple", "banana", "cherry"]
}
expression = "fruits[0:1]"
result = jmespath.search(expression, data)
​
print(result) # ['apple']

pipeline

Use the pipe symbol (|) to pass the result of the current node to the right side of the pipe symbol to continue projection.

data = {
    "students": [
        {"name": "Alice", "age": 20},
        {"name": "Bob", "age": 22},
        {"name": "Charlie", "age": 21}
    ]
}

Get all names:

expression = "students[*].name"
result = jmespath.search(expression, data)
print(result) # ['Alice', 'Bob', 'Charlie']

BobIf you want to get this value based on this . Let's try using an index:

expression = "students[*].name[1]"
result = jmespath.search(expression, data)
print(result) # []

It is found that the execution result is an empty list, what should I do at this time? Use pipe expressions, <expression> | <expression>

expression = "students[*].name | [1]"

built-in functions

Calculate list length

data = {
    "students": [
        {"name": "Alice", "age": 20},
        {"name": "Bob", "age": 22},
        {"name": "Charlie", "age": 21}
    ]
}
​
expression = "length(students)"  # 也可以这样写expression = "students | length(@)"
result = jmespath.search(expression, data)
print(result) # 3

lengthIt's jmespatha built-in function.
Of course, there are some other commonly used built-in functions, such as:

  • starts_with(str, prefix): Checks whether the string starts with the specified prefix.
  • ends_with(str, suffix): Checks whether the string ends with the specified suffix.
  • contains(str, substring): Check if a string contains a substring.
  • length(arr): Returns the length of the array.

at last

jmespathIt is indeed very powerful. Through step-by-step learning and practice, you can better master the functions and flexibility of JMESPath.

Finally, I would like to thank everyone who read my article carefully. Looking at the increase in fans and attention, there is always some courtesy. Although it is not a very valuable thing, if you can use it, you can take it directly!

Software Testing Interview Document

We must study to find a high-paying job. The following interview questions are the latest interview materials from first-tier Internet companies such as Alibaba, Tencent, Byte, etc., and some Byte bosses have given authoritative answers. After finishing this set I believe everyone can find a satisfactory job based on the interview information.
 

Insert image description here

 

Guess you like

Origin blog.csdn.net/myh919/article/details/133183668