本手冊提供 Dapp Studio 三層架構 DApp 的完整測試指南,包含自動化測試和手動測試流程。
- L1 (智能合約層): ERC-20 + RBAC 合約
- L2 (API 層): Express.js + Web3 認證
- L3 (前端層): React + Drizzle + MetaMask
- Node.js v22+
- MetaMask 瀏覽器擴展
- Git
- Ganache: localhost:8545
- API Server: localhost:3001
- Frontend: localhost:5173
# 使用確定性模式啟動
ganache --deterministic --port 8545# 編譯合約
npm run build:contracts
# 部署合約 (使用直接部署腳本)
node scripts/deploy.jscd backend && npm startcd frontend && npm run dev# 檢查所有服務
curl http://localhost:8545 # Ganache
curl http://localhost:3001/health # API
curl http://localhost:5173 # Frontend# 安裝依賴
npm install
# 執行所有 E2E 測試
npm run test:e2e- 認證測試 (11 scenarios):
e2e/tests/auth.spec.ts - 整合測試 (12 scenarios):
e2e/tests/integration.spec.ts - RBAC 測試 (9 scenarios):
e2e/tests/rbac.spec.ts
# 只執行認證測試
npx playwright test auth.spec.ts
# 只執行 RBAC 測試
npx playwright test rbac.spec.ts
# 執行特定測試案例
npx playwright test --grep "Basic wallet connection"cd frontend && npm testcd backend && npm testcd contracts && npm test- 網路名稱:
Ganache Local - RPC URL:
http://127.0.0.1:8545 - 鏈 ID:
1337 - 貨幣符號:
ETH
使用 Ganache 提供的私鑰導入帳戶:
# 查看可用帳戶
node scripts/derive-keys.js- 開啟 http://localhost:5173
- 點擊 "Login with Ethereum"
- MetaMask 彈出連接請求
- 確認連接
- 驗證帳戶地址顯示
- 連接錢包後點擊 "Sign Message"
- MetaMask 彈出簽名請求
- 確認簽名
- 驗證 JWT Token 獲取
- 檢查認證狀態更新
- 在 MetaMask 中切換帳戶
- 驗證前端自動檢測變更
- 確認認證狀態重置
- 重新執行認證流程
# 檢查預設管理員
node scripts/verify-deployment.js- 使用管理員帳戶登入
- 嘗試執行管理員功能
- 切換到普通用戶帳戶
- 驗證權限限制
- 管理員授予角色給其他帳戶
- 驗證新角色權限生效
- 撤銷角色
- 確認權限移除
- 連接錢包
- 查看 Token 餘額顯示
- 驗證總供應量顯示
- 輸入接收地址和數量
- 執行轉帳交易
- 確認 MetaMask 交易
- 驗證餘額更新
- 執行任何交易
- 觀察 "Pending" 狀態
- 等待區塊確認
- 驗證 "Confirmed" 狀態
症狀: 前端顯示 "Error Tokens" 而非實際餘額 原因: 服務未正確啟動 解決方案:
# 檢查服務狀態
curl http://localhost:8545
curl http://localhost:3001/health
# 重新啟動服務
ganache --deterministic --port 8545症狀: MetaMask 無法連接或顯示錯誤網路 解決方案:
- 確認 MetaMask 網路設定 (RPC: http://127.0.0.1:8545)
- 重置 MetaMask 帳戶 (Settings > Advanced > Reset Account)
- 清除瀏覽器快取
症狀: 部署腳本報錯或合約地址無效 解決方案:
# 清理並重新部署
rm -rf contracts/build/
npm run build:contracts
node scripts/deploy.js症狀: Playwright 測試在 30s 後超時 解決方案:
- 確認所有服務正在運行
- 檢查 MetaMask 模擬設定
- 增加測試超時時間
# Ganache 會顯示所有交易和區塊資訊
# 檢查是否有交易失敗或 revertcd backend && npm start
# 檢查認證錯誤和 API 請求日誌- 開啟開發者工具 (F12)
- 檢查 Console 標籤的錯誤訊息
- 查看 Network 標籤的 API 請求狀態
- 所有服務正常啟動
- 合約成功部署
- MetaMask 網路配置正確
- 測試帳戶已導入
- 錢包連接正常
- 簽名認證成功
- 餘額顯示正確
- 交易執行成功
- 角色權限正確
- 帳戶切換檢測
- 所有 E2E 測試通過
- 單元測試覆蓋率達標
- 合約測試通過
- 無測試超時或失敗
- 錢包連接: < 2 秒
- 簽名認證: < 3 秒
- 餘額查詢: < 1 秒
- 交易確認: < 10 秒 (取決於區塊時間)
本專案提供多種現代化工具進行 API 效能測試。選擇適合您需求的工具來測試 DApp API (localhost:3001)。
k6 是用 Go 編寫的現代化負載測試工具,適合複雜場景、效能回歸測試與 CI/CD 整合。
# 安裝 k6
# MacOS
brew install k6
# Linux
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
# Windows (使用 Chocolatey)
choco install k6基本健康檢查測試:
# 建立測試腳本 load-test.js
cat > load-test.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
vus: 10,
duration: '30s',
thresholds: {
http_req_duration: ['p(95)<500'], // 95% 請求應在 500ms 內完成
http_req_failed: ['rate<0.01'], // 錯誤率應低於 1%
},
};
export default function () {
const res = http.get('http://localhost:3001/health');
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
EOF
# 執行測試
k6 run load-test.js進階 API 壓力測試 (包含認證流程):
# 建立進階測試腳本 load-test-advanced.js
cat > load-test-advanced.js << 'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '30s', target: 20 }, // 30 秒內增加到 20 虛擬用戶
{ duration: '1m', target: 50 }, // 維持 50 虛擬用戶 1 分鐘
{ duration: '30s', target: 0 }, // 30 秒內降到 0
],
};
export default function () {
// 測試健康檢查
let res = http.get('http://localhost:3001/health');
check(res, { 'health check ok': (r) => r.status === 200 });
// 測試 API 端點 (根據實際 API 調整)
res = http.get('http://localhost:3001/api/balance', {
headers: { 'Content-Type': 'application/json' },
});
check(res, { 'balance API ok': (r) => r.status === 200 || r.status === 401 });
sleep(1);
}
EOF
# 執行進階測試
k6 run load-test-advanced.js
# 輸出 JSON 報告
k6 run --out json=results.json load-test-advanced.jsAutocannon 是用 Node.js 編寫的快速 HTTP/1.1 基準測試工具,適合快速評估服務極限。
# 安裝 (全域)
npm install -g autocannon
# 或使用 npx 直接執行 (無需安裝)基本健康檢查測試:
# 100 個並發連線,持續 10 秒
npx autocannon -c 100 -d 10 http://localhost:3001/health
# 查看詳細統計
npx autocannon -c 100 -d 10 --renderStatusCodes http://localhost:3001/health進階 API 測試 (包含請求頭):
# 測試帶認證的 API 端點
npx autocannon -c 50 -d 30 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:3001/api/balance
# 測試 POST 請求 (使用管道傳輸 JSON)
npx autocannon -c 50 -d 30 \
-m POST \
-H "Content-Type: application/json" \
-b '{"address":"0x1234..."}' \
http://localhost:3001/api/transfer程式化使用 (Node.js 腳本):
# 建立測試腳本 autocannon-test.js
cat > autocannon-test.js << 'EOF'
const autocannon = require('autocannon');
const instance = autocannon({
url: 'http://localhost:3001/health',
connections: 100,
duration: 10,
pipelining: 1,
}, (err, result) => {
if (err) {
console.error(err);
return;
}
console.log('完成測試:');
console.log(`平均 RPS: ${result.requests.average}`);
console.log(`平均延遲: ${result.latency.mean} ms`);
console.log(`P99 延遲: ${result.latency.p99} ms`);
});
// 即時追蹤進度
autocannon.track(instance);
EOF
# 執行程式化測試
node autocannon-test.jsArtillery 是用於負載測試、煙霧測試和持續效能驗證的現代化工具。
# 安裝最新版本
npm install -g artillery@latest
# 驗證版本 (應為 2.x+)
artillery version快速測試模式:
# 快速健康檢查測試 (10 虛擬用戶,每人 20 個請求)
artillery quick --count 10 --num 20 http://localhost:3001/health
# 設定請求速率 (每秒 50 個請求,持續 60 秒)
artillery quick --rate 50 --duration 60 http://localhost:3001/health設定檔模式 (推薦用於複雜場景):
# 建立 Artillery 設定檔 artillery.yml
cat > artillery.yml << 'EOF'
config:
target: 'http://localhost:3001'
phases:
- duration: 60
arrivalRate: 10
name: "預熱階段"
- duration: 120
arrivalRate: 50
name: "壓力測試階段"
- duration: 60
arrivalRate: 5
name: "降壓階段"
plugins:
expect: {}
processor: "./processor.js"
scenarios:
- name: "健康檢查流程"
flow:
- get:
url: "/health"
expect:
- statusCode: 200
- contentType: json
- name: "API 完整流程"
weight: 70
flow:
- get:
url: "/health"
- think: 2
- get:
url: "/api/balance"
headers:
Content-Type: "application/json"
expect:
- statusCode: [200, 401]
- think: 3
- post:
url: "/api/transfer"
json:
to: "0x1234567890abcdef"
amount: "100"
expect:
- statusCode: [200, 400, 401]
EOF
# 執行設定檔測試
artillery run artillery.yml
# 產生 HTML 報告
artillery run --output report.json artillery.yml
artillery report --output report.html report.json設定自訂處理器 (進階用法):
# 建立處理器檔案 processor.js
cat > processor.js << 'EOF'
module.exports = {
setAuthToken: function(context, events, done) {
// 模擬認證邏輯
context.vars.authToken = 'Bearer mock-jwt-token';
return done();
},
logResponse: function(requestParams, response, context, ee, next) {
console.log(`狀態碼: ${response.statusCode}`);
return next();
}
};
EOF
# 在 artillery.yml 中使用處理器函式| 工具 | 適用場景 | 優勢 | 劣勢 |
|---|---|---|---|
| k6 | CI/CD 整合、效能回歸測試、複雜腳本 | JavaScript 語法、強大的檢查點、詳細指標 | 需要額外安裝 |
| Autocannon | 快速基準測試、最大吞吐量評估 | 極快速度、Node.js 原生、低資源消耗 | 功能相對簡單 |
| Artillery | 多步驟使用者流程、場景模擬 | YAML 設定簡單、插件豐富、易讀報告 | 較大記憶體佔用 |
執行負載測試時,參考以下基準值:
-
健康檢查 (/health):
- 目標 RPS: > 1000 req/s
- 平均延遲: < 50ms
- P95 延遲: < 100ms
-
API 查詢 (/api/balance):
- 目標 RPS: > 500 req/s
- 平均延遲: < 200ms
- P95 延遲: < 500ms
-
區塊鏈交易 (/api/transfer):
- 目標 RPS: > 100 req/s
- 平均延遲: < 1000ms
- P95 延遲: < 2000ms
- 錯誤率: < 1%
- Nonce 防重放攻擊
- 簽名驗證正確性
- JWT Token 有效期
- 帳戶變更檢測
- 角色權限隔離
- 輸入參數驗證
- 重入攻擊防護
- 整數溢出保護
每次測試執行後記錄:
- 測試日期時間
- 執行的測試套件
- 通過/失敗數量
- 發現的問題
- 修復措施
- E2E 測試: 27 scenarios, 2.3 分鐘執行時間
- 覆蓋率: L1 + L2 + L3 完整覆蓋
- 成功率: 目標 100% 通過率
最後更新: 2025-12-17
版本: v1.0
維護者: 開發團隊