qwen_2.5_model / docs /09-testing-strategy.md
Muhammad Noman
Deploy OpenWA to Hugging Face Spaces
46252cd
|
Raw
History Blame Contribute Delete
13.9 kB

09 - Testing Strategy

9.1 Current Status

OpenWA now has an active Jest test suite covering the backend core, engine adapters, security helpers, database migrations, plugin hooks, and smoke-level e2e boot paths. This document describes the current test layout and the expected testing workflow for contributors.

Area Current state
Backend unit tests Source-controlled *.spec.ts files under src/; use the inventory commands below
E2E smoke tests Source-controlled *.e2e-spec.ts files under test/; use the inventory commands below
Dashboard checks ESLint, test type-check, i18n parity, React/Vite build, and source-controlled Node tests
SDK checks Path-filtered JavaScript, Python, PHP, Java, and Go SDK CI
PostgreSQL checks Dedicated CI job builds migrations and runs npm run test:pg-smoke against PostgreSQL 16
Coverage gate Jest global thresholds plus stricter thresholds for security, auth, engine-adapter, and integration modules

The exact counts will change as the project evolves. Use the commands below as the source of truth for the test inventory, and use the test commands in the next section for pass/fail status.

rg --files -g '*.spec.ts' src | wc -l
rg --files -g '*.e2e-spec.ts' test | wc -l
rg --files -g '*.test.ts' dashboard/src | wc -l
rg --files sdk/javascript/test sdk/python/tests sdk/php/tests sdk/java/src/test sdk/go \
  | rg '(\.test\.ts$|test_.*\.py$|Test\.php$|Test\.java$|_test\.go$)' \
  | wc -l
npm test -- --runInBand
npm run test:e2e -- --runInBand
npm --prefix dashboard run test:unit

9.2 Test Commands

Command Purpose
npm test Run backend Jest unit tests from src/
npm test -- --runInBand Run backend tests serially; useful for local debugging and clean output
npm run test:cov Run backend tests with coverage and coverage thresholds
npm run test:e2e Run smoke-level e2e tests from test/
npm run test:pg-smoke Run the PostgreSQL migration and UUID-default smoke test
npm run lint Run backend ESLint with type-aware rules
npx tsc --noEmit -p tsconfig.json Type-check backend source, unit specs, and e2e specs
npm run openapi:check Verify the committed OpenAPI snapshot
npm run check:versions Verify documentation and package version consistency
cd dashboard && npm run lint Run dashboard ESLint
cd dashboard && npm run typecheck Type-check dashboard test files
cd dashboard && npm run test:unit Run dashboard pure utility/unit tests
cd dashboard && npm run i18n:check Verify dashboard locale key parity
cd dashboard && npm run build Type-check and build the dashboard
cd sdk/javascript && npm test && npm run build && npm run smoke Test and package-smoke the JavaScript SDK
cd sdk/python && pytest Run the Python SDK tests
cd sdk/php && ./vendor/bin/phpunit Run the PHP SDK tests
cd sdk/java && mvn -B verify Run the Java SDK tests
cd sdk/go && go vet ./... && go test -race ./... Vet and race-test the Go SDK

9.3 Backend Unit Tests

Backend unit tests live next to the source files they cover:

src/
β”œβ”€β”€ common/
β”‚   β”œβ”€β”€ security/
β”‚   β”‚   β”œβ”€β”€ ssrf-guard.ts
β”‚   β”‚   └── ssrf-guard.spec.ts
β”‚   └── storage/
β”‚       β”œβ”€β”€ storage.service.ts
β”‚       └── storage.service.spec.ts
β”œβ”€β”€ engine/
β”‚   β”œβ”€β”€ adapters/
β”‚   β”‚   β”œβ”€β”€ baileys.adapter.ts
β”‚   β”‚   └── baileys.adapter.spec.ts
β”‚   └── identity/
β”‚       β”œβ”€β”€ wa-id.ts
β”‚       └── wa-id.spec.ts
└── modules/
    β”œβ”€β”€ session/
    β”‚   β”œβ”€β”€ session.service.ts
    β”‚   └── session.service.spec.ts
    └── webhook/
        β”œβ”€β”€ webhook.service.ts
        └── webhook.service.spec.ts

What Unit Tests Should Cover

  • Service behavior, validation, and error mapping.
  • Engine adapter mapping at the boundary, especially neutral WhatsApp IDs and delivery statuses.
  • Security helpers such as SSRF checks, path containment, trusted proxy IP resolution, and secret-file handling.
  • Database migrations for SQLite and PostgreSQL where SQL differs.
  • Plugin hooks, plugin loading, and capability wrappers.
  • Race-prone behavior such as reconnect handling, ack reconciliation, and concurrent reaction updates.

Unit Test Pattern

Use Nest's testing module when dependency injection behavior matters. For pure functions and small helpers, prefer direct imports with focused assertions.

describe('resolveReconnectConfig', () => {
  it('clamps invalid reconnect settings to safe defaults', () => {
    expect(
      resolveReconnectConfig({
        maxReconnectAttempts: 'not-a-number',
        reconnectBaseDelay: -1,
      }),
      // non-numeric attempts β†’ the default: unlimited retries (backoff parks at the 1h cap);
      // negative baseDelay β†’ clamped up to the 1s minimum
    ).toEqual({ maxAttempts: Number.POSITIVE_INFINITY, baseDelay: 1000 });
  });
});

9.4 E2E Smoke Tests

E2E smoke tests live in test/ and use test/jest-e2e.json.

test/
β”œβ”€β”€ app.e2e-spec.ts
β”œβ”€β”€ baileys-engine.e2e-spec.ts
β”œβ”€β”€ ingress-instance-throttle.e2e-spec.ts
β”œβ”€β”€ integration-fabric.e2e-spec.ts
β”œβ”€β”€ integration-instance.e2e-spec.ts
β”œβ”€β”€ mcp-auth.e2e-spec.ts
β”œβ”€β”€ serve-static.e2e-spec.ts
β”œβ”€β”€ webhooks.e2e-spec.ts
β”œβ”€β”€ jest-e2e.json
└── setup-e2e.ts

test/setup-e2e.ts configures the app for local test boot before AppModule is imported:

  • NODE_ENV=test
  • SQLite database
  • queue disabled
  • auto-start sessions disabled
  • schema synchronize enabled for test boot

The e2e suite intentionally avoids requiring a live WhatsApp account. It focuses on application boot, authentication plumbing, public health endpoints, engine selection paths, and dashboard static serving behavior.

9.5 Coverage Policy

Coverage thresholds are defined in package.json under the Jest configuration. Treat that file as the authoritative gate. Current policy:

Scope Branches Functions Lines Statements
Global 58% 58% 66% 65%
src/common/security/ 85% 95% 90% 90%
src/modules/auth/ 62% 70% 72% 72%
src/engine/adapters/ 63% 63% 70% 70%
src/modules/integration/ 67% 68% 77% 77%
src/core/hooks/ 80% 70% 82% 81%
src/modules/session/ 50% 63% 74% 72%
src/modules/webhook/ 65% 83% 84% 80%

The stricter scoped gates protect security-sensitive code and high-risk boundary layers. When adding security, engine-adapter, or integration-fabric behavior, add focused regression tests instead of relying on broad integration coverage.

9.6 CI Checks

Main CI is defined in .github/workflows/ci.yml.

Job Checks
lint security audit, backend ESLint, full-program TypeScript check, formatting, version consistency, OpenAPI snapshot
test backend coverage run, e2e smoke tests, Codecov upload
test-postgres real PostgreSQL 16 service, backend build, migration smoke, and PostgreSQL FTS provider spec
dashboard dashboard install, lint, test type-check, unit tests, i18n parity, build
build backend build after lint/test/dashboard jobs pass
docker multi-arch Docker build on pushes and pull requests; publish only where workflow permissions allow

SDK CI is defined in .github/workflows/sdk-ci.yml and is path-filtered to SDK sources plus server contract surfaces that SDKs mirror (src/**/dto/** and the engine interface). It runs:

  • JavaScript SDK tests, build, and dual CJS/ESM smoke test.
  • Python SDK tests with pytest.
  • PHP SDK tests with PHPUnit.
  • Java SDK tests with Maven.
  • Go SDK formatting, go vet, and race-enabled tests at the declared Go floor.

Release tags run .github/workflows/release.yml. The release gate verifies the tag matches package.json, checks documented version consistency, runs backend tests with coverage, builds the backend, and publishes the GitHub Release only after the Docker image has built and pushed successfully.

9.7 Testing Guidelines

Add Tests Near the Risk

For narrow changes, add or update the nearest *.spec.ts. For shared behavior, test both the helper and one representative consumer. For adapter changes, test the adapter boundary shape rather than the external WhatsApp library itself.

Mock External Systems

Do not require live WhatsApp, Redis, S3, Docker, or internet access for the default test suite. Use mocks, temporary directories, or local in-memory objects. Keep live-service tests opt-in and document their environment variables separately.

Preserve Engine-Neutral Contracts

Tests that touch WhatsApp IDs should assert the neutral dialect used by application code:

  • <phone>@c.us
  • <id>@g.us
  • <lid>@lid
  • status@broadcast, <id>@newsletter, <id>@broadcast

Application-level tests should not assert raw Baileys @s.whatsapp.net IDs or whatsapp-web.js internals.

Test Failure Paths

For services that dispatch asynchronously, include tests for lookup failure, delivery failure, retries, and swallowed fire-and-forget errors. A callback used with void should either catch internally or be covered by a test proving it cannot leak an unhandled rejection.

Keep E2E Fast

E2E tests should stay smoke-level unless a change specifically needs a full app boot. Prefer unit tests for business logic and e2e tests for wiring, guards, global pipes, app boot, and route-level behavior.

9.8 Manual Smoke Checks

Use these checks when changing Docker, Chromium, dashboard serving, or session startup behavior.

npm run build:all
node dist/main
docker compose -f docker-compose.dev.yml up -d --build
curl -f http://localhost:2785/api/health/ready

For production-compose changes:

docker compose up -d --build
docker compose logs -f openwa-api

Live WhatsApp checks require an operator-owned account and should not be part of CI:

  1. Create a session.
  2. Start the session.
  3. Scan QR or request a pairing code.
  4. Confirm session reaches ready.
  5. Send a text message to a test chat.
  6. Confirm message history, webhook delivery, and WebSocket events.

9.9 Known Gaps

  • No default CI job exercises a real WhatsApp connection.
  • The default test job uses SQLite; a dedicated test-postgres CI job exercises PostgreSQL 16.
  • No default CI job exercises real Redis, S3/MinIO, or Docker socket proxy integration.
  • Performance testing is not automated.
  • Dashboard browser/visual UI tests are not currently automated; dashboard pure utility tests run via npm --prefix dashboard run test:unit.

These gaps are intentional for the default suite because the project prioritizes deterministic tests that run without external services. Add opt-in integration jobs only when they are isolated, documented, and do not make normal contributor workflows brittle.