Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when writing tests for Rust service code - unit tests beside the code, integration tests in tests/, tokio::test, Router::oneshot for HTTP, sqlx::test for a fresh database per test, trait fakes or mockall at ports, test-first
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
Test-first, same discipline as everywhere (see tdd-workflow): write the failing test, watch it fail, minimal code to pass. This skill is the Rust mechanics for a service.
Core principle: the type system already rules out a lot; tests cover behaviour, invariants and the boundaries the compiler cannot see — HTTP wiring, serialization and SQL.
| Level | What it covers | Tools |
|---|---|---|
| Unit | Domain types and pure functions | #[cfg(test)] mod tests in the same file, #[test] |
| Unit with fakes | Service, its port traits faked | a hand-written fake struct, or mockall where the repository uses it |
| HTTP | Routing, extractors, status codes, error body | the Router called with tower::ServiceExt::oneshot — no port |
| Persistence | sqlx queries and migrations | #[sqlx::test]: a fresh database per test with migrations applied |
Integration tests that use the crate's public API go in tests/.
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn title_rejects_blank_and_overlong() {
for bad in ["", " ", &"x".repeat(201)] {
assert!(TaskTitle::try_from(bad.to_string()).is_err(), "{bad:?} should be rejected");
}
assert!(TaskTitle::try_from("x".repeat(200)).is_ok());
}
#[tokio::test]
async fn create_stores_the_task() {
let repo = FakeTaskRepo::default();
let service = TaskService::new(repo.clone());
let task = service.create(UserId::new(1), TaskTitle::try_from("Report".into()).unwrap()).await.unwrap();
assert_eq!(repo.stored(), vec![task]);
}
}
unwrap() is fine in tests: a panic is a failure with a line number.
#[tokio::test]
async fn blank_title_is_400_in_the_problem_shape() {
let app = router(test_state());
let res = app
.oneshot(Request::post("/tasks").header("content-type", "application/json")
.header("authorization", test_token(1)).body(Body::from(r#"{"title":""}"#)).unwrap())
.await
.unwrap();
assert_eq!(res.status(), StatusCode::BAD_REQUEST);
let body: serde_json::Value = serde_json::from_slice(&res.into_body().collect().await.unwrap().to_bytes()).unwrap();
assert!(body["errors"]["title"].is_string());
}
Arc<Mutex<Vec<_>>>) is often clearer than a mock; mockall's #[automock] where the repository already uses it. Never fake the type under test.rstest's #[case] where the repository uses it.#[sqlx::test] for anything that runs SQL: each test gets its own database with the migrations applied, so tests run in parallel without sharing rows. It needs DATABASE_URL pointing at a server it may create databases on (a container in CI and locally).tokio::time::pause() + advance() in #[tokio::test(start_paused = true)] for timers; never a real sleep.proptest) for parsers and invariants with large input spaces, where the repository has them.cargo test title_rejects or cargo test -p <crate> --test <file>; the full cargo test (all features the CI uses) plus cargo clippy --all-targets -- -D warnings before you stop. Coverage with cargo llvm-cov; mutation testing, where the repository runs it, is cargo mutants.#[ignore] on a failing test instead of fixing it.Debug output strings rather than values.std::thread::sleep in a test to wait for a task.아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
Use when writing acceptance criteria for a task - express each as an observable Given/When/Then that QA can execute, including negative cases
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the diff adds or changes an endpoint, resolver, RPC, job or query that takes an object id, a role check, a request binding or a tenant filter - BOLA/IDOR, function-level authorization, mass assignment and tenant scoping
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use on every UI change - semantic HTML, labels for controls, keyboard-navigable dialogs/menus, visible focus, and never color as the only signal
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when a task changes any screen, form, dialog, menu or control - Lighthouse/axe scan of the changed screens, a keyboard walk, and the thresholds that fail a task
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
How to work a task returned with review, QA or UAT findings. Use when a task is in need_revision or PR review comments are in your context.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when the repository keeps its alerting in code, or a person asks for alerts outside TaskTrooper - PrometheusRule YAML, a Cloud Monitoring alert policy in Terraform, a Datadog monitor, each routed to TaskTrooper's alert ingest URL so it opens an incident here
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.