用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/InugamiDev/ultrathink-oss --skill load-testing命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Unified design foundations — design system architecture, tokens, component specs, visual principles, creative vision, figma integration, plus brand design system loader (66 real brands via DESIGN.md). Absorbs design, design-system, design-systems, design-principles, design-router, creative-vision, figma, design-md.
Render, summarize, and present markdown documents and structured content in multiple output modes
Ultra UI skill - combines Google's DESIGN.md spec (machine-readable design tokens) with the ui-ux-pro-max knowledge base (91 styles, 161 palettes, 73 font pairings, 161 products, 104 UX guidelines, 25 chart types). Generates lint-clean DESIGN.md files, validates token references and WCAG contrast, exports Tailwind/DTCG tokens, and diffs design systems version-over-version.
基于 SOC 职业分类
正在显示 SKILL.md
| name | load-testing |
| description | Load testing with k6, Artillery, Locust — traffic simulation, performance baselines, and stress testing. |
| layer | domain |
| category | testing |
| triggers | ["load test","stress test","k6","artillery","locust","performance test","benchmark"] |
| inputs | ["Target endpoints and expected traffic patterns","Performance SLOs or baseline requirements","Scalability testing scenarios","Bottleneck identification needs"] |
| outputs | ["Load test scripts for k6, Artillery, or Locust","Test execution strategies and configurations","Performance baselines and threshold definitions","Results analysis and bottleneck identification"] |
| linksTo | ["testing-strategy","performance-budget","monitoring"] |
| linkedFrom | [] |
| riskLevel | low |
| memoryReadPolicy | selective |
| memoryWritePolicy | none |
| sideEffects | [] |
Provide expert guidance on load testing, stress testing, and performance benchmarking using k6, Artillery, and Locust. Covers test design, traffic simulation, threshold definition, CI integration, and results analysis.
| Type | Purpose | Duration | Load Pattern |
|---|---|---|---|
| Smoke | Verify script works | 1-2 min | Minimal load (1-5 VUs) |
| Load | Validate expected traffic | 10-30 min | Ramp to expected peak |
| Stress | Find breaking point | 15-30 min | Ramp beyond expected peak |
| Soak | Find memory leaks, degradation | 1-4 hours | Sustained normal load |
| Spike | Test sudden traffic bursts | 5-10 min | Sudden jump then drop |
| Breakpoint | Find max capacity | Variable | Continuous ramp until failure |
Basic load test:
import http from "k6/http";
import { check, sleep } from "k6";
import { Rate, Trend } from "k6/metrics";
// Custom metrics
const errorRate = new Rate("errors");
const orderDuration = new Trend("order_duration", true);
export const options = {
: [
{ : , : },
{ : , : },
{ : , : },
{ : , : },
{ : , : },
],
: {
: [, ],
: [],
: [],
},
};
= __ENV. || ;
() {
productsRes = http.();
(productsRes, {
: r. === ,
: .(r.).. > ,
}) || errorRate.();
();
productRes = http.();
(productRes, {
: r. === ,
}) || errorRate.();
();
}
Authenticated user flow with scenarios:
import http from "k6/http";
import { check, group, sleep } from "k6";
export const options = {
scenarios: {
browse: {
executor: "ramping-vus",
startVUs: 0,
stages: [
{ duration: "2m", target: 200 },
{ duration: "5m", target: 200 },
{ duration: "2m", target: 0 },
],
exec: "browseProducts",
},
checkout: {
executor: "constant-arrival-rate",
rate: 10, // 10 iterations per second
timeUnit: "1s",
duration: "10m",
preAllocatedVUs: 50,
maxVUs: 100,
exec: "checkoutFlow",
},
},
thresholds: {
"http_req_duration{scenario:checkout}": ["p(95)<2000"],
"http_req_duration{scenario:browse}": ["p(95)<500"],
},
};
function authenticate() {
const res = http.post(`${BASE_URL}/api/v1/auth/login`, JSON.stringify({
email: `user${__VU}@test.com`,
password: "testpassword",
}), { headers: { "Content-Type": "application/json" } });
return JSON.parse(res.body).token;
}
export function browseProducts() {
group("Browse", () => {
http.get(`${BASE_URL}/api/v1/products`);
sleep(Math.random() * 3 + 1); // 1-4s think time
http.get(`${BASE_URL}/api/v1/products/${Math.floor(Math.random() * 100) + 1}`);
sleep(Math.random() * 2 + 0.5);
});
}
export function checkoutFlow() {
const token = authenticate();
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
};
group("Checkout", () => {
// Add to cart
const cartRes = http.post(`${BASE_URL}/api/v1/cart/items`, JSON.stringify({
productId: Math.floor(Math.random() * 100) + 1,
quantity: 1,
}), { headers });
check(cartRes, { "cart: item added": (r) => r.status === 201 });
sleep(1);
// Place order
const orderRes = http.post(`${BASE_URL}/api/v1/orders`, JSON.stringify({
shippingAddressId: 1,
}), { headers });
check(orderRes, { "order: created": (r) => r.status === 201 });
});
}
Stress test to find breaking point:
export const options = {
stages: [
{ duration: "2m", target: 100 },
{ duration: "5m", target: 100 },
{ duration: "2m", target: 200 },
{ duration: "5m", target: 200 },
{ duration: "2m", target: 300 },
{ duration: "5m", target: 300 },
{ duration: "2m", target: 400 },
{ duration: "5m", target: 400 },
{ duration: "5m", target: 0 },
],
thresholds: {
http_req_duration: ["p(95)<2000"],
http_req_failed: ["rate<0.10"], // Accept up to 10% errors during stress
},
};
artillery.yml configuration:
config:
target: "http://localhost:3000"
phases:
- duration: 120
arrivalRate: 5
name: "Warm up"
- duration: 300
arrivalRate: 20
name: "Sustained load"
- duration: 120
arrivalRate: 50
name: "Peak load"
defaults:
headers:
Content-Type: "application/json"
plugins:
expect: {}
scenarios:
- name: "Browse and Purchase"
weight: 70
flow:
- get:
url: "/api/v1/products"
expect:
- statusCode: 200
- think: 2
- get:
url: "/api/v1/products/{{ $randomNumber(1, 100) }}"
expect:
- statusCode: 200
capture:
- json: "$.id"
as: "productId"
- think: 1
- name: "Search"
weight: 30
flow:
- get:
url: "/api/v1/products?search={{ $randomString() }}"
expect:
- statusCode: 200
from locust import HttpUser, task, between, tag
class ShopUser(HttpUser):
wait_time = between(1, 5)
host = "http://localhost:3000"
def on_start(self):
"""Authenticate on virtual user start."""
response = self.client.post("/api/v1/auth/login", json={
"email": f"user{self.environment.runner.user_count}@test.com",
"password": "testpassword",
})
self.token = response.json()["token"]
self.headers = {"Authorization": f"Bearer {self.token}"}
@task(5)
@tag("browse")
def browse_products(self):
self.client.get("/api/v1/products", headers=self.headers)
@task(3)
@tag("browse")
def view_product(self):
product_id = random.randint(1, 100)
self.client.get(f"/api/v1/products/{product_id}", headers=self.headers)
@task(1)
@tag("checkout")
def place_order(self):
with self.client.post("/api/v1/orders", json={
"items": [{"productId": 1, "quantity": 1}],
}, headers=self.headers, catch_response=True) as response:
if response.status_code == 201:
response.success()
else:
response.failure(f"Order failed: {response.status_code}")
GitHub Actions with k6:
name: Load Test
on:
pull_request:
branches: [main]
jobs:
load-test:
runs-on: ubuntu-latest
services:
app:
image: myapp:latest
ports: ["3000:3000"]
steps:
- uses: actions/checkout@v4
- name: Install k6
run: |
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D68
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" \
| sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update && sudo apt-get install k6
- name: Run load test
run: k6 run --out json=results.json tests/load/smoke.js
env:
BASE_URL: http://localhost:3000
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: k6-results
path: results.json
sleep() between requests to simulate real user behavior. Without pauses, you test throughput, not load.ramping-vus tests user concurrency; constant-arrival-rate tests requests per second.| Pitfall | Problem | Fix |
|---|---|---|
| No think time | Unrealistic throughput, tests concurrency not load | Add sleep() between requests |
| Testing from same machine as app | Network and CPU contention skews results | Use separate load generator machines |
| No warmup phase | Cold caches and JIT compilation inflate p95 | Add a 2-minute ramp-up phase |
| Ignoring error responses | Reporting fast 500s as good performance | Add check() assertions on responses |
| Hardcoded test data | All VUs hit same record, unrealistic cache behavior | Randomize product IDs, user accounts |
| No baseline comparison | Cannot tell if performance regressed | Store baselines and compare in CI |
| Testing only happy path | Errors and edge cases not exercised | Include auth failures, 404s, validation errors |
| Running from distant regions | Network latency dominates response time | Run load generators close to the target |