Token导航 LogoToken导航

Agent Skill · 开发

load-test-builder(负载测试构建器)

用于辅助测试设计、自动化测试、用例整理和回归验证。它适合让 Agent 编写单元测试、端到端测试、测试计划或根据失败日志定位问题。使用时需要确认项目测试框架、运行命令和夹具数据,避免为了通过测试而改坏真实逻辑;涉及浏览器或外部服务时,应区分本地模拟、测试环境和生产环境。

load-test-builder 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描有提醒项,按安装量在开发类的 21,746 个 Skill 里排第 9,138。

总安装 2,840周安装 116GitHub Stars 32下载 919核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:load-test-builder(负载测试构建器)
来源仓库:https://github.com/patricio0312rev/skills
仓库路径:skills/load-test-builder
安装命令:
npx skills add https://github.com/patricio0312rev/skills --skill load-test-builder
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/patricio0312rev/skills --skill load-test-builder

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

用于辅助测试设计、自动化测试、用例整理和回归验证。适用于开发类任务,可编写单元测试或端到端测试用例。通过 npx skills add 命令从指定 GitHub 仓库安装,需确认权限范围和安装路径。使用时需确认项目测试框架和运行命令,避免为了通过测试而修改真实逻辑。

load-test-builder 属于开发类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/load-test-builder

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/patricio0312rev/skills --skill load-test-build…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

load-test-builder 怎么安装?

在终端执行 npx skills add https://github.com/patricio0312rev/skills --skill load-test-builder。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

load-test-builder 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

load-test-builder 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

load-test-builder 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

load-test-builder 用的人多吗?

公开数据是累计安装 2,840 次,近一周安装 116 次,下载 919 次,GitHub 32 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

load-test-builder 安全吗?

第三方扫描有提醒项,说明存在需要人工确认的行为。安装前请打开源码看清它读了什么、联网到哪里。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。

先想清楚的地方

  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
load-test-builder

负载测试构建器 · 本页

2,84032需要联网MIT有提醒

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Load Test Builder

Validate system performance under realistic and stress conditions.

Core Workflow

  1. Define scenarios: User journeys and load patterns
  2. Set thresholds: Performance requirements
  3. Configure load: Ramp-up, peak, duration
  4. Run tests: Execute load scenarios
  5. Analyze results: Metrics and bottlenecks
  6. Integrate CI: Automated performance gates

k6 Load Testing

Installation

# macOS
brew install k6

# Docker
docker pull grafana/k6

Basic Load Test

// load-tests/basic.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';

// Custom metrics
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');

// Test configuration
export const options = {
  stages: [
    { duration: '1m', target: 20 },   // Ramp up to 20 users
    { duration: '3m', target: 20 },   // Stay at 20 users
    { duration: '1m', target: 50 },   // Ramp up to 50 users
    { duration: '3m', target: 50 },   // Stay at 50 users
    { duration: '1m', target: 0 },    // Ramp down to 0
  ],
  thresholds: {
    http_req_duration: ['p(95)<500', 'p(99)<1000'],
    http_req_failed: ['rate<0.01'],
    errors: ['rate<0.05'],
  },
};

const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';

export default function () {
  // Homepage
  const homeResponse = http.get(`${BASE_URL}/`);

  check(homeResponse, {
    'homepage status is 200': (r) => r.status === 200,
    'homepage loads fast': (r) => r.timings.duration < 500,
  });

  responseTime.add(homeResponse.timings.duration);
  errorRate.add(homeResponse.status !== 200);

  sleep(1);

  // API request
  const apiResponse = http.get(`${BASE_URL}/api/users`);

  check(apiResponse, {
    'api status is 200': (r) => r.status === 200,
    'api returns array': (r) => Array.isArray(JSON.parse(r.body)),
  });

  errorRate.add(apiResponse.status !== 200);

  sleep(Math.random() * 3 + 1); // Random think time 1-4 seconds
}

User Journey Test

// load-tests/user-journey.js
import http from 'k6/http';
import { check, group, sleep } from 'k6';
import { SharedArray } from 'k6/data';

const users = new SharedArray('users', function () {
  return JSON.parse(open('./data/users.json'));
});

export const options = {
  scenarios: {
    browse_and_buy: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 100 },
        { duration: '5m', target: 100 },
        { duration: '2m', target: 0 },
      ],
      gracefulRampDown: '30s',
    },
  },
  thresholds: {
    'group_duration{group:::Login}': ['p(95)<2000'],
    'group_duration{group:::Browse Products}': ['p(95)<1000'],
    'group_duration{group:::Checkout}': ['p(95)<3000'],
    http_req_failed: ['rate<0.01'],
  },
};

const BASE_URL = __ENV.BASE_URL || 'http://localhost:3000';

export default function () {
  const user = users[Math.floor(Math.random() * users.length)];

  group('Login', function () {
    const loginRes = http.post(
      `${BASE_URL}/api/auth/login`,
      JSON.stringify({
        email: user.email,
        password: user.password,
      }),
      {
        headers: { 'Content-Type': 'application/json' },
      }
    );

    check(loginRes, {
      'login successful': (r) => r.status === 200,
      'has token': (r) => JSON.parse(r.body).token !== undefined,
    });

    if (loginRes.status !== 200) return;

    const token = JSON.parse(loginRes.body).token;

    group('Browse Products', function () {
      const productsRes = http.get(`${BASE_URL}/api/products`, {
        headers: { Authorization: `Bearer ${token}` },
      });

      check(productsRes, {
        'products loaded': (r) => r.status === 200,
      });

      sleep(2);

      // View product detail
      const products = JSON.parse(productsRes.body);
      if (products.length > 0) {
        const productId = products[Math.floor(Math.random() * products.length)].id;
        const productRes = http.get(`${BASE_URL}/api/products/${productId}`, {
          headers: { Authorization: `Bearer ${token}` },
        });

        check(productRes, {
          'product detail loaded': (r) => r.status === 200,
        });
      }
    });

    sleep(1);

    group('Checkout', function () {
      // Add to cart
      const cartRes = http.post(
        `${BASE_URL}/api/cart`,
        JSON.stringify({ productId: '1', quantity: 1 }),
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${token}`,
          },
        }
      );

      check(cartRes, {
        'added to cart': (r) => r.status === 200 || r.status === 201,
      });

      // Checkout
      const checkoutRes = http.post(
        `${BASE_URL}/api/checkout`,
        JSON.stringify({ paymentMethod: 'card' }),
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${token}`,
          },
        }
      );

      check(checkoutRes, {
        'checkout successful': (r) => r.status === 200 || r.status === 201,
      });
    });
  });

  sleep(Math.random() * 5 + 2);
}

Stress Test

// load-tests/stress.js
import http from 'k6/http';
import { check } from 'k6';

export const options = {
  stages: [
    { duration: '2m', target: 100 },    // Normal load
    { duration: '5m', target: 100 },
    { duration: '2m', target: 200 },    // High load
    { duration: '5m', target: 200 },
    { duration: '2m', target: 300 },    // Stress
    { duration: '5m', target: 300 },
    { duration: '2m', target: 400 },    // Breaking point
    { duration: '5m', target: 400 },
    { duration: '10m', target: 0 },     // Recovery
  ],
  thresholds: {
    http_req_duration: ['p(99)<1500'],
    http_req_failed: ['rate<0.05'],
  },
};

export default function () {
  const response = http.get(`${__ENV.BASE_URL}/api/health`);

  check(response, {
    'status is 200': (r) => r.status === 200,
  });
}

Spike Test

// load-tests/spike.js
export const options = {
  stages: [
    { duration: '10s', target: 100 },   // Quick ramp
    { duration: '1m', target: 100 },    // Normal
    { duration: '10s', target: 1000 },  // Spike!
    { duration: '3m', target: 1000 },   // Stay at spike
    { duration: '10s', target: 100 },   // Scale down
    { duration: '3m', target: 100 },    // Recovery
    { duration: '10s', target: 0 },     // Ramp down
  ],
};

Soak Test

// load-tests/soak.js
export const options = {
  stages: [
    { duration: '5m', target: 100 },    // Ramp up
    { duration: '8h', target: 100 },    // Sustained load for 8 hours
    { duration: '5m', target: 0 },      // Ramp down
  ],
  thresholds: {
    http_req_duration: ['p(95)<500'],
    http_req_failed: ['rate<0.01'],
  },
};

Artillery

Installation

npm install -D artillery

Configuration

# artillery/load-test.yml
config:
  target: "http://localhost:3000"
  phases:
    - duration: 60
      arrivalRate: 5
      name: "Warm up"
    - duration: 120
      arrivalRate: 10
      name: "Normal load"
    - duration: 60
      arrivalRate: 50
      name: "Spike"
    - duration: 60
      arrivalRate: 10
      name: "Cool down"

  defaults:
    headers:
      Content-Type: "application/json"

  plugins:
    expect: {}

  ensure:
    p99: 500
    maxErrorRate: 1

scenarios:
  - name: "User Journey"
    flow:
      - get:
          url: "/"
          expect:
            - statusCode: 200
            - contentType: text/html

      - think: 2

      - get:
          url: "/api/products"
          expect:
            - statusCode: 200
          capture:
            - json: "$[0].id"
              as: "productId"

      - think: 1

      - get:
          url: "/api/products/{{ productId }}"
          expect:
            - statusCode: 200

      - post:
          url: "/api/cart"
          json:
            productId: "{{ productId }}"
            quantity: 1
          expect:
            - statusCode: 201

With Custom Functions

// artillery/processor.js
module.exports = {
  generateUser,
  logResponse,
  validateCheckout,
};

function generateUser(context, events, done) {
  context.vars.email = `user${Date.now()}@example.com`;
  context.vars.password = 'testpassword123';
  return done();
}

function logResponse(requestParams, response, context, events, done) {
  console.log(`Response: ${response.statusCode} - ${response.body}`);
  return done();
}

function validateCheckout(requestParams, response, context, events, done) {
  const body = JSON.parse(response.body);
  if (!body.orderId) {
    return done(new Error('Missing orderId in response'));
  }
  context.vars.orderId = body.orderId;
  return done();
}
# artillery/with-processor.yml
config:
  target: "http://localhost:3000"
  processor: "./processor.js"
  phases:
    - duration: 60
      arrivalRate: 10

scenarios:
  - name: "Checkout flow"
    flow:
      - function: "generateUser"
      - post:
          url: "/api/auth/register"
          json:
            email: "{{ email }}"
            password: "{{ password }}"
      - post:
          url: "/api/checkout"
          afterResponse: "validateCheckout"

Autocannon (Node.js)

// load-tests/autocannon.ts
import autocannon from 'autocannon';

async function runLoadTest() {
  const result = await autocannon({
    url: 'http://localhost:3000/api/users',
    connections: 100,
    duration: 30,
    pipelining: 10,
    headers: {
      'Content-Type': 'application/json',
    },
    requests: [
      {
        method: 'GET',
        path: '/api/users',
      },
      {
        method: 'POST',
        path: '/api/users',
        body: JSON.stringify({ name: 'Test', email: 'test@example.com' }),
      },
    ],
  });

  console.log(autocannon.printResult(result));

  // Validate results
  if (result.latency.p99 > 500) {
    console.error('P99 latency exceeded 500ms');
    process.exit(1);
  }

  if (result.errors > 0) {
    console.error(`Errors detected: ${result.errors}`);
    process.exit(1);
  }
}

runLoadTest();

CI Integration

# .github/workflows/load-tests.yml
name: Load Tests

on:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM
  workflow_dispatch:

jobs:
  load-test:
    runs-on: ubuntu-latest

    services:
      app:
        image: myapp:latest
        ports:
          - 3000:3000
        env:
          DATABASE_URL: postgresql://test@localhost/test

    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 C5AD17C747E3415A3642D57D77C6C491D6AC1D69
          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: Wait for app
        run: |
          timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 1; done'

      - name: Run load tests
        run: k6 run --out json=results.json load-tests/basic.js
        env:
          BASE_URL: http://localhost:3000

      - name: Upload results
        uses: actions/upload-artifact@v4
        with:
          name: load-test-results
          path: results.json

      - name: Comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const results = JSON.parse(fs.readFileSync('results.json', 'utf8'));
            // Parse and format results for PR comment

Results Analysis

// scripts/analyze-results.js
import fs from 'fs';

const results = JSON.parse(fs.readFileSync('results.json', 'utf8'));

const summary = {
  totalRequests: results.metrics.http_reqs.count,
  avgDuration: results.metrics.http_req_duration.avg,
  p95Duration: results.metrics.http_req_duration['p(95)'],
  p99Duration: results.metrics.http_req_duration['p(99)'],
  errorRate: results.metrics.http_req_failed.rate,
  throughput: results.metrics.http_reqs.rate,
};

console.table(summary);

// Check thresholds
const passed =
  summary.p95Duration < 500 &&
  summary.p99Duration < 1000 &&
  summary.errorRate < 0.01;

process.exit(passed ? 0 : 1);

Best Practices

  1. Start small: Gradually increase load
  2. Use realistic data: Production-like scenarios
  3. Monitor everything: Backend metrics too
  4. Set thresholds: Define pass/fail criteria
  5. Test regularly: Catch regressions early
  6. Isolate environment: Dedicated test environment
  7. Document findings: Track improvements
  8. Include think time: Simulate real users

Output Checklist

Every load test setup should include:

  • k6/Artillery configuration
  • Realistic user scenarios
  • Multiple load patterns (normal, stress, spike)
  • Performance thresholds
  • Custom metrics
  • CI integration
  • Results analysis
  • Soak test for memory leaks
  • Documentation
  • Baseline benchmarks

平台分布

Claude Code

30.93%
按下载量换算284

Gemini CLI

22.4%
按下载量换算206

Antigravity

20%
按下载量换算184

windsurf

13.23%
按下载量换算122

github-copilot

7.87%
按下载量换算72

Codex

3.24%
按下载量换算30

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。

继续浏览同类 Skills