# testing-patterns > Testing patterns for smart contracts and APIs. Unit, integration, e2e tests. TDD workflows. Use when writing tests for any project. - Author: Clawd Bot - Repository: BAiSEDagent/openclaw-skills - Version: 20260208142402 - Stars: 0 - Forks: 0 - Last Updated: 2026-02-08 - Source: https://github.com/BAiSEDagent/openclaw-skills - Web: https://mule.run/skillshub/@@BAiSEDagent/openclaw-skills~testing-patterns:20260208142402 --- --- name: testing-patterns description: "Testing patterns for smart contracts and APIs. Unit, integration, e2e tests. TDD workflows. Use when writing tests for any project." metadata: openclaw: emoji: "๐Ÿงช" --- # Testing Patterns Reusable testing patterns for smart contracts, APIs, and agent systems. ## Philosophy - Test behavior, not implementation - Every public function gets a test - Happy path first, then edge cases, then adversarial - Tests are documentation โ€” name them clearly ## Test Structure (Arrange-Act-Assert) ```typescript describe('x402 middleware', () => { it('returns 402 with payment header for protected routes', async () => { // Arrange const app = createTestServer({ price: '100000' }); // Act const res = await request(app).get('/premium'); // Assert expect(res.status).toBe(402); expect(res.headers['payment-required']).toBeDefined(); }); }); ``` ## Smart Contract Testing ### Foundry (Solidity tests) ```solidity contract PaymentTest is Test { USDC usdc; function setUp() public { usdc = new USDC(); usdc.mint(alice, 1000e6); } function test_transferWithAuthorization() public { // Sign off-chain, execute on-chain bytes32 nonce = keccak256("unique"); (uint8 v, bytes32 r, bytes32 s) = vm.sign(aliceKey, digest); usdc.transferWithAuthorization(alice, bob, 100e6, 0, block.timestamp + 1, nonce, v, r, s); assertEq(usdc.balanceOf(bob), 100e6); } function testFail_expiredAuthorization() public { // Should revert with expired validBefore vm.warp(block.timestamp + 1000); usdc.transferWithAuthorization(alice, bob, 100e6, 0, block.timestamp - 1, nonce, v, r, s); } } ``` ### Hardhat (TypeScript tests) ```typescript describe('EAS Attestation', () => { let eas: Contract; beforeEach(async () => { eas = await deployEAS(); }); it('creates attestation with correct schema', async () => { const uid = await eas.attest({ schema: SCHEMA_UID, data: { ... } }); const attestation = await eas.getAttestation(uid); expect(attestation.schema).to.equal(SCHEMA_UID); }); }); ``` ## API Testing ### Vitest + Supertest ```typescript import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import request from 'supertest'; describe('AgentHQ API', () => { let app: Express; beforeAll(async () => { app = await createApp({ database: ':memory:' }); }); describe('POST /api/agents/register', () => { it('registers new agent with valid data', async () => { const res = await request(app) .post('/api/agents/register') .send({ name: 'TestAgent', capabilities: ['data-analysis'] }) .expect(201); expect(res.body.agent.id).toBeDefined(); }); it('rejects duplicate agent names', async () => { await request(app).post('/api/agents/register').send({ name: 'Dupe' }); await request(app).post('/api/agents/register').send({ name: 'Dupe' }).expect(409); }); }); }); ``` ### Testing x402 Payment Flow (Integration) ```typescript it('completes full payment cycle', async () => { // 1. Get 402 const initial = await request(app).get('/premium'); expect(initial.status).toBe(402); // 2. Parse payment requirement const paymentInfo = JSON.parse(Buffer.from(initial.headers['payment-required'], 'base64').toString()); // 3. Sign payment const signature = await signPayment(wallet, paymentInfo); // 4. Submit with payment const paid = await request(app) .get('/premium') .set('Payment-Signature', Buffer.from(JSON.stringify(signature)).toString('base64')); expect(paid.status).toBe(200); expect(paid.headers['payment-response']).toBeDefined(); }); ``` ## Test Categories | Category | What | Tools | When | |----------|------|-------|------| | **Unit** | Single function/method | Vitest, Foundry | Every PR | | **Integration** | Multiple components | Supertest, Hardhat | Every PR | | **E2E** | Full user flow | Playwright, curl | Before deploy | | **Fuzz** | Random inputs | Foundry fuzz | Security-critical code | | **Gas** | Gas consumption | Foundry gas reports | Optimization passes | ## Coverage Targets - Core business logic: 90%+ - Payment flows: 100% (money is involved) - API endpoints: 80%+ - UI components: 60%+ (snapshot + interaction) ## Common Mistakes - โŒ Testing mocks instead of behavior - โŒ Tests that pass when code is broken (false positives) - โŒ Hardcoded timestamps that break later - โŒ Missing edge cases: zero amounts, empty strings, max uint256 - โŒ Not testing error paths and reverts ## References - **[references/foundry-testing.md](references/foundry-testing.md)** โ€” Foundry-specific: fuzz, invariant, fork tests - **[references/api-testing.md](references/api-testing.md)** โ€” HTTP testing patterns, auth testing, rate limit testing