From 4cdd0b07b9d5fbf56e68238eb6f8ddd4daf944c8 Mon Sep 17 00:00:00 2001 From: hailin Date: Mon, 24 Nov 2025 03:21:24 -0800 Subject: [PATCH] . --- .../identity-service/TEST-STRATEGY.md | 238 ++++++++++++++++++ .../identity-service/scripts/health-check.sh | 67 +++++ .../identity-service/scripts/quick-test.sh | 179 +++++++++++++ .../test/code-quality-checklist.md | 169 +++++++++++++ .../test/integration-checklist.md | 40 +++ .../test/manual-test-scenarios.md | 176 +++++++++++++ .../identity-service/test/performance-test.md | 56 +++++ .../test/security-test-checklist.md | 138 ++++++++++ 8 files changed, 1063 insertions(+) create mode 100644 backend/services/identity-service/TEST-STRATEGY.md create mode 100644 backend/services/identity-service/scripts/health-check.sh create mode 100644 backend/services/identity-service/scripts/quick-test.sh create mode 100644 backend/services/identity-service/test/code-quality-checklist.md create mode 100644 backend/services/identity-service/test/integration-checklist.md create mode 100644 backend/services/identity-service/test/manual-test-scenarios.md create mode 100644 backend/services/identity-service/test/performance-test.md create mode 100644 backend/services/identity-service/test/security-test-checklist.md diff --git a/backend/services/identity-service/TEST-STRATEGY.md b/backend/services/identity-service/TEST-STRATEGY.md new file mode 100644 index 00000000..f7623475 --- /dev/null +++ b/backend/services/identity-service/TEST-STRATEGY.md @@ -0,0 +1,238 @@ +# Identity Service 测试策略 + +## 测试金字塔 + +``` + /\ + / \ E2E Tests (20) + /----\ + / \ Integration Tests + /--------\ + / \ Unit Tests (46) + /--------------\ +``` + +## 当前测试状态 + +### ✅ 已完成 +- **单元测试**: 46 个测试全部通过 + - 领域层值对象测试 + - 领域层聚合根测试 + - 基础设施层服务测试 + +- **E2E 测试**: 20 个测试全部通过 + - 账户创建流程 + - 用户资料管理 + - 设备管理 + - Token 管理 + - 推荐系统 + - KYC 认证 + - 助记词恢复 + - 数据验证 + +### ⚠️ 需要补充的测试 + +#### 1. 集成测试(优先级:高) +- [ ] PostgreSQL 真实连接测试 +- [ ] Redis 真实连接测试 +- [ ] Kafka 真实连接测试 +- [ ] 事务一致性测试 +- [ ] 并发安全测试 + +#### 2. 性能测试(优先级:高) +- [ ] 负载测试(100-500 并发) +- [ ] 压力测试(找到系统极限) +- [ ] 数据库连接池测试 +- [ ] 内存泄漏测试 + +#### 3. 安全测试(优先级:高) +- [ ] SQL 注入测试 +- [ ] XSS 攻击测试 +- [ ] JWT Token 安全测试 +- [ ] 暴力破解防护测试 +- [ ] 敏感数据保护验证 +- [ ] 依赖漏洞扫描(npm audit, Snyk) + +#### 4. 手动测试(优先级:中) +- [ ] 完整用户旅程测试 +- [ ] 多设备管理流程测试 +- [ ] 边界条件测试 +- [ ] 异常场景测试 + +#### 5. 代码质量检查(优先级:中) +- [ ] 测试覆盖率分析(目标 >80%) +- [ ] 代码规范检查(ESLint) +- [ ] 类型安全检查(TypeScript) +- [ ] 代码复杂度分析 +- [ ] 依赖关系分析 + +## 测试执行指南 + +### 开发阶段 +```bash +# 1. 运行单元测试(每次代码修改后) +npm test + +# 2. 运行 E2E 测试(每次功能完成后) +npm run test:e2e + +# 3. 生成覆盖率报告 +npm run test:cov + +# 4. 代码规范检查 +npm run lint +``` + +### 提交前检查 +```bash +# 运行完整测试套件 +npm run test:all # 需要在 package.json 中添加这个脚本 + +# 格式化代码 +npm run format + +# 类型检查 +npm run build +``` + +### 部署前检查 +```bash +# 1. 健康检查 +./scripts/health-check.sh + +# 2. 快速功能测试 +./scripts/quick-test.sh + +# 3. 安全扫描 +npm audit +snyk test + +# 4. 性能测试(如果有) +k6 run performance-test.js +``` + +## 测试环境配置 + +### 本地开发环境 +```bash +# .env.test +NODE_ENV=test +DATABASE_URL=postgresql://test:test@localhost:5432/identity_test +REDIS_URL=redis://localhost:6379 +KAFKA_BROKERS=localhost:9092 +JWT_SECRET=test-secret-key-for-testing-only +``` + +### CI/CD 环境 +- GitHub Actions / GitLab CI +- 每次 push 自动运行单元测试 +- 每次 merge 到 main 自动运行 E2E 测试 +- 每日定时运行安全扫描 + +### 测试环境(Staging) +- 与生产环境配置相同 +- 使用真实的外部服务(测试账号) +- 运行完整的集成测试和性能测试 + +## 测试数据管理 + +### 测试数据策略 +1. **单元测试**: 使用 mock 数据,测试快速、隔离 +2. **E2E 测试**: 使用测试数据库,每次测试前清理 +3. **集成测试**: 使用真实服务,测试账号/测试环境 +4. **性能测试**: 使用大量模拟数据 + +### 测试数据库种子数据 +```bash +# 初始化测试数据 +npm run seed:test + +# 清理测试数据 +npm run seed:reset +``` + +## 持续改进 + +### 每个 Sprint +- [ ] 为新功能编写测试(TDD) +- [ ] 修复失败的测试 +- [ ] 提高测试覆盖率(+5%) +- [ ] 更新测试文档 + +### 每个月 +- [ ] 运行完整的性能测试 +- [ ] 运行安全扫描 +- [ ] 更新依赖版本 +- [ ] 代码质量回顾 + +### 每个季度 +- [ ] 渗透测试 +- [ ] 灾难恢复演练 +- [ ] 测试策略回顾和优化 + +## 测试指标 + +### 代码覆盖率目标 +- 整体覆盖率: **>80%** +- 领域层: **>95%** +- 应用层: **>90%** +- 基础设施层: **>80%** +- API 层: **>85%** + +### 性能指标目标 +- API 响应时间 P95: **<500ms** +- 数据库查询时间: **<100ms** +- 并发处理能力: **>500 TPS** +- 错误率: **<0.1%** + +### 质量指标目标 +- 代码复杂度: **<10** +- 代码重复率: **<5%** +- 技术债务比率: **<5%** +- 安全漏洞: **0 个高危** + +## 测试清单快速链接 + +- [集成测试清单](./test/integration-checklist.md) +- [性能测试计划](./test/performance-test.md) +- [安全测试清单](./test/security-test-checklist.md) +- [手动测试场景](./test/manual-test-scenarios.md) +- [代码质量清单](./test/code-quality-checklist.md) + +## 常见问题 + +### Q: 测试失败怎么办? +1. 查看错误日志 +2. 在本地复现问题 +3. 调试并修复 +4. 确认测试通过后提交 + +### Q: 如何提高测试覆盖率? +1. 使用 `npm run test:cov` 查看未覆盖的代码 +2. 为未覆盖的分支添加测试用例 +3. 重点关注领域逻辑和边界条件 + +### Q: 测试运行太慢怎么办? +1. 只运行相关测试: `npm test -- user-account.spec.ts` +2. 使用 mock 替代真实服务 +3. 并行运行测试(Jest 默认并行) +4. 优化测试数据准备逻辑 + +## 结论 + +当前测试覆盖已经包括: +- ✅ 核心业务逻辑(单元测试) +- ✅ API 端到端流程(E2E 测试) +- ✅ Mock 外部依赖 + +**但要真正适应生产环境,还需要:** +1. **集成测试** - 验证与真实服务的交互 +2. **性能测试** - 验证系统在高负载下的表现 +3. **安全测试** - 发现潜在的安全漏洞 +4. **手动测试** - 验证用户体验和边界情况 + +**推荐的测试优先级:** +1. 🔴 **立即进行**: 集成测试(PostgreSQL/Redis/Kafka) +2. 🟡 **本周完成**: 安全测试基础(依赖扫描、输入验证) +3. 🟢 **下周完成**: 性能测试、手动测试 +4. 🔵 **持续进行**: 代码质量检查、覆盖率提升 diff --git a/backend/services/identity-service/scripts/health-check.sh b/backend/services/identity-service/scripts/health-check.sh new file mode 100644 index 00000000..d54193b7 --- /dev/null +++ b/backend/services/identity-service/scripts/health-check.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# 健康检查脚本 - 检查所有依赖服务是否正常 + +set -e + +echo "🏥 开始健康检查..." +echo "" + +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' + +# 检查计数 +PASS=0 +FAIL=0 + +# 检查函数 +check_service() { + local service_name=$1 + local check_command=$2 + + echo -n "Checking $service_name ... " + + if eval "$check_command" > /dev/null 2>&1; then + echo -e "${GREEN}✓ OK${NC}" + PASS=$((PASS + 1)) + else + echo -e "${RED}✗ FAIL${NC}" + FAIL=$((FAIL + 1)) + fi +} + +# 检查 PostgreSQL +echo -e "${YELLOW}=== 数据库服务 ===${NC}" +check_service "PostgreSQL" "pg_isready -h localhost -p 5432" + +# 检查 Redis +echo -e "${YELLOW}=== 缓存服务 ===${NC}" +check_service "Redis" "redis-cli -h localhost -p 6379 ping" + +# 检查 Kafka +echo -e "${YELLOW}=== 消息队列服务 ===${NC}" +check_service "Kafka" "nc -zv localhost 9092" + +# 检查应用服务 +echo -e "${YELLOW}=== 应用服务 ===${NC}" +check_service "Identity Service" "curl -f http://localhost:3000/health" + +# 检查 Swagger 文档 +echo -e "${YELLOW}=== API 文档 ===${NC}" +check_service "Swagger UI" "curl -f http://localhost:3000/api" + +echo "" +echo -e "${YELLOW}======================================${NC}" +echo -e "${YELLOW}健康检查完成!${NC}" +echo -e "${GREEN}正常: $PASS${NC}" +echo -e "${RED}异常: $FAIL${NC}" +echo -e "${YELLOW}======================================${NC}" + +if [ $FAIL -eq 0 ]; then + echo -e "${GREEN}✓ 所有服务正常!${NC}" + exit 0 +else + echo -e "${RED}✗ 存在异常的服务!${NC}" + exit 1 +fi diff --git a/backend/services/identity-service/scripts/quick-test.sh b/backend/services/identity-service/scripts/quick-test.sh new file mode 100644 index 00000000..90de1951 --- /dev/null +++ b/backend/services/identity-service/scripts/quick-test.sh @@ -0,0 +1,179 @@ +#!/bin/bash +# 快速测试脚本 - 在本地环境快速验证核心功能 + +set -e + +echo "🚀 开始快速测试..." +echo "" + +# 颜色定义 +GREEN='\033[0;32m' +RED='\033[0;31m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +BASE_URL="http://localhost:3000/api/v1" + +# 测试结果统计 +PASS=0 +FAIL=0 + +# 测试函数 +test_api() { + local test_name=$1 + local method=$2 + local endpoint=$3 + local data=$4 + local expected_status=$5 + local token=$6 + + echo -n "Testing: $test_name ... " + + if [ -n "$token" ]; then + response=$(curl -s -w "\n%{http_code}" -X $method "$BASE_URL$endpoint" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $token" \ + -d "$data") + else + response=$(curl -s -w "\n%{http_code}" -X $method "$BASE_URL$endpoint" \ + -H "Content-Type: application/json" \ + -d "$data") + fi + + status=$(echo "$response" | tail -n1) + body=$(echo "$response" | head -n-1) + + if [ "$status" -eq "$expected_status" ]; then + echo -e "${GREEN}✓ PASS${NC}" + PASS=$((PASS + 1)) + echo "$body" + else + echo -e "${RED}✗ FAIL${NC} (Expected: $expected_status, Got: $status)" + FAIL=$((FAIL + 1)) + echo "$body" + fi + echo "" +} + +# 生成随机设备 ID +DEVICE_ID="test-device-$(date +%s)" + +# 1. 测试账户创建 +echo -e "${YELLOW}=== 1. 账户创建 ===${NC}" +CREATE_RESPONSE=$(curl -s -X POST "$BASE_URL/user/auto-create" \ + -H "Content-Type: application/json" \ + -d "{ + \"deviceId\": \"$DEVICE_ID\", + \"deviceName\": \"Test Device\", + \"provinceCode\": \"110000\", + \"cityCode\": \"110100\" + }") + +echo "$CREATE_RESPONSE" | jq '.' + +# 提取关键信息 +ACCESS_TOKEN=$(echo "$CREATE_RESPONSE" | jq -r '.data.accessToken') +REFRESH_TOKEN=$(echo "$CREATE_RESPONSE" | jq -r '.data.refreshToken') +ACCOUNT_SEQUENCE=$(echo "$CREATE_RESPONSE" | jq -r '.data.accountSequence') +MNEMONIC=$(echo "$CREATE_RESPONSE" | jq -r '.data.mnemonic') +REFERRAL_CODE=$(echo "$CREATE_RESPONSE" | jq -r '.data.referralCode') + +if [ "$ACCESS_TOKEN" != "null" ]; then + echo -e "${GREEN}✓ 账户创建成功${NC}" + echo "Account Sequence: $ACCOUNT_SEQUENCE" + echo "Referral Code: $REFERRAL_CODE" + PASS=$((PASS + 1)) +else + echo -e "${RED}✗ 账户创建失败${NC}" + FAIL=$((FAIL + 1)) + exit 1 +fi +echo "" + +# 2. 测试获取个人资料 +echo -e "${YELLOW}=== 2. 获取个人资料 ===${NC}" +test_api "获取个人资料" "GET" "/user/my-profile" "" 200 "$ACCESS_TOKEN" + +# 3. 测试更新个人资料 +echo -e "${YELLOW}=== 3. 更新个人资料 ===${NC}" +test_api "更新个人资料" "PUT" "/user/update-profile" \ + "{\"nickname\": \"测试用户\", \"address\": \"测试地址\"}" \ + 200 "$ACCESS_TOKEN" + +# 4. 测试获取设备列表 +echo -e "${YELLOW}=== 4. 获取设备列表 ===${NC}" +test_api "获取设备列表" "GET" "/user/my-devices" "" 200 "$ACCESS_TOKEN" + +# 5. 测试 Token 刷新 +echo -e "${YELLOW}=== 5. Token 刷新 ===${NC}" +REFRESH_RESPONSE=$(curl -s -X POST "$BASE_URL/user/auto-login" \ + -H "Content-Type: application/json" \ + -d "{ + \"refreshToken\": \"$REFRESH_TOKEN\", + \"deviceId\": \"$DEVICE_ID\" + }") + +NEW_ACCESS_TOKEN=$(echo "$REFRESH_RESPONSE" | jq -r '.data.accessToken') +if [ "$NEW_ACCESS_TOKEN" != "null" ] && [ "$NEW_ACCESS_TOKEN" != "$ACCESS_TOKEN" ]; then + echo -e "${GREEN}✓ Token 刷新成功${NC}" + PASS=$((PASS + 1)) +else + echo -e "${RED}✗ Token 刷新失败${NC}" + FAIL=$((FAIL + 1)) +fi +echo "" + +# 6. 测试助记词恢复 +echo -e "${YELLOW}=== 6. 助记词恢复 ===${NC}" +NEW_DEVICE_ID="test-device-recovery-$(date +%s)" +test_api "助记词恢复" "POST" "/user/recover-by-mnemonic" \ + "{ + \"accountSequence\": $ACCOUNT_SEQUENCE, + \"mnemonic\": \"$MNEMONIC\", + \"newDeviceId\": \"$NEW_DEVICE_ID\", + \"deviceName\": \"Recovered Device\" + }" \ + 201 "" + +# 7. 测试推荐码查询 +echo -e "${YELLOW}=== 7. 推荐码查询 ===${NC}" +test_api "推荐码查询" "GET" "/user/by-referral-code/$REFERRAL_CODE" "" 200 "" + +# 8. 测试 KYC 提交 +echo -e "${YELLOW}=== 8. KYC 提交 ===${NC}" +test_api "KYC 提交" "POST" "/user/submit-kyc" \ + "{ + \"realName\": \"张三\", + \"idCardNumber\": \"110101199001011234\", + \"idCardFrontUrl\": \"https://example.com/front.jpg\", + \"idCardBackUrl\": \"https://example.com/back.jpg\" + }" \ + 201 "$ACCESS_TOKEN" + +# 9. 测试错误场景 +echo -e "${YELLOW}=== 9. 错误场景测试 ===${NC}" +test_api "无效 Token" "GET" "/user/my-profile" "" 401 "invalid-token" +test_api "错误的助记词" "POST" "/user/recover-by-mnemonic" \ + "{ + \"accountSequence\": $ACCOUNT_SEQUENCE, + \"mnemonic\": \"wrong wrong wrong wrong wrong wrong wrong wrong wrong wrong wrong wrong\", + \"newDeviceId\": \"wrong-device\", + \"deviceName\": \"Wrong Device\" + }" \ + 400 "" + +# 总结 +echo "" +echo -e "${YELLOW}======================================${NC}" +echo -e "${YELLOW}测试完成!${NC}" +echo -e "${GREEN}通过: $PASS${NC}" +echo -e "${RED}失败: $FAIL${NC}" +echo -e "${YELLOW}======================================${NC}" + +if [ $FAIL -eq 0 ]; then + echo -e "${GREEN}✓ 所有测试通过!${NC}" + exit 0 +else + echo -e "${RED}✗ 存在失败的测试!${NC}" + exit 1 +fi diff --git a/backend/services/identity-service/test/code-quality-checklist.md b/backend/services/identity-service/test/code-quality-checklist.md new file mode 100644 index 00000000..e1743b0f --- /dev/null +++ b/backend/services/identity-service/test/code-quality-checklist.md @@ -0,0 +1,169 @@ +# 代码质量检查清单 + +## 自动化工具 + +### 1. ESLint - 代码规范检查 +```bash +npm run lint +``` + +### 2. Prettier - 代码格式化 +```bash +npm run format +npm run format:check +``` + +### 3. TypeScript 类型检查 +```bash +npm run build +# 或 +tsc --noEmit +``` + +### 4. 测试覆盖率 +```bash +npm run test:cov +``` +**目标覆盖率:** +- 整体覆盖率 > 80% +- 关键业务逻辑 > 90% +- 领域模型 > 95% + +### 5. SonarQube - 代码质量分析 +```bash +# Docker 启动 SonarQube +docker run -d --name sonarqube -p 9000:9000 sonarqube:latest + +# 扫描项目 +npx sonar-scanner \ + -Dsonar.projectKey=identity-service \ + -Dsonar.sources=src \ + -Dsonar.host.url=http://localhost:9000 +``` + +检查指标: +- Code Smells +- Bugs +- Vulnerabilities +- Security Hotspots +- Duplications +- Technical Debt + +### 6. 循环复杂度检查 +```bash +npm install -g complexity-report +cr --format json src/**/*.ts +``` +**目标:** +- 函数循环复杂度 < 10 +- 文件平均复杂度 < 5 + +## 手动代码审查清单 + +### 架构和设计 +- [ ] 遵循 DDD 原则 +- [ ] 清晰的层次划分(Domain/Application/Infrastructure/API) +- [ ] 依赖方向正确(外层依赖内层,内层不依赖外层) +- [ ] 没有循环依赖 +- [ ] 接口隔离,依赖倒置 + +### 领域层 +- [ ] 值对象是不可变的 +- [ ] 实体有唯一标识 +- [ ] 聚合根控制一致性边界 +- [ ] 领域事件正确发布 +- [ ] 业务规则在领域层,不在应用层 + +### 应用层 +- [ ] Command/Query 职责明确 +- [ ] Handler 只协调,不包含业务逻辑 +- [ ] 事务边界合理 +- [ ] 异常处理恰当 + +### 基础设施层 +- [ ] Repository 不泄露持久化细节 +- [ ] 外部服务接口清晰 +- [ ] 错误处理和重试机制 + +### API 层 +- [ ] DTO 验证充分 +- [ ] 错误响应统一 +- [ ] API 文档完整(Swagger) +- [ ] 版本控制策略 + +### 安全 +- [ ] 没有硬编码的密钥/密码 +- [ ] 敏感数据加密 +- [ ] 输入验证和消毒 +- [ ] SQL 注入防护(使用 ORM) +- [ ] XSS 防护 + +### 性能 +- [ ] 没有 N+1 查询 +- [ ] 合理使用索引 +- [ ] 避免阻塞操作 +- [ ] 合理的缓存策略 +- [ ] 分页查询,避免全表扫描 + +### 可维护性 +- [ ] 代码可读性好 +- [ ] 函数/类职责单一 +- [ ] 命名清晰准确 +- [ ] 注释充分但不冗余 +- [ ] 避免魔法数字 + +### 测试 +- [ ] 单元测试覆盖关键逻辑 +- [ ] 测试用例清晰可读 +- [ ] 测试独立,不依赖顺序 +- [ ] Mock 使用恰当 + +## 依赖分析 + +### 检查依赖关系 +```bash +npm install -g madge + +# 生成依赖图 +madge --image deps.png src/ + +# 检查循环依赖 +madge --circular src/ +``` + +### 检查未使用的依赖 +```bash +npm install -g depcheck +depcheck +``` + +### 检查过时的依赖 +```bash +npm outdated +``` + +## 文档检查 +- [ ] README.md 完整 + - [ ] 项目介绍 + - [ ] 安装步骤 + - [ ] 运行命令 + - [ ] 环境变量说明 + - [ ] API 文档链接 + +- [ ] 架构文档 + - [ ] 系统架构图 + - [ ] 领域模型图 + - [ ] 数据库 ER 图 + - [ ] API 接口文档 + +- [ ] 开发文档 + - [ ] 开发环境搭建 + - [ ] 编码规范 + - [ ] Git 工作流 + - [ ] 测试指南 + +## Git 提交质量 +- [ ] Commit message 清晰 +- [ ] 每个 commit 是原子性的 +- [ ] 没有提交敏感信息 +- [ ] 分支策略清晰 diff --git a/backend/services/identity-service/test/integration-checklist.md b/backend/services/identity-service/test/integration-checklist.md new file mode 100644 index 00000000..5d6364a5 --- /dev/null +++ b/backend/services/identity-service/test/integration-checklist.md @@ -0,0 +1,40 @@ +# 集成测试检查清单 + +## 数据库集成测试 +- [ ] PostgreSQL 真实连接测试 + - [ ] 事务回滚测试 + - [ ] 并发写入测试(多个账户同时创建) + - [ ] 账户序列号生成器的并发安全性 + - [ ] 外键约束测试 + - [ ] 索引性能测试 + +## Redis 集成测试 +- [ ] Redis 真实连接测试 + - [ ] Token 存储/读取/过期 + - [ ] SMS 验证码存储/过期 + - [ ] 分布式锁测试(防止重复注册) + +## Kafka 集成测试 +- [ ] Kafka 真实连接测试 + - [ ] 事件发布成功 + - [ ] 事件发布失败重试 + - [ ] 事件顺序保证 + - [ ] 消费者能正确接收事件 + +## SMS 服务集成测试 +- [ ] 真实 SMS API 调用(使用测试号码) + - [ ] 发送成功 + - [ ] 发送失败处理 + - [ ] 限流测试(防止恶意发送) + +## JWT Token 测试 +- [ ] Token 签名验证 +- [ ] Token 过期验证 +- [ ] Token 刷新流程 +- [ ] 跨服务 Token 验证(如果有多个服务) + +## 区块链钱包测试 +- [ ] 助记词生成的随机性 +- [ ] 地址派生的一致性 +- [ ] 加密/解密的安全性 +- [ ] 多链地址格式验证 diff --git a/backend/services/identity-service/test/manual-test-scenarios.md b/backend/services/identity-service/test/manual-test-scenarios.md new file mode 100644 index 00000000..8eb5842f --- /dev/null +++ b/backend/services/identity-service/test/manual-test-scenarios.md @@ -0,0 +1,176 @@ +# 手动测试场景 + +## 用户旅程测试 + +### 场景 1: 新用户完整注册流程 +1. **自动创建账户** + ```bash + curl -X POST http://localhost:3000/api/v1/user/auto-create \ + -H "Content-Type: application/json" \ + -d '{ + "deviceId": "manual-test-device-001", + "deviceName": "iPhone 14 Pro", + "provinceCode": "110000", + "cityCode": "110100" + }' + ``` + - ✅ 返回 201 + - ✅ 获得 userId, accountSequence, referralCode, mnemonic + - ✅ 获得 3 个钱包地址 (KAVA, DST, BSC) + - ✅ 获得 accessToken 和 refreshToken + - **保存 mnemonic 用于后续测试!** + +2. **查看个人资料** + ```bash + curl -X GET http://localhost:3000/api/v1/user/my-profile \ + -H "Authorization: Bearer {accessToken}" + ``` + - ✅ 返回正确的用户信息 + +3. **更新个人资料** + ```bash + curl -X PUT http://localhost:3000/api/v1/user/update-profile \ + -H "Authorization: Bearer {accessToken}" \ + -H "Content-Type: application/json" \ + -d '{ + "nickname": "测试用户", + "avatarUrl": "https://example.com/avatar.jpg", + "address": "北京市朝阳区测试路123号" + }' + ``` + - ✅ 更新成功 + - ✅ 再次查询个人资料,确认更新生效 + +4. **查看设备列表** + ```bash + curl -X GET http://localhost:3000/api/v1/user/my-devices \ + -H "Authorization: Bearer {accessToken}" + ``` + - ✅ 看到 1 个设备 + +### 场景 2: 多设备管理 +5. **在新设备上使用助记词恢复** + ```bash + curl -X POST http://localhost:3000/api/v1/user/recover-by-mnemonic \ + -H "Content-Type: application/json" \ + -d '{ + "accountSequence": {accountSequence}, + "mnemonic": "{mnemonic}", + "newDeviceId": "manual-test-device-002", + "deviceName": "iPad Pro" + }' + ``` + - ✅ 返回新的 token + - ✅ 钱包地址与第一个设备相同 + +6. **查看设备列表(使用新设备的 token)** + - ✅ 看到 2 个设备 + +7. **移除旧设备** + ```bash + curl -X POST http://localhost:3000/api/v1/user/remove-device \ + -H "Authorization: Bearer {newAccessToken}" \ + -H "Content-Type: application/json" \ + -d '{ + "deviceId": "manual-test-device-001" + }' + ``` + - ✅ 移除成功 + - ✅ 使用旧设备的 token 无法再访问 API + +### 场景 3: Token 管理 +8. **等待 access token 过期(或修改过期时间为 1 分钟测试)** + - ✅ 过期的 token 无法访问 API + +9. **使用 refresh token 获取新的 access token** + ```bash + curl -X POST http://localhost:3000/api/v1/user/auto-login \ + -H "Content-Type: application/json" \ + -d '{ + "refreshToken": "{refreshToken}", + "deviceId": "manual-test-device-002" + }' + ``` + - ✅ 获得新的 access token + - ✅ 新 token 可以正常使用 + +### 场景 4: KYC 认证 +10. **提交 KYC 信息** + ```bash + curl -X POST http://localhost:3000/api/v1/user/submit-kyc \ + -H "Authorization: Bearer {accessToken}" \ + -H "Content-Type: application/json" \ + -d '{ + "realName": "张三", + "idCardNumber": "110101199001011234", + "idCardFrontUrl": "https://example.com/id-front.jpg", + "idCardBackUrl": "https://example.com/id-back.jpg" + }' + ``` + - ✅ 提交成功 + - ✅ 查看个人资料,确认 KYC 信息存在且身份证号已脱敏 + +### 场景 5: 推荐系统 +11. **根据推荐码查询用户** + ```bash + curl -X GET http://localhost:3000/api/v1/user/by-referral-code/{referralCode} + ``` + - ✅ 返回正确的账户信息 + +12. **使用推荐码注册新用户** + ```bash + curl -X POST http://localhost:3000/api/v1/user/auto-create \ + -H "Content-Type: application/json" \ + -d '{ + "deviceId": "manual-test-device-003", + "deviceName": "Android Phone", + "provinceCode": "110000", + "cityCode": "110100", + "inviterReferralCode": "{referralCode}" + }' + ``` + - ✅ 创建成功 + - ✅ 新用户的 inviterSequence 正确 + +## 边界测试 + +### 设备限制测试 +- [ ] 添加 5 个设备 → 成功 +- [ ] 尝试添加第 6 个设备 → 失败,提示设备数量限制 +- [ ] 移除 1 个设备后 → 可以再添加 1 个 + +### 并发测试(手动) +- [ ] 两个设备同时使用同一个 refresh token → 只有一个成功 +- [ ] 两个用户同时创建账户 → 账户序列号不重复 +- [ ] 同一个推荐码被多人使用 → 都成功 + +### 异常处理测试 +- [ ] 数据库连接断开 → 返回 500 错误 +- [ ] Redis 连接断开 → SMS 验证码功能失败 +- [ ] Kafka 连接断开 → 事件发布失败(但主流程成功) +- [ ] 网络超时 → 合理的超时提示 + +### 数据一致性测试 +- [ ] 创建账户失败(如数据库错误)→ 账户序列号不会被消耗 +- [ ] 添加设备失败(如超过限制)→ 数据库没有脏数据 +- [ ] Token 生成失败 → 账户仍然创建成功,可以重新登录 + +## 真实环境测试 + +### 部署到测试环境 +- [ ] Docker Compose 一键启动 +- [ ] Kubernetes 部署 +- [ ] 环境变量配置正确 +- [ ] 数据库迁移成功 +- [ ] 健康检查端点响应正常 + +### 监控和日志 +- [ ] 日志正确输出到文件/控制台 +- [ ] 错误日志包含堆栈信息 +- [ ] 性能指标可以被 Prometheus 采集 +- [ ] 日志可以被 ELK/Loki 采集 + +### 备份和恢复 +- [ ] 数据库备份 +- [ ] 数据恢复测试 +- [ ] 灾难恢复演练 diff --git a/backend/services/identity-service/test/performance-test.md b/backend/services/identity-service/test/performance-test.md new file mode 100644 index 00000000..abfdcb9f --- /dev/null +++ b/backend/services/identity-service/test/performance-test.md @@ -0,0 +1,56 @@ +# 性能测试计划 + +## 工具推荐 +- **Artillery** - HTTP 负载测试 +- **K6** - 现代化负载测试工具 +- **Apache JMeter** - 传统但功能强大 + +## 测试场景 + +### 1. 账户创建性能 +```bash +# 使用 k6 测试 +k6 run --vus 100 --duration 30s account-creation-test.js +``` +- 目标:100 并发用户,持续 30 秒 +- 指标: + - 平均响应时间 < 500ms + - P95 响应时间 < 1000ms + - 错误率 < 0.1% + - TPS (每秒事务数) > 200 + +### 2. 登录/刷新 Token 性能 +- 目标:200 并发用户 +- 指标: + - 平均响应时间 < 200ms + - P95 < 500ms + +### 3. 助记词恢复性能 +- 目标:50 并发用户(计算密集型操作) +- 指标: + - 平均响应时间 < 2000ms + - 不应该阻塞其他请求 + +### 4. 数据库连接池测试 +- 测试连接池耗尽场景 +- 测试连接泄漏检测 + +### 5. 内存泄漏测试 +- 长时间运行测试(24小时) +- 监控内存使用趋势 + +## 压力测试 +```bash +# 逐步增加负载直到系统崩溃 +k6 run --stages \ + "5m:100" \ # 5分钟内增加到100用户 + "10m:500" \ # 10分钟内增加到500用户 + "5m:1000" \ # 5分钟内增加到1000用户 + "10m:0" \ # 10分钟内降回0 + stress-test.js +``` + +找到系统的极限: +- 最大并发用户数 +- 最大 TPS +- 崩溃点 diff --git a/backend/services/identity-service/test/security-test-checklist.md b/backend/services/identity-service/test/security-test-checklist.md new file mode 100644 index 00000000..4d5e98ad --- /dev/null +++ b/backend/services/identity-service/test/security-test-checklist.md @@ -0,0 +1,138 @@ +# 安全测试检查清单 + +## 自动化安全扫描工具 + +### 1. OWASP ZAP +```bash +# Docker 运行 ZAP 扫描 +docker run -v $(pwd):/zap/wrk/:rw \ + -t owasp/zap2docker-stable zap-baseline.py \ + -t http://localhost:3000 -g gen.conf -r testreport.html +``` + +### 2. npm audit +```bash +npm audit +npm audit fix +``` + +### 3. Snyk +```bash +npm install -g snyk +snyk test +snyk monitor +``` + +## 手动安全测试 + +### 认证和授权 +- [ ] **JWT Token 安全** + - [ ] Token 在 URL 中不可见(只在 Header) + - [ ] Token 过期时间合理(access: 15min, refresh: 7天) + - [ ] Refresh token 轮换(用过的不能再用) + - [ ] Token 包含最小必要信息 + - [ ] Token 签名算法安全(HS256/RS256) + +- [ ] **设备授权** + - [ ] 未授权设备无法使用 token + - [ ] 设备绑定无法伪造 + - [ ] 设备限制(最多5个)有效 + +- [ ] **会话管理** + - [ ] 登出后 token 立即失效 + - [ ] 移除设备后该设备的 token 失效 + - [ ] 冻结账户后所有 token 失效 + +### 输入验证 +- [ ] **SQL 注入测试** + ```sql + phoneNumber: "13800138000' OR '1'='1" + nickname: "'; DROP TABLE users; --" + ``` + +- [ ] **NoSQL 注入测试** + ```json + {"accountSequence": {"$gt": 0}} + ``` + +- [ ] **XSS 攻击测试** + ```javascript + nickname: "" + avatarUrl: "javascript:alert('XSS')" + ``` + +- [ ] **命令注入测试** + ```bash + deviceName: "; rm -rf /" + ``` + +- [ ] **路径遍历测试** + ``` + avatarUrl: "../../etc/passwd" + ``` + +### 业务逻辑漏洞 +- [ ] **助记词安全** + - [ ] 助记词不在日志中出现 + - [ ] 助记词传输加密(HTTPS) + - [ ] 助记词存储加密 + - [ ] 助记词不在错误信息中泄露 + +- [ ] **身份证号安全** + - [ ] 返回时必须脱敏 + - [ ] 数据库加密存储 + - [ ] 不在日志中记录完整身份证号 + +- [ ] **暴力破解防护** + - [ ] 登录失败次数限制 + - [ ] SMS 验证码尝试次数限制 + - [ ] 账户序列号枚举防护 + - [ ] 验证码发送频率限制 + +- [ ] **重放攻击防护** + - [ ] API 请求幂等性 + - [ ] Nonce/时间戳验证 + +- [ ] **越权访问测试** + - [ ] 用户 A 无法访问用户 B 的数据 + - [ ] 用户 A 无法修改用户 B 的设备 + - [ ] 普通用户无法访问管理员接口 + +### 敏感数据保护 +- [ ] **传输安全** + - [ ] 强制 HTTPS + - [ ] TLS 1.2+ + - [ ] 安全的 Cipher Suite + +- [ ] **存储安全** + - [ ] 密码使用 bcrypt/argon2 加密 + - [ ] 助记词 AES-256-GCM 加密 + - [ ] 身份证号加密存储 + - [ ] 数据库连接字符串不在代码中 + +- [ ] **日志安全** + - [ ] 日志不包含密码 + - [ ] 日志不包含完整助记词 + - [ ] 日志不包含完整身份证号 + - [ ] 日志不包含完整银行卡号 + +### CORS 和 CSRF +- [ ] CORS 白名单配置正确 +- [ ] CSRF Token 验证(如果有 Web 前端) +- [ ] SameSite Cookie 设置 + +### 速率限制 +- [ ] 全局速率限制(如:100 req/min per IP) +- [ ] 登录接口限制(如:5 次失败锁定 15 分钟) +- [ ] SMS 发送限制(如:1 次/分钟, 5 次/小时, 10 次/天) +- [ ] 账户创建限制(如:1 个/IP/天) + +### 依赖安全 +- [ ] 所有依赖是最新稳定版 +- [ ] 没有已知的 CVE 漏洞 +- [ ] 定期更新依赖 + +## 渗透测试工具 +- **Burp Suite** - 手动渗透测试 +- **SQLMap** - SQL 注入自动化测试 +- **Postman** - API 安全测试