**DOs** - Put tests first: Keep helper fns after tests to foreground intent. ```rust // Tests first /// Sends a prompt and asserts the streamed message. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn full_conversation_turn_integration() { /* ... */ } // Helpers after tests fn write_config(codex_home: &Path, server: &MockServer) { /* ... */ } ``` - Use readable multi-line config strings: Start with a leading newline; inline variables with format!. ```rust fs::write( codex_home.join("config.toml"), format!(r#" model_provider = "mock" model = "test-model" [model_providers.mock] name = "mock" base_url = "{}/v1" env_key = "PATH" wire_api = "responses" "#, server.uri()), )?; ``` - Consider indoc for long blocks: Keep indentation tidy without left margin loss. ```rust use indoc::formatdoc; fs::write( codex_home.join("config.toml"), formatdoc!(r#" model_provider = "mock" model = "test-model" [model_providers.mock] name = "mock" base_url = "{base}/v1" env_key = "PATH" wire_api = "responses" "#, base = server.uri()), )?; ``` - Prefer template + replace for SSE: Avoid brace-escaping hell in format! strings. ```rust fn sse_message(text: &str) -> String { const TEMPLATE: &str = r#"event: response.output_item.done data: {"type":"response.output_item.done","item":{"type":"message","role":"assistant","content":[{"type":"output_text","text":"TEXT_PLACEHOLDER"}]}} event: response.completed data: {"type":"response.completed","response":{"id":"resp1","output":[]}} "#; TEMPLATE.replace("TEXT_PLACEHOLDER", text) } ``` - Name things precisely: Use codex_home for the temp config directory. ```rust fn write_config(codex_home: &Path, server: &MockServer) { // ... } ``` - Assert on the final message via file: Use --output-last-message and compare file contents. ```rust let codex_home = TempDir::new().unwrap(); let sandbox = TempDir::new().unwrap(); write_config(codex_home.path(), &server); let last = sandbox.path().join("last_message.txt"); let mut cmd = assert_cmd::Command::cargo_bin("codex").unwrap(); cmd.env("CODEX_HOME", codex_home.path()) .current_dir(sandbox.path()) .arg("exec") .arg("--skip-git-repo-check") .arg("--output-last-message") .arg(&last) .arg("Hello"); cmd.assert().success().stdout(predicates::str::contains("Hello, world.")); assert_eq!(fs::read_to_string(&last).unwrap().trim(), "Hello, world."); ``` - Document each test: Add a one-liner docstring explaining the behavior under test. ```rust /// Simulates a shell tool call then verifies the assistant's follow-up. #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn tool_invocation_flow() { /* ... */ } ``` **DON'Ts** - Don’t put helpers above tests: It hides the test’s purpose and increases scrolling. ```rust // Anti-pattern: helpers first fn write_config(...) { /* ... */ } #[tokio::test] async fn test_case() { /* ... */ } ``` - Don’t hand-escape JSON braces inside format!: Hard to read and easy to break. ```rust // Anti-pattern: unreadable escaping format!("data: {{\"text\":\"{text}\"}}"); ``` - Don’t use vague names like dir or home: Be explicit about the directory’s role. ```rust // Anti-pattern: vague fn write_config(dir: &Path, server: &MockServer) { /* ... */ } ``` - Don’t assert only via stdout: Stream formatting can change; assert the canonical last message file. ```rust // Anti-pattern: only stdout check cmd.assert().stdout(predicates::str::contains("done")); ``` - Don’t omit test docstrings: Future readers shouldn’t have to infer the intent. ```rust // Anti-pattern: no docstring #[tokio::test] async fn full_conversation_turn_integration() { /* ... */ } ```