Skip to content

Testing Strategy

dev-mondoshawan edited this page Apr 16, 2026 · 1 revision

Testing Strategy

**Referenced Files in This Document** - [backend/src/models/__mocks__/db.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/models/__mocks__/db.js) - [backend/src/services/bagsAuthVerifier.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/services/bagsAuthVerifier.js) - [backend/src/services/pkiChallenge.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/services/pkiChallenge.js) - [backend/src/routes/agents.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/routes/agents.js) - [backend/src/routes/register.js](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/src/routes/register.js) - [backend/package.json](https://github.com/RunTimeAdmin/AgentID/blob/main/backend/package.json) - [frontend/package.json](https://github.com/RunTimeAdmin/AgentID/blob/main/frontend/package.json)

Table of Contents

  1. Introduction
  2. Testing Levels
  3. Unit Testing
  4. Integration Testing
  5. End-to-End Testing
  6. Security Testing
  7. Performance Testing
  8. Test Data Management
  9. Continuous Integration

Introduction

AgentID employs a comprehensive testing strategy covering unit, integration, and end-to-end tests. The goal is to ensure reliability, security, and performance across all components.

Testing Levels

graph TB
E2E["E2E Tests<br/>Critical User Flows"] --> Integration["Integration Tests<br/>API Endpoints"]
Integration --> Unit["Unit Tests<br/>Services & Utils"]
Unit --> Mock["Mocked Dependencies"]
Loading

Unit Testing

Service Tests

Test individual service functions with mocked dependencies:

// Example: bagsAuthVerifier test
describe('bagsAuthVerifier', () => {
  describe('verifyBagsSignature', () => {
    it('should return true for valid signature', () => {
      const result = verifyBagsSignature(message, signature, pubkey);
      expect(result).toBe(true);
    });
    
    it('should return false for invalid signature', () => {
      const result = verifyBagsSignature(message, 'invalid', pubkey);
      expect(result).toBe(false);
    });
  });
});

Mocking Database

The setMockQuery() function enables database mocking:

const { setMockQuery } = require('../models/db');

beforeEach(() => {
  setMockQuery((text, params) => {
    // Return mock data based on query
    if (text.includes('SELECT')) {
      return { rows: [{ pubkey: 'test', name: 'Test Agent' }] };
    }
    return { rows: [] };
  });
});

Integration Testing

API Endpoint Tests

Test routes with real HTTP requests:

describe('POST /api/register', () => {
  it('should create a new agent', async () => {
    const response = await request(app)
      .post('/api/register')
      .send({
        pubkey: 'valid_pubkey',
        name: 'Test Agent',
        signature: 'valid_sig',
        message: 'test_message',
        nonce: 'test_nonce'
      });
    
    expect(response.status).toBe(201);
    expect(response.body.agent).toBeDefined();
  });
  
  it('should reject invalid input', async () => {
    const response = await request(app)
      .post('/api/register')
      .send({ name: 'Test Agent' }); // Missing required fields
    
    expect(response.status).toBe(400);
  });
});

Database Integration

Test with real database:

  • Use test database
  • Clean up after each test
  • Use transactions for isolation

End-to-End Testing

Critical User Flows

  1. Registration Flow

    • Navigate to registration page
    • Fill form and submit
    • Verify agent created
  2. Verification Flow

    • Request challenge
    • Sign challenge
    • Submit response
    • Verify completion
  3. Discovery Flow

    • Search for agents
    • Filter by capability
    • View agent details

E2E Tools

  • Cypress: For frontend E2E tests
  • Playwright: Alternative E2E testing

Security Testing

Signature Verification

Test Ed25519 signature validation:

describe('Security: Signature Verification', () => {
  it('should reject tampered signatures', () => {
    const tamperedSig = signature.slice(0, -5) + 'xxxxx';
    const result = verifySignature(message, tamperedSig, pubkey);
    expect(result).toBe(false);
  });
  
  it('should reject replayed nonces', async () => {
    // Complete verification once
    await verifyChallenge(pubkey, nonce, signature);
    
    // Attempt replay
    await expect(verifyChallenge(pubkey, nonce, signature))
      .rejects.toThrow('Challenge already completed');
  });
});

Rate Limiting

Verify rate limiting works:

describe('Security: Rate Limiting', () => {
  it('should block excessive requests', async () => {
    // Make requests up to limit
    for (let i = 0; i < 100; i++) {
      await request(app).get('/api/agents');
    }
    
    // Next request should be blocked
    const response = await request(app).get('/api/agents');
    expect(response.status).toBe(429);
  });
});

Performance Testing

Load Testing

Use tools like Artillery or k6:

# artillery.yml
config:
  target: 'http://localhost:3002'
  phases:
    - duration: 60
      arrivalRate: 10
scenarios:
  - name: "Get badge"
    requests:
      - get:
          url: "/api/badge/test_pubkey"

Benchmarks

Target performance metrics:

  • API response time: < 200ms (p95)
  • Badge generation: < 100ms (cached)
  • Database queries: < 50ms

Test Data Management

Fixtures

Use consistent test data:

// test/fixtures/agents.js
module.exports = {
  validAgent: {
    pubkey: 'A'.repeat(88),
    name: 'Test Agent',
    signature: 'valid_signature',
    message: 'challenge_message',
    nonce: 'test_nonce'
  },
  invalidAgent: {
    pubkey: 'short',
    name: ''
  }
};

Database Seeding

Seed test database:

beforeAll(async () => {
  await seedDatabase([
    { table: 'agent_identities', data: testAgents },
    { table: 'agent_verifications', data: testVerifications }
  ]);
});

afterAll(async () => {
  await cleanupDatabase();
});

Continuous Integration

GitHub Actions Workflow

name: Test
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:14
      redis:
        image: redis:7
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18
      - run: npm ci
      - run: npm run migrate
      - run: npm test
      - run: npm run test:coverage

Coverage Requirements

Minimum coverage thresholds:

  • Statements: 80%
  • Branches: 75%
  • Functions: 80%
  • Lines: 80%

Pre-commit Hooks

Run tests before commits:

{
  "husky": {
    "hooks": {
      "pre-commit": "npm run lint && npm run test:staged"
    }
  }
}

Clone this wiki locally