Skip to content

ADR-002: Integration Testing Strategy for E2E Workflows

Status: Accepted

Date: 2025-12-23

Authors: Development Team

Deciders: Core Development Team, Technical Lead

Context

The Prediction DAO Research platform consists of multiple interconnected smart contracts (FutarchyGovernor, WelfareMetricRegistry, ProposalRegistry, ConditionalMarketFactory, PrivacyCoordinator, OracleResolver, and RagequitModule) that must work together correctly to enable complete user workflows. While we have comprehensive unit tests for individual contracts, we lack integration tests to validate end-to-end (E2E) flows across contract boundaries.

Problem Statement

Without integration tests, we face several risks:

  1. Hidden Integration Bugs: Unit tests validate individual contracts but may miss issues in contract interactions, state synchronization, and event sequencing
  2. Manual Testing Burden: Developers must manually verify complete workflows, which is time-consuming and error-prone
  3. Regression Detection: Changes to one contract may break workflows involving other contracts, with no automated detection
  4. Deployment Confidence: Lack of E2E validation reduces confidence in production deployments
  5. Documentation Gap: No systematic documentation of expected E2E behaviors and workflows

Forces at Play

  • Complexity: The system has 6 key E2E workflows with multiple contracts interacting in each
  • Time Constraints: Need efficient test execution to maintain fast CI/CD pipeline
  • Existing Infrastructure: Already using Hardhat with comprehensive unit tests
  • Team Familiarity: Team is experienced with Hardhat and ethers.js
  • Maintainability: Tests must be maintainable as contracts evolve

Decision

We will implement a comprehensive integration testing strategy using the Hardhat ecosystem with the following approach:

  1. Testing Framework: Use Hardhat Network with ethers.js v6, Chai matchers, and Hardhat Network Helpers
  2. Test Organization: Create separate test/integration/ directory structure organized by feature area (clearpath, fairwins, oracle, factory)
  3. Fixture Pattern: Implement reusable deployment fixtures using loadFixture from @nomicfoundation/hardhat-network-helpers for efficient state management
  4. Coverage Target: Achieve 100% coverage of the 6 key E2E workflows:
  5. Complete proposal lifecycle (ClearPath)
  6. Privacy-preserving trading flow
  7. Multi-stage oracle resolution
  8. Ragequit protection flow
  9. FairWins market creation and resolution
  10. DAO factory deployment flow
  11. CI/CD Integration: Add dedicated GitHub Actions workflow for integration tests with coverage reporting
  12. Helper Library: Create reusable helper functions for common multi-step operations
  13. Documentation: Maintain comprehensive integration testing plan document with examples and best practices

Rationale

Why Hardhat Ecosystem?

  • Already in use: No new tooling to learn, leverages existing expertise
  • Performance: Hardhat Network's in-memory blockchain provides fast test execution
  • Debugging: Excellent debugging capabilities with console.log and stack traces
  • Community standard: Industry best practice for Ethereum development
  • Rich ecosystem: Network helpers, time manipulation, account impersonation all available

Why Separate Integration Tests?

  • Clarity: Clear distinction between unit and integration tests
  • Execution control: Can run integration tests separately (slower but more comprehensive)
  • Organization: Feature-based organization matches user workflows
  • Maintenance: Easier to locate and update tests related to specific flows

Why Fixture Pattern?

  • Performance: Snapshot/restore is much faster than redeploying contracts for each test
  • Consistency: Ensures all tests start from identical state
  • Reusability: Single fixture can support multiple test suites
  • Isolation: Tests remain independent without side effects

Why These 6 Workflows?

These workflows represent: - Critical paths: Most important user journeys through the system - Multi-contract interactions: Exercise integration points between contracts - Platform coverage: Cover both ClearPath (governance) and FairWins (markets) - Security-critical operations: Include oracle resolution, bond management, privacy

Consequences

Positive

  • Higher quality: Early detection of integration issues before production
  • Faster debugging: Failed tests pinpoint exact interaction failures
  • Deployment confidence: Validated E2E flows increase confidence in releases
  • Documentation: Tests serve as executable documentation of system behavior
  • Regression prevention: Automated tests catch breaking changes immediately
  • Onboarding aid: New developers can understand system by reading integration tests
  • Maintainability: Fixture pattern and helpers reduce code duplication

Negative

  • Test execution time: Integration tests are slower than unit tests (estimated 3-5 minutes for full suite)
  • Maintenance overhead: Must update integration tests when contracts change
  • Initial investment: Requires upfront time to create fixtures and first tests
  • CI/CD complexity: Adds another workflow to maintain in GitHub Actions

Risks and Mitigations

Risk: Tests become flaky due to timing issues - Mitigation: Use time.increase() explicitly instead of relying on block mining - Mitigation: Avoid race conditions with proper await usage - Mitigation: Use deterministic test data

Risk: Tests become too slow - Mitigation: Use fixture pattern for efficient state reset - Mitigation: Parallelize independent test files if needed - Mitigation: Monitor test execution time and optimize slow tests

Risk: Tests become outdated as contracts evolve - Mitigation: Include integration tests in code review process - Mitigation: Fail CI/CD if integration tests don't pass - Mitigation: Regular review of test coverage during sprints

Risk: Test maintenance burden - Mitigation: Create helper library to reduce duplication - Mitigation: Document test patterns and conventions - Mitigation: Provide examples and templates for common scenarios

Alternatives Considered

Alternative 1: Continue with Unit Tests Only

Pros: - No additional work required - Faster test execution - Simpler CI/CD pipeline

Cons: - No validation of E2E workflows - Integration bugs discovered in production - Manual testing required for releases - Poor documentation of system behavior

Why not chosen: Insufficient for validating complex multi-contract interactions critical to system reliability

Alternative 2: Use Foundry for Integration Tests

Pros: - Faster test execution (Rust-based) - Built-in fuzzing capabilities - Gas-efficient testing

Cons: - New tooling to learn (Solidity test syntax) - Less mature ecosystem for integration testing - Team unfamiliar with Foundry - Would require maintaining two test frameworks - Harder to simulate complex multi-step workflows

Why not chosen: Team expertise and project investment are in Hardhat ecosystem; adding another framework increases complexity

Alternative 3: End-to-End Tests with Frontend

Pros: - Tests entire stack including UI - Validates user experience - Catches frontend integration issues

Cons: - Much slower execution (minutes per test) - More fragile (UI changes break tests) - Harder to debug failures - Doesn't isolate contract issues - Requires maintaining test UI environment

Why not chosen: Too slow and fragile for primary integration testing; better suited for a small smoke test suite

Alternative 4: Manual Testing Checklist

Pros: - No code to maintain - Flexible for exploratory testing - Can catch UX issues

Cons: - Time-consuming for each release - Human error prone - Not automated in CI/CD - Poor documentation - Doesn't scale with system complexity

Why not chosen: Not reliable or scalable for continuous integration

Alternative 5: Use hardhat-deploy Plugin

Pros: - Advanced deployment management - Tag-based fixture system - Deterministic deployments

Cons: - Additional dependency - Steeper learning curve - Overkill for current needs - Adds complexity to simple scenarios

Why not chosen: Current fixture needs are simple enough for native loadFixture; can add later if needed

Implementation Notes

Phase 1: Foundation (Week 1)

  1. Create test/integration/ directory structure
  2. Implement deploySystemFixture in test/integration/fixtures/deploySystem.js
  3. Create helper functions library in test/integration/helpers/index.js
  4. Write first integration test for proposal lifecycle

Phase 2: Core Workflows (Weeks 2-3)

  1. Implement tests for privacy-preserving trading flow
  2. Implement tests for oracle resolution flow
  3. Implement tests for ragequit flow
  4. Implement tests for FairWins market lifecycle

Phase 3: Factory and Edge Cases (Week 4)

  1. Implement tests for DAO factory deployment
  2. Add error path tests for all workflows
  3. Add multi-user concurrent operation tests

Phase 4: CI/CD and Documentation (Week 5)

  1. Create .github/workflows/integration-tests.yml
  2. Add npm scripts for running integration tests
  3. Update documentation with examples
  4. Train team on writing integration tests

Success Criteria

  • All 6 key E2E workflows have passing integration tests
  • Integration test suite runs in under 5 minutes
  • Zero flaky tests (100% pass rate across 10 runs)
  • CI/CD fails on integration test failures
  • Integration testing documentation is complete
  • At least 2 team members can write integration tests independently

Monitoring

Track these metrics monthly: - Integration test count - Test execution time - Pass rate - Coverage of E2E workflows - Bugs caught by integration tests vs. production

References

Revision History

Date Changes Author
2025-12-23 Initial version Development Team