本文目录导读:

- 使用 k6 + JavaScript
- 使用 Apache JMeter + 命令行
- 使用 Locust + Python
- 自定义 Shell 脚本自动化
- 集成 CI/CD (GitHub Actions)
- Python 自动化框架示例
- 最佳实践建议
使用 k6 + JavaScript
k6 是流行的开源性能测试工具,可以直接用脚本控制:
// performance-test.js
import http from 'k6/http';
import { sleep, check } from 'k6';
import { Rate, Trend } from 'k6/metrics';
// 自定义指标
const errorRate = new Rate('errors');
const responseTime = new Trend('response_time');
export const options = {
stages: [
{ duration: '2m', target: 100 }, // 逐渐增加用户
{ duration: '5m', target: 100 }, // 保持负载
{ duration: '2m', target: 0 }, // 逐渐减少
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95%请求响应时间<500ms
errors: ['rate<0.1'], // 错误率<10%
},
};
export default function () {
const res = http.get('https://api.example.com/users');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 200ms': (r) => r.timings.duration < 200,
});
errorRate.add(res.status !== 200);
responseTime.add(res.timings.duration);
sleep(1);
}
使用 Apache JMeter + 命令行
JMeter 支持无头模式自动执行:
# 执行测试计划 jmeter -n -t test-plan.jmx -l results.jtl -e -o report/ # 参数说明: # -n: 非GUI模式 # -t: 测试计划文件 # -l: 日志文件 # -e: 生成报告 # -o: 输出目录 # 带参数传递 jmeter -n -t test-plan.jmx \ -Jusers=100 \ -Jrampup=30 \ -Jduration=300 \ -l results.jtl
使用 Locust + Python
# locustfile.py
from locust import HttpUser, task, between
import random
class WebsiteUser(HttpUser):
wait_time = between(1, 3) # 用户等待时间
def on_start(self):
"""用户开始时的初始化"""
self.client.post("/login", {
"username": f"user_{random.randint(1,1000)}",
"password": "test123"
})
@task(3) # 权重为3
def view_homepage(self):
self.client.get("/")
@task(2)
def search_products(self):
self.client.get("/search?q=laptop")
@task(1)
def add_to_cart(self):
self.client.post("/cart", {
"product_id": random.randint(1,100)
})
# 命令行执行 locust -f locustfile.py \ --host=http://example.com \ --users=100 \ --spawn-rate=10 \ --run-time=10m \ --headless \ --html=report.html
自定义 Shell 脚本自动化
#!/bin/bash
# performance-test.sh
# 配置
API_URL="https://api.example.com"
CONCURRENT_USERS=50
DURATION=300
REPORT_DIR="reports/$(date +%Y%m%d_%H%M%S)"
mkdir -p $REPORT_DIR
echo "=== 开始性能测试 ==="
echo "API: $API_URL"
echo "并发用户: $CONCURRENT_USERS"
echo "持续时间: ${DURATION}s"
# 1. 基础响应时间测试
echo "执行基础响应时间测试..."
for i in {1..10}; do
start_time=$(date +%s%N)
curl -s -o /dev/null -w "%{http_code}" $API_URL/health
end_time=$(date +%s%N)
duration_ms=$((($end_time - $start_time) / 1000000))
echo "请求 $i: ${duration_ms}ms"
done
# 2. 并发测试 (使用ab工具)
echo "执行并发测试..."
ab -n 1000 -c $CONCURRENT_USERS \
-H "Content-Type: application/json" \
-p payload.json \
$API_URL/endpoint > $REPORT_DIR/ab_results.txt
# 3. 使用k6执行更复杂的测试
echo "执行k6测试..."
k6 run --vus $CONCURRENT_USERS \
--duration ${DURATION}s \
--out json=$REPORT_DIR/k6_results.json \
performance-test.js
# 4. 生成报告
echo "生成测试报告..."
python3 generate_report.py $REPORT_DIR
echo "=== 测试完成 ==="
echo "报告位置: $REPORT_DIR"
集成 CI/CD (GitHub Actions)
# .github/workflows/performance-test.yml
name: Performance Testing
on:
schedule:
- cron: '0 2 * * *' # 每天凌晨2点
push:
branches: [main]
workflow_dispatch: # 手动触发
jobs:
performance-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup k6
uses: grafana/setup-k6-action@v1
- name: Run performance tests
run: |
k6 run \
--vus 50 \
--duration 5m \
--out json=results.json \
tests/performance/script.js
- name: Upload results
uses: actions/upload-artifact@v2
with:
name: performance-results
path: results.json
- name: Check thresholds
run: |
if jq -e '.metrics.http_req_duration.values.p95 > 500' results.json > /dev/null; then
echo "❌ 性能阈值未通过!"
exit 1
else
echo "✅ 性能测试通过"
fi
Python 自动化框架示例
# performance_automation.py
import subprocess
import json
import time
from datetime import datetime
import smtplib
from email.mime.text import MIMEText
import os
class PerformanceTestAutomation:
def __init__(self, config):
self.config = config
self.results = {}
def run_k6_test(self, script_path, params):
"""执行k6测试"""
cmd = [
"k6", "run",
"--vus", str(params.get('vus', 50)),
"--duration", params.get('duration', '5m'),
"--out", f"json={self.config['output_dir']}/k6_results.json",
script_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode == 0
def run_locust_test(self, locustfile, params):
"""执行Locust测试"""
cmd = [
"locust",
"-f", locustfile,
"--host", self.config['target_url'],
"--users", str(params.get('users', 100)),
"--spawn-rate", str(params.get('spawn_rate', 10)),
"--run-time", params.get('run_time', '10m'),
"--headless",
"--html", f"{self.config['output_dir']}/locust_report.html"
]
result = subprocess.run(cmd, capture_output=True, text=True)
return result.returncode == 0
def generate_report(self):
"""生成综合报告"""
report = {
'timestamp': datetime.now().isoformat(),
'target': self.config['target_url'],
'tests': self.results,
'summary': self.analyze_results()
}
with open(f"{self.config['output_dir']}/report.json", 'w') as f:
json.dump(report, f, indent=2)
return report
def analyze_results(self):
"""分析测试结果"""
summary = {
'passed': True,
'avg_response_time': 0,
'error_rate': 0,
'throughput': 0
}
# 分析k6结果
if os.path.exists(f"{self.config['output_dir']}/k6_results.json"):
with open(f"{self.config['output_dir']}/k6_results.json") as f:
data = json.load(f)
summary['avg_response_time'] = data.get('metrics', {}).get('http_req_duration', {}).get('avg', 0)
summary['throughput'] = data.get('metrics', {}).get('http_reqs', {}).get('rate', 0)
return summary
def send_notification(self, report):
"""发送通知"""
if not self.config.get('email'):
return
msg = MIMEText(f"""
性能测试完成
时间: {report['timestamp']}
目标: {report['target']}
状态: {'通过' if report['summary']['passed'] else '失败'}
平均响应时间: {report['summary']['avg_response_time']}ms
吞吐量: {report['summary']['throughput']} req/s
""")
# 发送邮件逻辑
# ...
# 使用示例
if __name__ == "__main__":
config = {
'target_url': 'https://api.example.com',
'output_dir': './test_results',
'email': 'admin@example.com'
}
automation = PerformanceTestAutomation(config)
# 运行测试
automation.run_k6_test('tests/k6/script.js', {
'vus': 100,
'duration': '10m'
})
automation.run_locust_test('tests/locust/locustfile.py', {
'users': 200,
'spawn_rate': 20,
'run_time': '15m'
})
# 生成报告
report = automation.generate_report()
automation.send_notification(report)
最佳实践建议
-
环境准备
- 使用独立的测试环境
- 准备测试数据
- 监控系统资源
-
测试计划
- 定义明确的性能指标
- 设置合理的阈值
- 规划测试场景
-
持续集成
- 集成到CI/CD pipeline
- 自动化报告生成
- 阈值告警通知
-
数据管理
- 存储历史结果
- 趋势分析
- 性能回归检测
选择哪种方式取决于你的技术栈、团队经验和具体需求,k6 适合需要JavaScript脚本的团队,JMeter 适合传统企业,Locust 适合Python开发者。