Use Postman for API automated testing

The most basic function of Postman is used to replay the request, and it cooperates with a good response formatting tool.

For advanced usage, you can use Postman to generate scripts in various languages, and you can also capture packets, authenticate, and transfer files.

Merely doing this is not enough for the development of a system, or it is too trivial. You still need to switch back and forth between the development environment, the test environment, and the production environment frequently. A single request is not enough. You need to maintain all API requests of the system, and each request also has a different querystring and body.

Collection

All requests on the server side are organized by function or business module. Use markdown to add appropriate descriptions to all requests and examples. At this time, Collection is used. The following are some of postman's terminology and suggestions for organizational requests.

  • Collection corresponds to an Application, and each member (server, client, QA) in the group shares a Collection. You can add tests and documents to the entire Collection. For applications that did not organize requests in postman at the beginning, you can set up Proxy, run the application again, and capture all the requests of the application.

  • Folder (ItemGroup) corresponds to a module or sub-routes of each level. If  router.use('/users') all requests are in a folder, folders can be nested into each other according to routing.

  • Request (Item) corresponds to a request and can add authentication information. You can also set up a proxy to capture packets.

  • Example corresponds to a request with different parameters and responses, and is used for Mock Server and documents.

Postman can generate documents and Mock Server according to the structure of the Collection. But they are all paid functions, and the free version has a limit on the number of times.

Documentation

Postman automatically generates documents to help team collaboration, and solves the major bugs of manual document writing and untimely updating.

For GET requests, a description of the field can be added on Postman to generate a document.

For POST and PUT requests, if the Content-Type is  form-data or  x-www-form-urlencoded you can add a description to generate a document. However, passing json is more convenient and flexible nowadays, so there  application/json will be many, and json cannot be commented. If you need to add documentation to json, you can add redundant fields to  _{key}.comment indicate comments

{
  "id": 128,
  "_id.comment": "id",
  "page": 10,
  "_page.comment": "页数"
  "pageSize": 15,
  "_pageSize.comment": "每页条数"
}

However, there are too many redundant fields, and a better solution is to perform json verification on the request in the test, and at the same time serve as a part of the document function. After all, json-schema is used to describe data to make it more readable.

Speaking of the request above, for the response document, you can verify the json-schema or the description of each field, and more test cases represent more details.

Mock

When the server has not written the API, the client can generate Mock Server according to Examples.

It is recommended that the client do its own Mock, integrate it with the project, and incorporate version control, which is convenient and flexible.

test

For each Request, a test case is required. Verify whether the response is successful, whether the response time is too long, or whether the data type of the response json is correct.

The test can be used  pm.expect for  BDD testing, and the style is  chai very similar. If you are familiar with  chai it, it is easy to get started.

Postman has some built-in third-party libraries. If you prefer  chai , you can use it directly, or use the  pm.expect underlying chai implementation, which is consistent with the chai BDD API.

Postman also has some http-related test APIs, such as status code, header, body, and also provides some snippets.

// 响应成功
pm.test('Status code is 200', () => {
  pm.response.to.have.status(200)
})

// 响应成功 chai.expect
pm.test('Status code is 200', () => {
  chai.expect(pm.response).to.have.property('code', 200)
})

// 校验响应数据
pm.test('Page is 100', () => {
  const jsonData = pm.response.json()
  chai.expect(jsonData.page).to.eql(100)
})

Json Schema

json-schema can be used to describe json information, make json more readable, and it can also be used to verify the legitimacy of json. Major languages ​​have libraries that implement json-schema.

It is recommended to perform json-schema verification on all GET responses, firstly to verify the data, secondly it can also be used as a document, use tv4 to verify json

pm.test("User info", () => {
  const jsonData = pm.response.json()
  const schema = {
    title: 'UserInfo',
    discription: '用户信息',
    type: 'object',
    required: ['age', 'email', 'name'],
    properties: {
      age: {
        description: '年龄',
        type: 'number',
        mininum: 0,
      },
      email: {
        description: '邮箱',
        type: 'string' 
      },
      name: {
        description: '姓名',
        type: 'string' 
      }
    }
  }
  pm.expect(tv4.validate(jsonData, schema)).to.eql(true)
})

You can also add json verification to the request, but it is more complicated, because postman does not directly give the api to get all the request parameters, you need to parse and calculate it yourself

// 获取 application/json 中的数据
const json = JSON.stringify(pm.request.body.raw)

// 获取 GET query string 的数据
const qs = pm.request.url.query.toObject()

It would be great if postman could automatically generate data based on the json-schema of the request parameters...

Test request parameters

A request with a number of parameters, such as  GET the  querystring(search) well as  POST the  bodydifferent parameters have different response.

Assuming that the json schema returned by different parameters of a request is completely different, you can write two Requests to test separately. If the returned json schema is the same, but the value is different, you need to consider which parameters are passed and how many parameters are.

In a classic scenario, the qualified list is filtered according to filter. Take the user list as an example, the pseudo code is as follows

const url = '/api/users'
const query = {
  name: 'san',
  age: 12,
  sex: 'MALE'
}
// 注意query数据需要校验,防止 SQL 注入
const sql = `select * from users where name = ${query.name} and age = ${query.age} and sex = ${query.sex}`

One idea is to test according to the requested parameters. An important snipet is to obtain querystring in postman. Query is a type  PropertyList of data defined in postman-collection-PropertyList. as follows

const name = pm.request.url.query.get('name')
const age = pm.request.url.query.get('age')

if (name) {
  pm.test('Items should match the name', () => {
    const jsonData = pm.response.json()
    expect(_.uniq(jsonData.rows.map(row => row.name))).to.eql([name])
  })
}

// 冗余代码有些多,postman不知道支不支持自建 snipets
if (age) {
  pm.test('Items should match the age', () => {
    const jsonData = pm.response.json()
    expect(_.uniq(jsonData.rows.map(row => row.age))).to.eql([age])
  })
}

Of course, the above filter only contains the simplest scenario, which only involves the equality test. But there are disparity and inclusion relations.

const query = {
  name: 'san',
  age: 12,
  sex: 'MALE'
}
const sql = `select * from users where name like ${query.name} and age < ${query.age} and sex = ${query.sex}`

This kind of request parameter depends on the negotiation and communication between the front and back ends, of course, it is very unfriendly for testing or an unknowing development.

Of course, it is not friendly to the backend, because you need to process each query you pass in, and you need to manually change it every time you add a filter field in the future.

It is up to the front end to determine the data to be filtered, such as using a search syntax similar to mongo.

graphql is pretty cool, it's worth trying

const query = {
  name: {
    $like: 'san' 
  },
  age: {
    $lt: 12 
  },
  sex: 'MALE'
}

However, this requires relatively high test development capabilities, and testers need to analyze parameters and test interfaces.

Test multiple requests

When unit testing a function, a lot of input and expected output are required. In postman, it can be used  data to simulate multiple inputs

data is a variable that can only be used in Runner. It is necessary to establish a related data file for each Folder and add version control

  • using csv and json files in the postman collection runner

Integration Testing

After a single API test is passed, all requests need to be integrated for testing. At this time there are two problems

  1. How to ensure API dependency
  2. How to pass data between APIs

It is the order of their request that initiated the request in order Collection, and if necessary to force to change the order, you can use  setNextRuest()three scope of the data in the postman, data, environment, global. { {}} Replace with placeholders in the request  .

environment It can be used to change  HOSTto avoid frequent manual switching of the local environment, development environment and production environment in the URL. It can also be used to transfer data.

A common scenario is that the project uses token to save login information, and each request needs to carry the token. The environment variable of the token can be set in the login test code

const url = 'http://{
   
   {HOST}}/api/login'

pm.test('There is a token', () => {
  const jsonData = pm.response.json()
  pm.expect(jsonData.token).to.a('string')
  pm.environment.set('token', jsonData.token)
})

const urlNext = 'http://{
   
   {HOST}}/api/profile?token={
   
   {token}}'

Test Collection

After ensuring the dependencies, you can create a new Runner to the Collection and introduce a data file to test all requests. You can also use Runner and data to test the partial Folder.

The latest version of postman is already supported, create new variables and Tests for each Postman

All requests will have some common tests, such as whether the test interface responds successfully and the test filter mentioned above

pm.test('Response is right', () => {
  // status code: 2XX
  pm.response.to.be.success
})

pm.test('Filter is matching', () => {
  // ...
})

Continuous integration

When you can test the Collection, you need to add version control to the test, integrate it with the project, and keep test records to locate bugs on time. It can be newman integrated with postman's official tools  , but one inconvenience is that continuous integration can only save records, not restore records.

newman run https://api.getpostman.com/collections/{
   
   {collection_uid}}?apikey={
   
   {postman-api-key-here}} --environment https://api.getpostman.com/environments/{
   
   {environment_uid}}?apikey={
   
   {postman-api-key-here}}

Contrast UI automation testing

According to my understanding, the purpose of UI automation testing is to test whether the process is smooth, such as logging in, registering, and logging out, and screenshots if the use case fails. However, the constant changes in front-end requirements, coupled with various front-end frameworks now, make selectors not particularly easy to obtain and the process is easy to change.

The API automated test is used to test whether the data is correct. And most of the problems are data problems, so API automated testing is more cost-effective.
If you exchange experience in software testing, interface testing, automated testing, and interviews. If you are interested, you can add software test communication: 1085991341, and there will be technical exchanges with colleagues.

to sum up

  1. How to write test cases

[chai.js] The bdd grammar used at the bottom  of postman is used as an assertion library, and some unique grammars are added.

  1. How to debug

Click on the menu bar View -> Show Devtools (Show Postman Console) to view the response and check the output, but you cannot interrupt the point. For a single request of the system, you can use Proxy to monitor the request for debugging.

  1. How to use js third-party libraries to pre-process and post-process requests

For example: When sending a request, the server requires timestmap(unix) the format of the time  , but the readability of the interface is too weak when debugging, can the moment conversion time be used  ? When you receive a response, you also need  moment to analyze the time to get a better presentation. Or use  lodash some functions for data processing.

You can write scripts in Tests and Pre-request Script to do some processing on requests and responses. But you cannot format data, such as dates. It is recommended to use ISO formatted strings when communicating the date between the front and back ends. Both front and back ends are easy to parse and readable.

  1. How to manage request dependencies

For example: Two APIs need to have a dependency relationship. For example, when a user is created (registered), his personal information is obtained. To obtain personal information, you need to rely on the API to create a user.

Use Environment Variables to manage dependencies

  1. How to set uniform request parameters

For example: Most interfaces require uniform  token parameters.

There seems to be no way

  1. How to integrate into server-side projects

If the subsequent version of the system fails the API test, it is important to keep the test record, and version control can know the code changes during this time period. Take git as an example, you need to run the test after each submission and keep the test results.

You can use the npm package newman to integrate into the project

The above content is the entire content of this article. The above content hopes to be helpful to you. Friends who have been helped are welcome to like and comment.

Guess you like

Origin blog.csdn.net/Chaqian/article/details/106627548