禅道博客

分享专业技术知识,文章内容干货满满

测试开发之接口篇-使用K6完成接口自动化测试

2023-05-10 09:30:00
陈琦
原创 1178
摘要:K6是一个优秀的开源性能测试工具,它提供了简洁又丰富的API,灵活和易用的描述性语法。

K6是一个优秀的开源性能测试工具,它提供了简洁又丰富的API,灵活和易用的描述性语法。以下列出K6中的几个概念:

  • Metrics:测试度量的指标。如请求响应时间、执行耗时、检查点通过率、失败次数等;
  • Thresholds:定义了指标度量的成功、失败标准。如请求失败率小于5%,迭代执行耗时平均小于3秒;
  • Checks:测试用例的检查点。如响应状态码等于200,响应内容包括文本关键字等;
  • Tags:可作用于请求、指标、阀值和检查点的标签,便于分类进行统计;
  • Groups:以函数的形式对脚本进行逻辑划分,以方便进行分类统计分析;
  • Scenarios:用于控制性能测试中的加压方式和过程,如虚拟用户数量和加载、并发集合点、迭代模式等。

本文针对接口测试的目标,需要我们在脚本中实现以下的控制处理,这里不涉及更多的性能测试的有关内容。

  1. 控制并发用户数和接口调用次数;
  2. 验证指定编号用例的请求响应时间平均值小于6秒;
  3. 验证某个分组中请求的响应时间90%小于6秒;
  4. 验证某个分组整体脚本执行时间平均值小于6秒;
  5. 使用多级分组模拟测试套件及其子套件;
  6. 支持在检查点配置测试用例编号和名称;
  7. 输出JSON格式的测试结果摘要和日志文件。

下面我们看一下示例的脚本,完整的脚本文件请访问GitHub

import http from 'k6/http'; import exec from 'k6/execution'; import { check, sleep, group } from "k6";
export const options = {
    // 设置并发用户数及其加载方式
    stages: [
        { duration: "2s", target: 3 }, // 2秒内,加载3个虚拟用户
        { duration: "1s", target: 0 }, // 1秒内,销毁所有虚拟用户
    ],
    // 设置性能有关指标的阀值,形如{id:1}标签的指标会影响指定用例的成败。
    thresholds: {
        // 验证编号为1的用例的响应时间,平均值小于1000毫秒 'http_req_duration{id:1}': ['avg < 1'],
        // '用户登录'分组中所有请求的响应时间,90%小于6000毫秒 'http_req_duration{group:::登录请求}': ['p(90) < 6000'],
        // '用户登录'分组的整体执行时间,平均值小于6000毫秒 'group_duration{group:::登录请求}': ['avg < 6000'],
    },
};
export default function () {
    // 单元测试套件 group('用户登录', function () {
        let resp = http.get('https://httpbin.org/get?p1=1', {
            tags: { id: '1' }, // 标记用例编号为1,用于上述阀值统计
        });
        // 期待响应状态码
        let expectRespStatus = 200 // 通过设置错误的期待结果,模拟三分之一的迭代失败
        // if (+`${exec.vu.idInTest}` % 3 === 0) {
        //     expectRespStatus = 222 // }
        // console.log(`in iteration ${exec.vu.idInTest}, expectRespStatus=${expectRespStatus}`)
        // 验证器方法,可以验证响应的状态码、耗时、内容等
        const validator = (r) => resp.status == expectRespStatus
        // 注意:此处的检查点和前面定义的阀值'http_req_duration{id:1}'均会影响用例的成败
        // 断言方法(用例ID, 用例名称,验证点名称,被验证数据,验证器) assert(1, '微信扫码登录', '验证跳转到个人仪表盘', resp, validator);
        // 子套件'用户登录-登录次数限制'及其下用例代码 group('失败次数限制', function () { assert(0, '登录失败连续3次,账号锁定', '显示账号已被锁定', resp, (r) => true); assert(0, '登录非连续性失败累计达到3次,账号不锁定', '可成功登录', resp, (r) => true); assert(0, '锁定账号15分钟后自动解禁', '解禁后可成功登录', resp, (r) => true);
        });
        // 当前套件'用户登录'下的另一个用例 group('CASE', function () { assert(0, '邮箱登录', '验证到达首页', resp, (r) => resp.status == 200);
        });
        sleep(1);
    }); group('用户管理', function () { // 单元测试套件
        const resp = http.post('https://httpbin.org/post', JSON.stringify({
            foo: 'abc',
            bar: '123',
        }), {
            tags: { foo: 'bar' },
            headers: { 'Content-Type': 'application/json',
            },
        });
        // 验证器
        const validator = (data) => {
            const status = data.status
            const dur = data.timings.duration
            // console.log('===', status, dur)
            // 验证状态码和响应时间
            const pass = status == 200 && dur < 6000 return pass
        }
        // 断言:用例ID, 用例名称,验证点名称,被验证数据,验证器 assert(0, '重置密码', '验证用户收到密码重置右键', resp, validator);
        sleep(1);
    });
}
export function setup() {
    console.log('--- setup')
}
export function teardown(data) {
    console.log('--- teardown')
}
// 配置ZTF执行时请保留该函数,否则thresholds阀值结果不会影响用例结果
// export function handleSummary(data) {
// return {
// 'results/summary.json': JSON.stringify(data), //the default data object //     };
// } function assert (caseId, caseName, checkpoint, data, validator) {
    const name = `${caseId} - ${caseName}`
    const tags = { id: caseId, name: caseName, checkpoint: checkpoint} check(data, { [name]: validator }, tags);
}

在命令行执行以下命令:

k6 run main.js

得到下列控制台输出:

running (05.0s), 0/3 VUs, 3 complete and 0 interrupted iterations default ✓ [======================================] 0/3 VUs  3s
     █ setup
     █ 用户登录
       ✓ 1 - 微信扫码登录
       █ 失败次数限制
         ✓ 0 - 登录失败连续3次,账号锁定
         ✓ 0 - 登录非连续性失败累计达到3次,账号不锁定
         ✓ 0 - 锁定账号15分钟后自动解禁
       █ CASE
         ✓ 0 - 邮箱登录
     █ 用户管理
       ✓ 0 - 重置密码
     █ teardown
     checks.........................: 100.00% ✓ 18       ✗ 0  
     data_received..................: 20 kB   4.0 kB/s
     data_sent......................: 2.2 kB  443 B/s
     group_duration.................: avg=857.26ms min=25.43µs med=604.99ms max=2.02s    p(90)=1.84s    p(95)=1.92s   
     ✓ { group:::登录请求 }.............: avg=0s min=0s med=0s max=0s       p(90)=0s       p(95)=0s      
     http_req_blocked...............: avg=320.83ms min=0s med=307.26ms max=668.21ms p(90)=655.24ms p(95)=661.73ms
     http_req_connecting............: avg=107.18ms min=0s med=101.03ms max=238.79ms p(90)=220.52ms p(95)=229.66ms
     http_req_duration..............: avg=392.41ms min=205.38ms med=283.97ms max=702.8ms  p(90)=686.37ms p(95)=694.58ms
       { expected_response:true }...: avg=392.41ms min=205.38ms med=283.97ms max=702.8ms  p(90)=686.37ms p(95)=694.58ms
     ✓ { group:::登录请求 }.............: avg=0s min=0s med=0s max=0s       p(90)=0s       p(95)=0s      
     ✓ { id:1 }.....................: avg=257.77ms min=205.38ms med=209.42ms max=358.51ms p(90)=328.69ms p(95)=343.6ms 
     http_req_failed................: 0.00%   ✓ 0        ✗ 6  
     http_req_receiving.............: avg=92.33µs min=60µs med=98µs max=125µs    p(90)=115.49µs p(95)=120.25µs
     http_req_sending...............: avg=348.5µs min=206µs med=306µs max=565µs    p(90)=499µs    p(95)=531.99µs
     http_req_tls_handshaking.......: avg=211.06ms min=0s med=206.07ms max=429.09ms p(90)=427.12ms p(95)=428.1ms 
     http_req_waiting...............: avg=391.97ms min=204.69ms med=283.6ms max=702.28ms p(90)=685.91ms p(95)=694.09ms
     http_reqs......................: 6       1.19129/s
     iteration_duration.............: avg=2.05s min=51.71µs med=3.03s max=3.69s    p(90)=3.64s    p(95)=3.66s   
     iterations.....................: 3       0.595645/s
     vus............................: 1 min=1 max=3
     vus_max........................: 3 min=3 max=3

脚本执行结束后,K6会以他默认的形式来展示测试日志和结果。为了达成上述的接口测试目标,下文我们将介绍,如何分析K6测试结果、并提交到禅道测试管理系统中。

暂时没有记录
评论通过审核后显示。