review

Remember last time, we made a simple page that supports HTTP requests, but we didn’t actually use it in the use case.

Use case design

I have a big shortcoming. I do what I think, usually design a simple version in advance and then polish it later. In fact, this is too unfriendly for a mature system. So let’s cut to the chase.

About the case

Thought about many times, now in the company to make the test platform of a characteristic, be don’t need to write code can complete interface test cases to write, but because of the not much to everyone’s growth has increased, so this time I intend to do it, if you are willing to write code, you can import the code or online writing code, if you don’t want to see the code, You can also use the codeless mode, and you have to convert at any time.

Life cycle of use cases

By design, use cases are executed as links, and a use case has many temporary variables through which we can resolve data dependencies and complete the testing of the entire process. Due to the limited drawing ability of the author, the above picture is not included. A use case has several parts:

  • Pre-setup operation

  • Case execution

  • After the tearDown operation

Each operation has many steps, and the data generated by each step will be stored throughout the life cycle of the main use case to achieve the effect of data interoperability.

The steps can be HTTP requests, redis operations, SQL statements, Python code snippet, and so on. Each step can have a return value that resolves the data dependency problem.

For example,

If we needed to get the user’s balance, our use case would be written like this:

  1. First design a login test case:

Use case name: User login

Prerequisites: None

Use case execution: Send HTTP request to obtain token

Postcondition: None

Assertion statements: verify HTTP status codes, etc

  1. Write a test case (master case) to get a user’s balance:

Use case name: Get user balance prerequisites:

  • Step1: User login

    The returned value is step1, and the token data in the login interface is obtained through step1

Use case execution: Replace ${step1. Token} in body with a real token and send an HTTP request.

Postcondition: None

Assertion statement: Validates the code and MSG and the information in the data field

It doesn’t matter if you don’t understand it at the beginning, it’s going to look like this. There is no picture mainly. This is a process.

Common component package Pity_Basic

The main contents are:

  • Stores the variables generated by the use case lifecycle

  • Look for variables in the request field and replace them with real data

  • Operations related to redis

  • SQL Related Operations

  • Operations related to HTTP

  • Operations related to Python code blocks

    All of the above code related operations are designed to convert data and code to each other, and the specific ideas are not fully worked out yet. I like to write while thinking, otherwise I think certainly not complete, only when writing encountered a problem to think about how to do the next step.

    Give me limited time to think, I can only go step by step!

    In fact, I also feel that I said here in the fog, or wait for the follow-up finished product out, look back or modify this article!

Write variables to find related methods

Here we have our own set of rules. All data such as ${variable} are variables that need to be replaced, which may be generated by other prefixes or constants, and need to be replaced at any time. This rule requires that variables be as simple as possible, with no special symbols.

import re

el_exp = r"\$\{(.+)\}"
pattern = re.compile(el_exp)


def get_el_expression(string: str) :
    Param string: :return: ""
    return re.findall(pattern, string)


if __name__ == "__main__":
    s = "select * from xxx where name = '${mygod}'"
    print(get_el_expression(s))
Copy the code

We use re to extract variables, so that if we have variables in the SQL statement, we can do dynamic SQL statements, as shown in the figure above. However, based on this, we also need to provide a variable pool to hold all the temporary variables for the use case.

Write variable pool related methods

""" "Pity variable pool The lifetime of the variable pool is consistent with the use case. """
__author__ = "xiaoke"


class VarPool(object) :

    def __init__(self, case_id) :
        """ :param case_id: used to identify the primary lifecycle of the variable
        self.cache = dict()
        self.case_id = case_id

    def set(self, key, value) :
        self.cache[key] = value

    def get(self, key) :
        return self.cache.get(key)

    def get_default(self, key, default_value) :
        return self.cache.get(key, default_value)


Copy the code

Here we create a variable pool class, which actually maintains a map. Of course, since there may be variable conflicts in complex scenarios, we will control this at the Web page level to ensure that users do not use duplicate variables.


That’s all for today’s content, mainly a problem of conception. Then slowly fill in the concepts, make it more and more clear. Because I’m confused right now, and if I’m confused, I can review the whole use case process again.

Pity_basic will be available as a tar package from pypi, but the main reason for pulling it out is to support switching between code and codeless modes.

Pity_basic code address