Skip to content

Latest commit

 

History

History
595 lines (476 loc) · 13.2 KB

File metadata and controls

595 lines (476 loc) · 13.2 KB

DApp Testing Manual

概述

本手冊提供 Dapp Studio 三層架構 DApp 的完整測試指南,包含自動化測試和手動測試流程。

架構層級

  • L1 (智能合約層): ERC-20 + RBAC 合約
  • L2 (API 層): Express.js + Web3 認證
  • L3 (前端層): React + Drizzle + MetaMask

環境準備

必要工具

  • Node.js v22+
  • MetaMask 瀏覽器擴展
  • Git

Port 配置

  • Ganache: localhost:8545
  • API Server: localhost:3001
  • Frontend: localhost:5173

服務啟動順序

1. 啟動 Ganache

# 使用確定性模式啟動
ganache --deterministic --port 8545

2. 部署智能合約

# 編譯合約
npm run build:contracts

# 部署合約 (使用直接部署腳本)
node scripts/deploy.js

3. 啟動 API 服務器

cd backend && npm start

4. 啟動前端

cd frontend && npm run dev

5. 健康檢查

# 檢查所有服務
curl http://localhost:8545     # Ganache
curl http://localhost:3001/health  # API
curl http://localhost:5173     # Frontend

自動化測試

E2E 測試套件 (Playwright)

執行完整測試

# 安裝依賴
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"

單元測試

前端測試 (Vitest)

cd frontend && npm test

後端測試 (Vitest)

cd backend && npm test

智能合約測試 (Mocha)

cd contracts && npm test

手動測試流程

MetaMask 設定

1. 添加本地網路

  • 網路名稱: Ganache Local
  • RPC URL: http://127.0.0.1:8545
  • 鏈 ID: 1337
  • 貨幣符號: ETH

2. 導入測試帳戶

使用 Ganache 提供的私鑰導入帳戶:

# 查看可用帳戶
node scripts/derive-keys.js

Web3 認證測試

1. 基本連接流程

  1. 開啟 http://localhost:5173
  2. 點擊 "Login with Ethereum"
  3. MetaMask 彈出連接請求
  4. 確認連接
  5. 驗證帳戶地址顯示

2. 簽名認證流程

  1. 連接錢包後點擊 "Sign Message"
  2. MetaMask 彈出簽名請求
  3. 確認簽名
  4. 驗證 JWT Token 獲取
  5. 檢查認證狀態更新

3. 帳戶切換測試

  1. 在 MetaMask 中切換帳戶
  2. 驗證前端自動檢測變更
  3. 確認認證狀態重置
  4. 重新執行認證流程

RBAC 功能測試

1. 角色驗證

# 檢查預設管理員
node scripts/verify-deployment.js

2. 權限測試

  1. 使用管理員帳戶登入
  2. 嘗試執行管理員功能
  3. 切換到普通用戶帳戶
  4. 驗證權限限制

3. 角色授予/撤銷

  1. 管理員授予角色給其他帳戶
  2. 驗證新角色權限生效
  3. 撤銷角色
  4. 確認權限移除

合約互動測試

1. Token 餘額查詢

  1. 連接錢包
  2. 查看 Token 餘額顯示
  3. 驗證總供應量顯示

2. Token 轉帳

  1. 輸入接收地址和數量
  2. 執行轉帳交易
  3. 確認 MetaMask 交易
  4. 驗證餘額更新

3. 交易狀態追蹤

  1. 執行任何交易
  2. 觀察 "Pending" 狀態
  3. 等待區塊確認
  4. 驗證 "Confirmed" 狀態

故障排除

常見問題

1. "Error Tokens" 顯示

症狀: 前端顯示 "Error Tokens" 而非實際餘額 原因: 服務未正確啟動 解決方案:

# 檢查服務狀態
curl http://localhost:8545
curl http://localhost:3001/health

# 重新啟動服務
ganache --deterministic --port 8545

2. MetaMask 連接失敗

症狀: MetaMask 無法連接或顯示錯誤網路 解決方案:

  1. 確認 MetaMask 網路設定 (RPC: http://127.0.0.1:8545)
  2. 重置 MetaMask 帳戶 (Settings > Advanced > Reset Account)
  3. 清除瀏覽器快取

3. 合約部署失敗

症狀: 部署腳本報錯或合約地址無效 解決方案:

# 清理並重新部署
rm -rf contracts/build/
npm run build:contracts
node scripts/deploy.js

4. E2E 測試超時

症狀: Playwright 測試在 30s 後超時 解決方案:

  1. 確認所有服務正在運行
  2. 檢查 MetaMask 模擬設定
  3. 增加測試超時時間

日誌檢查

1. Ganache 日誌

# Ganache 會顯示所有交易和區塊資訊
# 檢查是否有交易失敗或 revert

2. API 服務器日誌

cd backend && npm start
# 檢查認證錯誤和 API 請求日誌

3. 瀏覽器控制台

  • 開啟開發者工具 (F12)
  • 檢查 Console 標籤的錯誤訊息
  • 查看 Network 標籤的 API 請求狀態

測試檢查清單

部署前檢查

  • 所有服務正常啟動
  • 合約成功部署
  • MetaMask 網路配置正確
  • 測試帳戶已導入

功能測試檢查

  • 錢包連接正常
  • 簽名認證成功
  • 餘額顯示正確
  • 交易執行成功
  • 角色權限正確
  • 帳戶切換檢測

自動化測試檢查

  • 所有 E2E 測試通過
  • 單元測試覆蓋率達標
  • 合約測試通過
  • 無測試超時或失敗

效能測試

響應時間基準

  • 錢包連接: < 2 秒
  • 簽名認證: < 3 秒
  • 餘額查詢: < 1 秒
  • 交易確認: < 10 秒 (取決於區塊時間)

負載測試 (Load Testing)

本專案提供多種現代化工具進行 API 效能測試。選擇適合您需求的工具來測試 DApp API (localhost:3001)。

1. k6 (推薦 - 腳本化測試與 CI/CD 整合)

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.js

2. Autocannon (高吞吐量基準測試)

Autocannon 是用 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.js

3. Artillery (最新版 - 場景導向測試)

Artillery 是用於負載測試、煙霧測試和持續效能驗證的現代化工具。

# 安裝最新版本
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
維護者: 開發團隊