为什么要写测试平台

从事测试行业也有几年了,也用过很多的测试平台。之前看到过一位大佬说,当你从事测试几年后,你是想当一个工具的制造者还是做一个使用者。我想,我是想当一个制造者。 

2020第四季度的时候使用 Django + DRF + vue2 + HttpRunner2.x 写过一个半成品的接口自动化平台,后面由于一些原因就没有在写。直到 2021 年的第四季度,由于一些原因,又开始搞接口自动化测试平台了。

这次前端用的技术栈是 vue3 的 Composition API 语法(基于最新的 3.2.x 版本的 script setup 语法)、typescript、vite,element-plus 以及 vue3 的全家桶。

为什么要用 vue3 和 ts ?

当然是更快更好用,composition-api 更加适合大项目,ts 的可靠性和可维护性更高,虽然可能我用不到这些特性,但并不影响我以后出去面试的时候吹牛逼。

后端使用的是 Python 的 FastAPI 框架 + sqlalchemy + mysql + Apscheduler + pydantic 等

最早看到 FastAPI 框架是在 HttpRunner3.x 的源码里看到的,当时读源码的时候不知道这个库是做什么的,然后就去 Google 上搜索了一下。当时网上关于 FastAPI 的资料还是比较少的,就去看了下官网,从刚开始打算了解一下,到花了一下午的时间,都看啃官网文档。看完官方文档之后就放弃用了几年的 Django 框架。

平台大体可以分为三个部分。第一部分也是最主要的。运行 api 并且返回测试结果。我起名为 LRUN,L 代表了我姓的首字母和公司英文的首字母。它的主要功能就是传入一个 yaml 路径,在内部对 yaml 文件进行处理,包括参数提取、参数替换、断言、hooks,最后返回测试结果。

例如下面的 yaml 内容,实现了四个接口。登录接口,登录成功后获取到 token,保存为变量,在传给后面的接口,可以在请求头里使用提取到的变量。新增供应商,字段 contacts 是不能重复的,所以我写了个随机生成名称的方法,在这里直接调用这个方法。也可以选择该接口是否执行、执行次数、请求前置、请求后置等

- config:
    base_url: http://47.101.111.187:8081
    headers: {}
    name: 冒烟测试
    variables: {}
- test:
    extract:
      code: body.code
      token: body.data.token
    mock: false
    name: 登录接口
    request:
      headers:
        Accept-Language: zh-cn
      json:
        password: zouzou
        username: zouzou
      method: POST
      url: /api/user/login
    setup_hooks:
    - ${hook_down()}
    - ${hook_down()}
    skip: false
    ssl: true
    teardown_hooks:
    - ${hook_down()}
    times: 1
    validate:
    - eq:
      - body.code
      - '2001'
    - eq:
      - body.msg
      - login success
    - eq:
      - status_code
      - 200
- test:
    extract: {}
    mock: false
    name: 新增供应商
    request:
      headers:
        Authorization: JWT ${token}
      json:
        contacts: ${staff_name()}
        contacts_iphone: '17111111111'
        id: null
        remarks: '12'
        supplier_name: ${staff_name()}
      method: PUT
      url: /api/manage/supplier
    skip: false
    ssl: false
    times: 1
    validate:
    - ne:
      - body.msg
      - 供应商添加成功
- test:
    extract:
      id: body.data[0].id
    mock: false
    name: 查询员工数据
    request:
      headers:
        Authorization: JWT ${token}
      json:
        account: ''
        name: ''
      method: POST
      url: /api/manage/search/supplier?page=1&size=10
    skip: false
    ssl: true
    times: 1
    validate:
    - eq:
      - body.code
      - '2001'
    - eq:
      - status_code
      - 200
    - len_gt:
      - body.data
      - 8
- test:
    extract: {}
    mock: false
    name: 删除供应商
    request:
      headers:
        Authorization: JWT ${token}
      json: {}
      method: DELETE
      url: /api/manage/supplier?id=${id}
    skip: false
    ssl: false
    times: 1
    validate:
    - eq:
      - body.msg
      - 删除成功

各参数意义如下

  • test:一个 test 为一个接口用例
  • ​times:接口运行次数

  • skip:是否跳过接口

  • SSL:是否开启 SSL 验证。

  • mock:是否 mock 接口(目前功能还未实现)

  • request:填写请求信息,请求方式、请求体、path 等

  • extract:提取接口响应里的参数,支持提取响应头、响应体、响应 cookies。

  • validate:断言,支持丰富的断言方式(13种断言方式,满足接口测试断言的多种场景),eq 表示断言相等,not_equal 不等于

  • setup_hooks:请求前置,可以做一些加密处理

  • teardown_hooks:请求后置

运行上面的 yaml 文件后返回的结果如下,会返总耗时、总接口数、成功用例数、失败用例数、跳过的用例数。还有单个接口的详细信息。

{
    "name":"冒烟测试",
    "total":4,
    "case_id":"adaad59f-af5f-409e-87e1-d621a97f7985",
    "success":false,
    "success_total":3,
    "fail_total":1,
    "total_time":0.156,
    "skip":0,
    "step_data":[
        {
            "details":[
                {
                    "results":{
                        "name":"登录接口",
                        "success":true,
                        "time":"2021-12-30 22:48:38",
                        "duration_ms":23.52,
                        "content_size":192
                    }
                },
                {
                    "request":{
                        "url":"http://47.101.111.187:8081/api/user/login",
                        "headers":{
                            "User-Agent":"python-requests/2.26.0",
                            "Accept-Encoding":"gzip, deflate",
                            "Accept":"*/*",
                            "Connection":"keep-alive",
                            "Accept-Language":"zh-cn",
                            "Content-Length":"44",
                            "Content-Type":"application/json"
                        },
                        "method":"POST",
                        "body":{
                            "password":"zouzou",
                            "username":"zouzou"
                        }
                    }
                },
                {
                    "response":{
                        "status_code":200,
                        "reason":"OK",
                        "headers":{
                            "Connection":"close",
                            "Content-Length":"192",
                            "Allow":"POST, OPTIONS",
                            "Content-Type":"application/json",
                            "Date":"Thu, 30 Dec 2021 14:48:38 GMT",
                            "Referrer-Policy":"same-origin",
                            "Server":"nginx/1.16.1",
                            "Vary":"Accept, Origin, Cookie",
                            "X-Content-Type-Options":"nosniff",
                            "X-Frame-Options":"DENY"
                        },
                        "cookies":{
​
                        },
                        "body":{
                            "code":"2001",
                            "success":true,
                            "msg":"login success",
                            "data":{
                                "token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTY0MTQ4MDUxOH0.nipBF4Ov1QgofPx7lGgoDPlS9_saWUbSpFUAzZfimts"
                            }
                        }
                    }
                },
                {
                    "validate":{
                        "validate_extractor":[
                            {
                                "comparator":"equal",
                                "check":"body.code",
                                "check_value":"2001",
                                "expect_value":"2001",
                                "check_result":"pass"
                            },
                            {
                                "comparator":"equal",
                                "check":"body.msg",
                                "check_value":"login success",
                                "expect_value":"login success",
                                "check_result":"pass"
                            },
                            {
                                "comparator":"equal",
                                "check":"status_code",
                                "check_value":200,
                                "expect_value":200,
                                "check_result":"pass"
                            }
                        ]
                    }
                }
            ]
        },
        {
            "details":[
                {
                    "results":{
                        "name":"新增供应商",
                        "success":true,
                        "time":"2021-12-30 22:48:38",
                        "duration_ms":23.18,
                        "content_size":58
                    }
                },
                {
                    "request":{
                        "url":"http://47.101.111.187:8081/api/manage/supplier",
                        "headers":{
                            "User-Agent":"python-requests/2.26.0",
                            "Accept-Encoding":"gzip, deflate",
                            "Accept":"*/*",
                            "Connection":"keep-alive",
                            "Authorization":"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTY0MTQ4MDUxOH0.nipBF4Ov1QgofPx7lGgoDPlS9_saWUbSpFUAzZfimts",
                            "Content-Length":"136",
                            "Content-Type":"application/json"
                        },
                        "method":"PUT",
                        "body":{
                            "contacts":"测试204260",
                            "contacts_iphone":"17111111111",
                            "id":null,
                            "remarks":"12",
                            "supplier_name":"测试204260"
                        }
                    }
                },
                {
                    "response":{
                        "status_code":200,
                        "reason":"OK",
                        "headers":{
                            "Connection":"close",
                            "Content-Length":"58",
                            "Allow":"GET, POST, PUT, DELETE, HEAD, OPTIONS",
                            "Content-Type":"application/json",
                            "Date":"Thu, 30 Dec 2021 14:48:38 GMT",
                            "Referrer-Policy":"same-origin",
                            "Server":"nginx/1.16.1",
                            "Vary":"Accept, Origin",
                            "X-Content-Type-Options":"nosniff",
                            "X-Frame-Options":"DENY"
                        },
                        "cookies":{
​
                        },
                        "body":{
                            "code":"4001",
                            "success":false,
                            "msg":"供应商不存在"
                        }
                    }
                },
                {
                    "validate":{
                        "validate_extractor":[
                            {
                                "comparator":"not_equal",
                                "check":"body.msg",
                                "check_value":"供应商不存在",
                                "expect_value":"供应商添加成功",
                                "check_result":"pass"
                            }
                        ]
                    }
                }
            ]
        },
        {
            "details":[
                {
                    "results":{
                        "name":"查询员工数据",
                        "success":false,
                        "time":"2021-12-30 22:48:38",
                        "duration_ms":29.99,
                        "content_size":752
                    }
                },
                {
                    "request":{
                        "url":"http://47.101.111.187:8081/api/manage/search/supplier?page=1&size=10",
                        "headers":{
                            "User-Agent":"python-requests/2.26.0",
                            "Accept-Encoding":"gzip, deflate",
                            "Accept":"*/*",
                            "Connection":"keep-alive",
                            "Authorization":"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTY0MTQ4MDUxOH0.nipBF4Ov1QgofPx7lGgoDPlS9_saWUbSpFUAzZfimts",
                            "Content-Length":"27",
                            "Content-Type":"application/json"
                        },
                        "method":"POST",
                        "body":{
                            "account":"",
                            "name":""
                        }
                    }
                },
                {
                    "response":{
                        "status_code":200,
                        "reason":"OK",
                        "headers":{
                            "Connection":"close",
                            "Content-Length":"752",
                            "Allow":"GET, POST, HEAD, OPTIONS",
                            "Content-Type":"application/json",
                            "Date":"Thu, 30 Dec 2021 14:48:38 GMT",
                            "Referrer-Policy":"same-origin",
                            "Server":"nginx/1.16.1",
                            "Vary":"Accept, Origin",
                            "X-Content-Type-Options":"nosniff",
                            "X-Frame-Options":"DENY"
                        },
                        "cookies":{
​
                        },
                        "body":{
                            "code":"2001",
                            "success":true,
                            "msg":"",
                            "total":4,
                            "data":[
                                {
                                    "id":58,
                                    "update_time":"2021-11-02 14:16:18",
                                    "create_time":"2021-11-02 14:16:18",
                                    "supplier_name":"1635833778109",
                                    "contacts":"解耦",
                                    "contacts_iphone":"",
                                    "remarks":""
                                },
                                {
                                    "id":57,
                                    "update_time":"2021-11-02 14:15:32",
                                    "create_time":"2021-11-02 14:15:32",
                                    "supplier_name":"1635833732898",
                                    "contacts":"解耦",
                                    "contacts_iphone":"",
                                    "remarks":""
                                },
                                {
                                    "id":56,
                                    "update_time":"2021-11-02 11:26:41",
                                    "create_time":"2021-11-02 11:26:41",
                                    "supplier_name":"1635823601082",
                                    "contacts":"解耦",
                                    "contacts_iphone":"",
                                    "remarks":""
                                },
                                {
                                    "id":42,
                                    "update_time":"2021-11-01 17:47:45",
                                    "create_time":"2021-11-01 17:47:45",
                                    "supplier_name":"供应商",
                                    "contacts":"李明明",
                                    "contacts_iphone":"15511112222",
                                    "remarks":"测试备注"
                                }
                            ]
                        }
                    }
                },
                {
                    "validate":{
                        "validate_extractor":[
                            {
                                "comparator":"equal",
                                "check":"body.code",
                                "check_value":"2001",
                                "expect_value":"2001",
                                "check_result":"pass"
                            },
                            {
                                "comparator":"equal",
                                "check":"status_code",
                                "check_value":200,
                                "expect_value":200,
                                "check_result":"pass"
                            },
                            {
                                "comparator":"length_greater_than",
                                "check":"body.data",
                                "check_value":[
                                    {
                                        "id":58,
                                        "update_time":"2021-11-02 14:16:18",
                                        "create_time":"2021-11-02 14:16:18",
                                        "supplier_name":"1635833778109",
                                        "contacts":"解耦",
                                        "contacts_iphone":"",
                                        "remarks":""
                                    },
                                    {
                                        "id":57,
                                        "update_time":"2021-11-02 14:15:32",
                                        "create_time":"2021-11-02 14:15:32",
                                        "supplier_name":"1635833732898",
                                        "contacts":"解耦",
                                        "contacts_iphone":"",
                                        "remarks":""
                                    },
                                    {
                                        "id":56,
                                        "update_time":"2021-11-02 11:26:41",
                                        "create_time":"2021-11-02 11:26:41",
                                        "supplier_name":"1635823601082",
                                        "contacts":"解耦",
                                        "contacts_iphone":"",
                                        "remarks":""
                                    },
                                    {
                                        "id":42,
                                        "update_time":"2021-11-01 17:47:45",
                                        "create_time":"2021-11-01 17:47:45",
                                        "supplier_name":"供应商",
                                        "contacts":"李明明",
                                        "contacts_iphone":"15511112222",
                                        "remarks":"测试备注"
                                    }
                                ],
                                "expect_value":8,
                                "check_result":"fail"
                            }
                        ]
                    }
                }
            ]
        },
        {
            "details":[
                {
                    "results":{
                        "name":"删除供应商",
                        "success":true,
                        "time":"2021-12-30 22:48:38",
                        "duration_ms":30.85,
                        "content_size":51
                    }
                },
                {
                    "request":{
                        "url":"http://47.101.111.187:8081/api/manage/supplier?id=58",
                        "headers":{
                            "User-Agent":"python-requests/2.26.0",
                            "Accept-Encoding":"gzip, deflate",
                            "Accept":"*/*",
                            "Connection":"keep-alive",
                            "Authorization":"JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjEsImV4cCI6MTY0MTQ4MDUxOH0.nipBF4Ov1QgofPx7lGgoDPlS9_saWUbSpFUAzZfimts",
                            "Content-Length":"2",
                            "Content-Type":"application/json"
                        },
                        "method":"DELETE",
                        "body":{
​
                        }
                    }
                },
                {
                    "response":{
                        "status_code":200,
                        "reason":"OK",
                        "headers":{
                            "Connection":"close",
                            "Content-Length":"51",
                            "Allow":"GET, POST, PUT, DELETE, HEAD, OPTIONS",
                            "Content-Type":"application/json",
                            "Date":"Thu, 30 Dec 2021 14:48:38 GMT",
                            "Referrer-Policy":"same-origin",
                            "Server":"nginx/1.16.1",
                            "Vary":"Accept, Origin",
                            "X-Content-Type-Options":"nosniff",
                            "X-Frame-Options":"DENY"
                        },
                        "cookies":{
​
                        },
                        "body":{
                            "code":"2002",
                            "success":true,
                            "msg":"删除成功"
                        }
                    }
                },
                {
                    "validate":{
                        "validate_extractor":[
                            {
                                "comparator":"equal",
                                "check":"body.msg",
                                "check_value":"删除成功",
                                "expect_value":"删除成功",
                                "check_result":"pass"
                            }
                        ]
                    }
                }
            ]
        }
    ]
}
查看返回结果

相关文章:

  • 2022-12-23
  • 2022-01-08
  • 2021-09-29
  • 2022-12-23
  • 2021-08-01
  • 2017-11-24
  • 2022-12-23
  • 2022-01-08
猜你喜欢
  • 2021-07-20
  • 2019-01-28
  • 2021-11-07
  • 2021-11-07
  • 2022-12-23
  • 2021-06-16
相关资源
相似解决方案