“This is the 28th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

First, pre-work

1. Gold process

Before making a performance script to understand that the performance of actual combat operations, briefly explain the use of an electrical system order process to do this in the performance of the business scenario, the process is also called call gold process, the user from the browsing homepage to choose goods, add to cart, and pay a series of steps into the process, below is the business flow chart of the performance of actual combat.

2. Jmeter installation

Jmeter must be installed before script development. If not, please download Jmeter from the official website. Jmete R is a pure Java development, so you need to install JDK environment, please download JDK1.8 or above and install, here will not demonstrate the installation steps, in order to facilitate you to configure JDK and Jmeter environment variables, JDK and Jmeter environment variables in the MAC environment are provided as follows:

Jdk environment variables are referenced as follows:

$ vim .bash_profileExport JAVA_HOME=/usr/local/ Java /jdk1.8.0_181 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH#Press ESC and enter the following command
$ :wq!
#The terminal enters the command to take effect
$ source ~.bash_profile
Copy the code

Jmeter environment variables are referenced as follows:

$ cd ~
$ vi ~.bash_profile
#Jmeter: pathJmeter_HOME = / Users/tools/apache - Jmeter - 5.3 PATH = $PATH: $HOME/bin: $Jmeter_HOME/bin:$ export PATHEffective execution:$ source ~.bash_profile
Copy the code

To verify whether the Jmeter environment is configured successfully, enter the [Jmeter -v] command. If the following information is displayed, the configuration is successful. The advantage of configuring environment variables is that Jmeter can be opened in any file directory on the terminal. {Jmeter_path} /bin/jmeter: {Jmeter_path} /bin/jmeter

To start, enter the Jmeter command:

liwen ~ % Jmeter ================================================================================ Don't use GUI mode for  load testing ! , only for Test creation and Test debugging. For load testing, use CLI Mode (was NON GUI): Jmeter -n -t [jmx file] -l [results file] -e -o [Path to web report folder] & increase Java Heap to meet your test requirements: Modify current env variable HEAP="-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m" in the Jmeter batch file Check : https://Jmeter.apache.org/usermanual/best-practices.html = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =Copy the code

Here is what Jmeter looks like after startup:

Second, script actual combat development

Before developing the script, split the script development into two parts, one part is the development of registration process script, and the other part is the development of order process script, as shown below:

1. Users register links

Why start from the registration script because the order process requires the user login state can order, so the registration script in the registration process from the beginning of development;

It can be observed from the registration interface document that the system registration needs to obtain the verification code of the mobile phone before calling the registration interface to register in the system.

1.1. Interface description

Registered user interface diagram:

To quickly develop the registration script, manually enter a mobile phone number and click to obtain the verification code. The interface to obtain the verification code is as follows:

Click the interface to register users, enter the verification code, password, mobile phone number and user name, and click “Send” to register successfully. The interface document is displayed as follows:

Through the above registration user, open the landing interface document, enter the user name and secret to log in, below is the user login interface after landing response information graph, containing the user’s token, the response status code and other information, other interfaces need to be in state can be obtained by adding token header information can the interface response information, However, the registered users need to add the user address to complete the ordering process. If there is no user address, the ordering will not be successful, because the ordering does not know where the goods are sent.

The following figure shows the interface for adding user address information. The interface input parameters are as follows:

Click the debug button and the interface request template information is displayed below. You can refer to the interface documentation to make a script and develop the script quickly.

It is not convenient to register users in batches in the future through manual interface documents, so they need to be associated with each other. Only in this way can users be registered in batches. However, if we need a large number of users in pressure test, we can generate a batch of users through Java, Python, EXCL and other tools and save them in files. Then, the CSV Data Set Config component in Jmeter can be used to read files to obtain user parameters, so that users can be registered in batches. How to make mobile phone numbers in batches? Two codes are provided here to help users quickly generate mobile phone numbers.

The generation of mobile phone numbers must meet the rules of mobile phone numbers, and the following conditions must be met through research:

  • China Telecom: 133, 149, 153, 173, 177, 180, 181, 189, 191, 199
  • China Unicom: 130, 131, 132, 145, 155, 156, 166, 171, 175, 176, 185, 186
  • China Mobile: 134 (0-8), 135, 136, 137, 138, 139, 147, 150, 151, 152, 157, 158, 159, 172, 178, 182, 183, 184, 187, 188, 198

The phone number code generated by Python is as follows:

import  random
# All headers are added
phon = [133.149.153.173.177.180.181.189.191.199.130.131.132.145.155.156.166.171.175.176.185.186.135.136.137.138.139.147.150.151.152.157.158.159.172.178.182.183.184.187.188.198]
Open the file and store it in a memory location
f = open("phone.txt"."w")
# Loop 1 million times
for i in range(1.1000000) :# Splice the phone number
    phone = str(random.choice(phon)) + "".join(random.choice("0123456789") for i in range(8))
    # Save your phone number
    f.write(phone)
    f.write("\n")
# close file
f.close()
Copy the code

Java generate mobile phone number code reference:

public static void main(String[] args) throws IOException {
// Save to a file
FileWriter fileWriter = new FileWriter("./7d/phone.txt");
// Save 1000 mobile phone numbers
for (int j = 0; j < 100000; j++) {
    // Save the phone number data
    String[] phone = {"133"."149"."153"."173"."177"."180"."181"."189"."191"."199"."130"."131"."132"."145"."155"."156"."166"."171"."175"."176"."185"."186"."135"."136"."137"."138"."139"."147"."150"."151"."152"."157"."158"."159"."172"."178"."182"."183"."184"."187"."188"."198"};
    Random random = new Random();
    int first = random.nextInt(phone.length);
    StringBuilder stringBuilder = new StringBuilder(phone[first]);
    for (int i = 0; i < 8; i++) {
        stringBuilder.append(random.nextInt(10));
    }
    fileWriter.write(stringBuilder.toString());
    fileWriter.write("\n");
}
// Close the file stream
fileWriter.close();
}
Copy the code

Note:

Why is it necessary to use random numbers to make user phone numbers instead of generating phone numbers sequentially? It is because the data generated sequentially and stored in the database in the registration system is not real. The parameterized data of pressure measurement should conform to the real user data.

1.2. Script development

Open Jmeter and create a new thread group, as shown below:

To obtain a verification code using a mobile phone number, perform the following steps:

1, create HTTP Reques and enter the following parameters to develop the script;

${telephone} ${telephone} ${telephone}

Since user registration requires mobile verification code, parameters need to be obtained through association and used by the registration interface. If you do not know what association is, please refer to thePerformance test actual combat 30 talk””Correlation and assertion: Every move, every quiet moment, the core is fetching data] Here will not be detailed, to obtain the verification code writing method as shown in the figure:

Step 1 Create an HTTP Request. Enter the registration address and related information as follows:

Url:

http://cloud-gateway.mall.demo.7d.com/mall-portal/sso/register
Copy the code

The specific writing is as follows:

Description:

${username} is a global variable in Jmeter. ${username} is a global variable in Jmeter.

Here is the global parameter file:

The user can be registered through the above operations, but the order process still cannot be successfully placed after registration, because of the lack of user address, the user address is added to the user, the interface to add user address implementation reference is as follows:

The Jmeter script for the entire registration process is shown below:

The above scripts are registered users to login to increase user address information is realized in Jmeter, did not add assertions because these scripts in the script above is mainly done user registration, user registration information is data preparation for order process do so didn’t add assertions, but everyone can add assertions component, whether the request is correct.

Note:

If you only test the ordering process and do not want to use the login interface, you only need to save the user information and token information to the local, and then read the token and user information to the interface that requires the login mode through the parameterization technology, so as to normal pressure test business scenarios. The following describes how to save the data to the local through Jmeter.

The first step is to add the thread group, add the HTTP Request, and enter the login interface address and user parameters as follows:

Add output to the global parameter file and save the file information path, as shown in the figure below:

Add the JSR233 Sampler component to Jmeter as shown below:

Reference code:

FileOutputStream fps=new FileOutputStream("${outfile_online}".true);
OutputStreamWriter osw=new OutputStreamWriter(fps);
BufferedWriter bw=new BufferedWriter(osw);
bw.append("${Bearer}\t${token}\n");
if(bw! =null){bw.close(); }if(osw! =null){osw.close(); }if(fps! =null){fps.close(); }Copy the code

Through code writing, and then click run verification output results are as follows:

Succeeded in writing the parameter file. Procedure

2. Users place links

Before developing an order script, review the steps required in the order process so that the script can be developed in preparation for benchmarking and capacity testing.

New global variable, the purpose of global variable is to better switch pressure measurement environment and variable value, and better preparation for parameterization, so global definition variable is adopted, the operation steps are as follows:

1. Start Jmeter and right-click User Defined Variables to see the corresponding values. It is recommended to write annotations after each Defined variable so that you can easily remember the value of the variable.

The name module is the name of the variable to be parameterized. Enter the Value of the variable in the Value module, which is also a common key-value input pattern.

When you write an interface, you need to know the type of interface request so that you can easily use the type of interface script. Generally, the request is divided into common requests such as GET, POST, DELETE, and PUT. A GET request is a resource request, a POST request is a submission request, a DELETE request is a deletion request, and a PUT request is a modification request. However, these are not the only ones defined in this way.

@GetMapping("/7d/test/{info}")
public MsgResponse getRequest(@PathVariable Integer info) {
    if (info == 1) {
        // Update the data status
        return MsgResponse.success().add("data"."Update status succeeded");
    } else {
        // Query data
        HashMap<String, String> map = new HashMap<>();
        map.put("7d"."Performance Combat 1");
        map.put("7dTest"."Performance 2");
        return MsgResponse.success().add("data", map); }}Copy the code

As can be seen from the simple demo code above, although it is a GET request, the back-end code will do the corresponding action according to the value passed. If you want to know what the specific definition of these requests is, you can refer to other materials to learn, and there is no further explanation here.

2.1. Obtain the home page interface

The interface document of the home page is as follows. Through the interface document, we obtain the following information:

1. This interface is a GET request. We know that generally GET requests are to obtain resource data.

2. It can be seen from the response data structure that it is a JSON data structure and nested with several layers of list data structure;

3, in order to further understand why it is such a data structure that can look at it and back-end code link figure will understand why this is such a data structure, below is to obtain the back-end home page even road map and the department code, someone asked why need to see the link with the code, this is in order to analyze problems do knowledge accumulation, and if the code is the performance bottleneck, If you don’t know how the code calls the relationship, then you won’t know how to locate the code problems and give reasonable tuning suggestions:

(UML class diagram and code diagram)

Before looking at the above code call relationship, let’s first understand the general development pattern of Java EE projects

Description:

  • The Controller is the Web layer that receives and returns data to the user;
  • A service is a business logic layer that processes and validates data
  • Dao full name (Data Access Object) is the persistence layer, which focuses on the operation of the database.
  • DB is the database;

With the above knowledge foamy, the analysis of the home page interface request will be clear, with the home page to understand how to call the back-end code how to achieve;

1. The Web layer can see the requested resource path, as shown in the figure:

2, business implementation layer, as shown in figure can see, the interface through the request for home page ads, recommend brands, seconds kill information, new product recommendation, sentiment is recommended, project data, there are six data structure through code will understand the front after the request, the front-end display interface response why there are several layers of data structure;

3. Check the Dao layer data below and select “Obtaining recommended brand” as an example. Notice that the method name getRecommendBrandList needs to be one-to-one with the ID name in XML otherwise the statements in XML won’t find the DAO layer method and you won’t be able to look for data.

The specific DAO layer structure is as follows:

/** * get recommended brand */
List<PmsBrand> getRecommendBrandList(@Param("offset") Integer offset,@Param("limit") Integer limit);
Copy the code

4. The ID keyword in the SQL statement in the XML file that corresponds to the name of the getRecommendBrandList method above, it’s easy to see that this XML file is just a few SQL statements. Note that @param (“offset”) in the Dao layer needs to correspond to @param (“offset”) in the XML to pass the correct value.

<select id="getRecommendBrandList" resultMap="com.dunshan.mall.mapper.PmsBrandMapper.BaseResultMap">
    SELECT b.*
    FROM
        sms_home_brand hb
        LEFT JOIN pms_brand b ON hb.brand_id = b.id
    WHERE
        hb.recommend_status = 1
        AND b.show_status = 1
    ORDER BY
        hb.sort DESC
    LIMIT #{offset}, #{limit}
</select>
Copy the code

Through the above back-end code analysis, we can understand the back-end call relationship, and know how to analyze code problems in the future when encountering code performance problems.

By analyzing the code step by step, you can now understand the above code and UML class diagram.

Next, I started to write the interface to get home page information in Jmeter, create a thread group, create an HTTP Request, input variables, and add assertions according to the response results, as shown in the following figure.

Add login header information, because adding goods to shopping requires login before adding goods to shopping cart, so all scripts need to add header file information, the script will not be explained in the future, the script implementation is as follows:

Verify that the interface succeeds. The result is as follows:

Before the user login interface and use the information query interface in the registration process has been explained, this is no longer in the Jmeter described here, why it is important to note in the order process requires the user to log in with the user information, this is because behind the interface state requires the user to login token address with the user id information, so you need to use the interface information, If you need to benchmark scenarios in the future, you can save this information and parameterize it the next time the interface needs it.

2.2 Add commodity interface to shopping cart

See the interface document first, then analyze what parameters are needed, and then decide how to write the corresponding Jmeter script. The following figure shows the interface for adding goods to shopping cart, which requires one skuCode code and one quantity code. The system automatically adds the item skuCode code to the shopping cart, and automatically adds a record to the database or cache. Why do you need to add it to the database or cache? It is convenient for users to enter the shopping cart next time. The commodity data is still there. If you do not add the database or cache, close the browser or mobile phone browser and other information, the commodity data will naturally be lost.

If commodity information is added to cookie, it should be known that cookie data is stored in the browser or other caches, and the data depends on the cache. If the cache disappears, the data will disappear naturally, so the data needs to be stored in the server, but the server depends on the user’s login state. If there is login state information, the system will automatically retain the data. The next time the user logs in, they will see the product information. If there is no login state, the data will not exist the next time they open the browser.

The data stored in cookies is only temporary storage. When the user leaves, the commodity information will be lost. Therefore, when the user leaves, it will prompt whether the commodity information needs to be retained.

Note that the user must log in to retain the product information in order to see it next time.

It is necessary to analyze the skuCode and quantity of goods to be added to the shopping cart, and the goods can be added successfully only if there is inventory. If the goods exist, it will not work if there is no inventory. Generally, these data are provided by the business or they are familiar with the business.

Through table structure analysis, inventory table is [PMS_SKu_stock] through SQL statements can be found out the need to parameterize commodity skuCode code; After obtaining the data you want, you just need to save the data as text or CSV, and add the parameters in the script next time. For parameterization, please refer to Jmeter in Performance Test Practice 30. I won’t specify how to parameterize it here.

Below is a table of commodity inventory information:

2.3 Add product interface to shopping cart finally

The parameter file is as follows. For how to use the CSV Data Set Config component, please refer to how to parameterize in The performance Test Practice 30 lecture. I will not explain how to use it too much here.

The final script is as follows:

2.4 Interface for querying shopping cart information

By observing the query shopping cart interface is a get request, is the same with before, no longer more introduction, but watch the next step is to confirm the shopping cart of goods of our order process interfaces need to pass an array parameter, the array parameters is the result of this query out shopping cart ID value of the information, the current query shopping cart interface is a json array, JSON Extractor in Jmeter can obtain the ID number of all shopping cart information, and then through the [BeanShell PostProcessor] after processing the results can be passed to the next step to do parameters.

The interface documentation is as follows:

The corresponding results are as follows:

{
 "code": 200."message": "Operation successful"."data": [{"id": 63280."productId": 27."productSkuId": 98."memberId": 90."quantity": 1."price": 249."productPic": "https://perfo7d.oss-cn-beijing.aliyuncs.com/mall/images/20200923/web.png"."productName": ""."productSubTitle": ""."productSkuCode": "201808270027001"."memberNickname": "xingneng_test"."createDate": "The 2020-11-02 T15:28:56. 000 + 00:00"."modifyDate": "The 2020-11-02 T15:28:56. 000 + 00:00"."deleteStatus": 0."productCategoryId": 7."productBrand": ""."productSn": "No86577"."productAttr": "[{\" key \ ": \ \" color ", \ "value \" : \ \ "black"}, {\ "key \" : \ \ "capacity", \ "value \" : \ "32 gb \}"]"}}]Copy the code

The Jmeter script for querying the shopping interface is as follows:

Verification results:

* is a regular expression, -1 means to obtain all the data.

The BeanShell PreProcessor is shown below:

// log.info(" debug whether to get length ID :"+vars.get("cartId_matchNr"));
int num=Integer.valueOf("${cartId_matchNr}");
 //log.info(" data :"+num);
StringBuilder stringBuilder = new StringBuilder();
for(i = 1; i<=num; i++){ stringBuilder.append(vars.get("cartId_"+i)+",");
}
String ids =  stringBuilder.substring(0, stringBuilder.length() - 1);
 //log.info(" result: "+ids);
vars.put("ides",ids);
Copy the code

Explanation: ${cartIds_matchNr} in this code is available by adding the Debug Sampler component to the View Results Tree and clicking the Debug Sampler request. The shopping cart confirmation order interface can be parameterized with this value.

BeanShell processing verification results are as follows:

2.5. Shopping cart order confirmation interface

Flow chart:

Interface documentation:

According to the shopping cart information to generate confirmation sheet information interface script reference is as follows:

Note: the ${ides} parameter is the id obtained by the shopping cart query and processed by the BeanShell script. If you do not clear the parameter, please check the above script to see how to write the parameter.

[${ides}]
Copy the code

Verification results:

2.6. Generate order interface

Interface according to the above documents can be observed at the interface to the shopping cart id number on the current step is implemented, the user receiving address this value at the time of registration has been added, and can also be through a user interface to query the value of information, the rest is coupons, integrating the two values, now this isn’t related with these two values can not preach or what value is, Observe the processing according to the following code, can be null;

In this script, useIntegration and couponId are directly removed, and the Jmeter script is as follows:

The script code is as follows:

{
  "cartIds": [${ides}],
  "memberReceiveAddressId": ${userId},
  "payType": 0
}
Copy the code

The response results are as follows:

2.7 interface for paging query of order information

Why do we use paging order query interface as the pressure test interface, this is because after the actual purchase of goods, sometimes you will directly query your previous order information or all the order information under the browser, at this time you will call paging order information interface, which is in line with the real scenario.

Interface documentation:

Note: Status according to the interface document prompt can only enter [order status: -1-> all; 0-> to be paid; 1-> to be shipped; 2-> Shipped; 3-> completed; 4-> Closed] these several status values, after pageSize and pageNum is very good to understand what value; We can also see what values need to be passed in code like this:

It can be implemented in Jmeter according to the interface information. The script is as follows.

Verification results:

2.8. Payment order interface

The interface documentation is as follows:

Description:

The order number is generated according to the response result of the interface generating order information. If the order number needs to be used, the order number needs to be extracted through association and passed to the interface for use. If it is a benchmark scenario test, it is necessary to create a batch of order numbers as parameters before running the order interface.

The specific interface implementation reference is as follows:

The writing method for obtaining the order number in the interface for generating order information is as follows. It should be noted that the value of this component should be placed under “Generating Order Information”, so that the payment interface can obtain the order number as a parameter.

The payment order interface development reference is as follows:

Script verification results:

2.9 interface for obtaining order details by ID

See the order details through the interface document as long as the order number can be found out the details of the order;

Jmeter implements the following:

The query results are as follows:

Third, summary

1, through the registration process and order process script development, I believe you can master Jmeter script development in Jmeter to achieve get and POST requests, parameterization, correlation, and also through the [JSR223 Sampler] component to save the response results to the local. It can also process response parameters through BeanShell PostProcessor, processing the desired result of the parameters, and finally passing the parameters to the next interface for use.

2. By adding the Debug Sampler component, you can learn how to Debug interface requests and observe parameterized value changes.

3, through the use of home interface as an example, step by step with you to see how the back-end code is called and the logical relationship between the code. If a method is found to be slow in the performance test, you can input the timestamp before and after the method and output it to the log to view the execution time of the method.

With the basics above, you’ll have no problem developing common performance scripts.

Four, problem,

  1. When would you need to use JSR233 Sampler to save values to files?
  2. When is the Debug Sampler needed?