rules-testinglisted
Install: claude install-skill jardisTools/dev-skills
### 1. Principle
Tests assert behaviour at the package boundary, not internal implementation. A refactor that preserves behaviour must not require test changes.
- **Integration** = default. Real dependencies via Docker.
- **Unit** = fallback when the unit has no outside world (VO, pure formatter, parser without I/O).
- Unit test needing 3+ Mocks = bad Integration test in disguise.
### 2. Rules
| Concern | Rule |
|---|---|
| Mapping | `src/Cache/RedisCache.php` → `tests/Integration/Cache/RedisCacheTest.php` |
| Naming | Class `RedisCacheTest`, method `test{Action}{Condition}{ExpectedResult}` |
| Structure | AAA separated, one concept per test |
| Independence | No `setUpBeforeClass` side effects, no static cache, no `@depends` |
| Behaviour | Assert outputs and side effects, never SQL strings or private calls |
| Mocking | Only Contracts (interfaces). Prefer Fakes in `tests/Support/` |
```php
// tests/Support/InMemoryCache.php
final class InMemoryCache implements CacheInterface
{
private array $data = [];
public function get(string $key, mixed $default = null): mixed { return $this->data[$key] ?? $default; }
public function set(string $key, mixed $value, int|null $ttl = null): bool { $this->data[$key] = $value; return true; }
}
```
### 3. Failing-test process
Before changing test or code:
1. What SHOULD happen? Derive from architecture, PRD, Contract.
2. What ACTUALLY happens? Debug output, read involved code.
3. Decide:
- Behaviour correct → adapt test,