awa-testing 0.6.2

Test utilities for the Awa job queue
Documentation
# awa-testing

Test utilities for the [Awa](https://crates.io/crates/awa) job queue.

`awa-testing` lets you exercise job handlers and admin code paths in unit and integration tests without spinning up the full worker runtime. Use it for in-tree tests of the workspace, in your own crate's tests, or anywhere you want to drive a single job through a real Postgres without configuring queues, dispatchers, and maintenance leaders.

The crate is `dev-dependencies`-shaped: there is no embedded Postgres, you point it at a real test database (typically a local container on port `15432`).

## What's in here

- `TestClient` — synchronous-feeling wrapper around a `PgPool`:
  - `migrate()` runs the schema and resets the runtime backend so tests start from a known state.
  - `clean()` resets the runtime backend and deletes through the `awa.jobs` compatibility surface plus `awa.queue_meta` for cross-test isolation.
  - `insert(&args)` enqueues one job.
  - `work_one(&worker)` / `work_one_in_queue(&worker, queue)` claim and execute exactly one job through the supplied `Worker`, returning a `WorkResult` (`Completed`, `Failed`, `Snoozed`, `Retryable`, `Cancelled`, `WaitingExternal`, `NoJob`).
  - `get_job(id)` returns the current `JobRow`.
- `WorkResult` — enum with `is_completed()`, `is_failed()`, `is_waiting_external()`, `is_no_job()` predicates.
- `setup` module — `database_url()`, `database_url_with_app_name()`, `pool()`, `pool_with_url()` helpers and `reset_runtime_backend()` for explicit test cleanup.

`TestClient` is intentionally a lightweight compatibility-surface harness. It does not exercise the full dispatcher, queue-storage receipt plane, or maintenance leader; use the worker runtime or integration benchmarks when a test needs production storage-path fidelity.

## Usage

```rust
use awa::JobArgs;
use awa_testing::TestClient;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, JobArgs)]
struct SendEmail {
    to: String,
    subject: String,
}

struct SendEmailWorker;

#[async_trait::async_trait]
impl awa::Worker for SendEmailWorker {
    fn kind(&self) -> &'static str { "send_email" }
    async fn perform(&self, ctx: &awa::JobContext) -> Result<awa::JobResult, awa::JobError> {
        let _args: SendEmail = serde_json::from_value(ctx.job.args.clone())
            .map_err(|e| awa::JobError::terminal(e.to_string()))?;
        // ... run the side-effect under test ...
        Ok(awa::JobResult::Completed)
    }
}

#[tokio::test]
async fn send_email_completes() {
    let pool = awa_testing::setup::pool(4).await;
    let client = TestClient::from_pool(pool).await;
    client.migrate().await.unwrap();

    client.insert(&SendEmail {
        to: "test@example.com".into(),
        subject: "Test".into(),
    }).await.unwrap();

    let result = client.work_one_in_queue(&SendEmailWorker, Some("default")).await.unwrap();
    assert!(result.is_completed());
}
```

## See also

- [Test plan]../docs/test-plan.md
- [Development]../docs/development.md
- For Python projects, the equivalent helpers live in [`awa.testing`]../awa-python/python/awa/testing.py.

## License

MIT OR Apache-2.0