如上所述
k6 run ../tests/http_get.js
我该如何在单次运行中执行多个脚本文件?特别是指位于给定本地目录中的所有脚本。例如:
k6 run ../tests/
k6原生支持这个吗?
如上所述
k6 run ../tests/http_get.js
我该如何在单次运行中执行多个脚本文件?特别是指位于给定本地目录中的所有脚本。例如:
k6 run ../tests/
k6原生支持这个吗?
根据您的设置,有几种不同的方法可以解决这个问题。一个相当直接的方法是在 Bash 中分叉 k6 运行命令。
Depending on your setup there are a couple different ways you can solve this. A pretty straight forward way is to fork the k6 run command inside bash.
#!/bin/sh
k6 run test1_spec.js &
k6 run test2_spec.js &
k6 run test3_spec.js
你可以轻松编写一些更复杂的Bash脚本来读取/tests/目录中的所有内容并运行它们。但我选择这样做是因为我需要为每个特定的测试提供一些自定义输入参数。
另一种方法是编写一个Docker Compose脚本来完成几乎相同的操作。这将为每个测试启动一个Docker容器并在其中运行。 k6 Docker镜像只不过是添加了k6二进制文件的小型Linux镜像而已。
version: '3'
services:
k6_test:
image: loadimpact/k6
container_name: test_k6
volumes:
- ./:/specs
command: run /tests/test_spec.js
ports:
- "6565:6565"
k6_test2:
image: loadimpact/k6
container_name: test2_k6
volumes:
- ./:/specs
command: run /tests/test2_spec.js
ports:
- "6566:6566"
这两种方法都应该允许你在CI环境和本地机器上同时运行多个测试。
目前,k6只接受一个脚本文件,并运行默认导出的函数。
import {sleep} from "k6";
import http from "k6/http";
export default function() {
http.get("http://test.loadimpact.com/");
sleep(2);
}
import {sleep} from "k6";
import mainPageUserFlow from "../cases/main-page";
import billingUserFlow from "../cases/billing";
export default function() {
mainPageUserFlow();
billingUserFlow();
sleep(2);
}
group
和 group_duration
指标,就像这个链接中的示例 https://gist.github.com/ppcano/1442dc243321747ee146a6c90859fe89 一样。我建议你将你的示例发布在 https://community.k6.io/ 上,以便更好地帮助你。 - ppcanogroup
和系统度量group_duration
创建了一个阈值。https://docs.k6.io/docs/tags-and-groups#section-system-tags。标签和自定义度量非常灵活和强大;您可以在任何自定义标记的任何自定义度量上定义阈值。 - ppcano您可以设置不同的场景并指向包含脚本的不同文件以运行每个场景,如此文档所述 https://k6.io/docs/using-k6/k6-options/reference/#scenarios
以下是一个示例:
import { default as firstScenario } from './firstScenario';
import { default as secondScenario } from './secondScenario';
export const options: Options = {
thresholds: {
http_req_duration: [`p(99)<${httpReqDuration}`],
checks: ['rate>0.80'],
},
scenarios: {
scriptAuthenticatedScenario: {
exec: 'myFirstScenario',
executor: 'constant-vus',
vus,
duration,
},
scriptUnauthenticatedScenario: {
exec: 'mySecondScenario',
executor: 'constant-vus',
vus,
duration,
},
},
};
export function myFirstScenario() {
firstScenario();
}
export function mySecondScenario() {
secondScenario();
}
export function handleSummary(data) {
return {
'results/scenarios.html': htmlReport(data),
stdout: textSummary(data, { indent: ' ', enableColors: true }),
};
}
使用 &
将会并行运行测试,如果你想要按顺序运行并获取合并结果,我建议:
exit_c=0
(
k6 run script_1.js || exit_c=$?
k6 run script_2.js || exit_c=$?
...
k6 run script_n.js || exit_c=$?
exit $exit_c
)
当我刚开始学习 k6 时,我想看一个带有值的例子。
因此,这是一个示例,在我的'http://localhost: 3000/#/'下 = OWASP Juice Shop(用于安全测试培训的免费网页。您可以在本地安装和运行的页面):
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter, Rate } from 'k6/metrics';
export const requests = new Counter('http_reqs');
const myFailRate = new Rate('failed requests');
export const options = {
scenarios: {
main: { //Test Case 1
executor: 'constant-vus',
exec: 'main',
vus: 30,
duration: '90s',
},
login: { //Test Case 2
executor: 'constant-vus',
exec: 'login',
vus: 10,
startTime: '15s',
duration: '90s',
},
about: { //Test Case 3
executor: 'shared-iterations',
exec: 'about',
vus: 5,
iterations: 50,
startTime: '30s',
maxDuration: '90s',
},
}
}
export function main() { //Test Case 1
const res = http.get('http://localhost:3000/#/');
sleep(Math.random() * 5);
myFailRate.add(res.status !== 200);
const checkRes = check(res, {
'status was 200': (r) => r.status == 200,
'response body contains <OWASP Juice Shop>': (r) => r.body.indexOf('OWASP Juice Shop') !== -1,
'duration was <=200ms(miliseconds)': (r) => r.timings.duration <= 200,
});
}
export function login() { //Test Case 2
const res = http.get('http://localhost:3000/#/login');
sleep(Math.random() * 2);
myFailRate.add(res.status !== 200);
const checkRes = check(res, {
'status was 200': (r) => r.status == 200,
'response body contains <Login1>': (r) => r.body.includes("Login"), //Failure expected here. Not found, Yet I see it on the page
'response body contains <Login2>': (r) => r.body.includes('Login'), //Failure expected here. Not found, Yet I see it on the page
'response body contains <Login3>': (r) => r.body.indexOf('Login') !== -1, //Failure expected here. Not found, Yet I see it on the page
'response body contains <Login4>': (r) => r.body.indexOf("Login") !== -1, //Failure expected here. Not found, Yet I see it on the page
'response body contains <OWASP Juice Shop> in the Login page': (r) => r.body.indexOf('OWASP Juice Shop') !== -1,
'duration was <=200ms(Login)': (r) => r.timings.duration <= 200,
});
}
export function about() { //Test Case 3
const res = http.get('http://localhost:3000/#/about')
sleep(Math.random() * 5);
myFailRate.add(res.status !== 200);
const checkRes = check(res, {
'status was 200': (r) => r.status == 200,
'response body contains <About Us>': (r) => r.body.includes('About Us'), //Failure expected here. Not found, Yet I see it on the page
'response body contains <OWASP Juice Shop> in the About page': (r) => r.body.indexOf('OWASP Juice Shop') !== -1,
'duration was <=200ms(About)': (r) => r.timings.duration <= 200,
});
}
附注:解决方案已在k6 v0.43.1 (2023.04.20)上进行测试。