<!-- Generated by gzkit — do not edit manually -->
# tests Agent Instructions

> Shared subtree rules. See root `AGENTS.md` for project-wide governance.

# Cross-Platform Development Policy (Binding)

**Platforms:** Windows (primary), macOS, Linux
**Doctrine:** ADR-0.0.1

---

## Quick Reference

| Category     | Use                             | Avoid                         |
| ------------ | ------------------------------- | ----------------------------- |
| Paths        | `Path("dir") / "file"`          | `"dir/file"` or `"dir\\file"` |
| Encoding     | `encoding="utf-8"`              | Default encoding              |
| Temp files   | Context managers                | Raw `shutil.rmtree()`         |
| Subprocess   | List form, `uv run`             | `shell=True`, bare `python`   |
| Cleanup      | Context managers, `gc.collect()` | `ignore_errors=True`          |
| Line endings | `newline=""` for CSV            | Hard-coded `\r\n`             |

---

## File Paths (Always pathlib.Path)

```python
from pathlib import Path
config_path = Path("config") / "settings.json"
config_path.read_text(encoding="utf-8")
```

---

## Encoding (Always UTF-8)

```python
Path("data.json").read_text(encoding="utf-8")
```

---

## Temporary Files (Context Managers)

```python
with tempfile.TemporaryDirectory() as temp_dir:
    temp_path = Path(temp_dir) / "data.json"
    # Cleanup automatic (Windows-safe)
```

---

## Subprocess (List Form)

```python
subprocess.run(["git", "status"], capture_output=True, text=True, encoding="utf-8")
subprocess.run(["uv", "run", "-m", "unittest"], check=True)
```

---

## Code Review Checklist

- [ ] All file operations use `pathlib.Path`
- [ ] All file I/O specifies `encoding="utf-8"`
- [ ] Temp files use context managers
- [ ] No `shell=True` in subprocess
- [ ] No hard-coded path separators

# Test Policy (canonical)

> **Flag defects, never excuse them.** If a test reveals a defect in code, config, or test infrastructure — flag it as a defect. Never rationalize a failing or skipped test as "pre-existing" or "not in scope". Fix it or file a GHI.

- Use **stdlib `unittest`**; no pytest.
- Prefer **table-driven** tests with deterministic seeds; no network/external services.
- **Smoke/BVT <=60s**; cover current-scope surfaces only.
- Fixtures: local, small, reproducible; avoid huge goldens.
- **Database isolation**: Unit tests MUST use `tempfile` temp DBs; NEVER use live/production databases.

## DB Isolation (Django-like philosophy)

- Never touch live/production DBs from tests.
- Prefer shared in-memory SQLite DB for speed and isolation.
- Always pass `sqlite_path`/`db_path` to functions under test.

## Cross-Platform Test Cleanup (Windows-Critical)

**BINDING RULE:** Never use raw `shutil.rmtree()` in test tearDown.

### Pattern 1: Context Manager (Preferred)

```python
class TestSomething(unittest.TestCase):
    def test_with_temp_dir(self):
        with tempfile.TemporaryDirectory() as temp_dir:
            test_file = Path(temp_dir) / "data.json"
            test_file.write_text("{}")
            result = process_dir(temp_dir)
            self.assertEqual(result, expected)
```

## Coverage Floor

- **Minimum line coverage: 40.00%**
- Before closing any brief, verify coverage has not regressed.

## Run

- `uv run ruff check . --fix && uv run ruff format .`
- `uv run -m unittest -v`

## Verify

- All tests PASS; smoke suite <=60s.
- Coverage >=40.00%.
