* test(doctor): add comprehensive tests for fix and check functions Add edge case tests, e2e tests, and improve test coverage for: - database_test.go: database integrity and sync checks - git_test.go: git hooks, merge driver, sync branch tests - gitignore_test.go: gitignore validation - prefix_test.go: ID prefix handling - fix/fix_test.go: fix operations - fix/e2e_test.go: end-to-end fix scenarios - fix/fix_edge_cases_test.go: edge case handling * docs: add testing philosophy and anti-patterns guide - Create TESTING_PHILOSOPHY.md covering test pyramid, priority matrix, what NOT to test, and 5 anti-patterns with code examples - Add cross-reference from README_TESTING.md - Document beads-specific guidance (well-covered areas vs gaps) - Include target metrics (test-to-code ratio, execution time targets) * chore: revert .beads/ to upstream/main state * refactor(doctor): add category grouping and Ayu theme colors - Add Category field to DoctorCheck for organizing checks by type - Define category constants: Core, Git, Runtime, Data, Integration, Metadata - Update thanks command to use shared Ayu color palette from internal/ui - Simplify test fixtures by removing redundant test cases * fix(doctor): prevent test fork bomb and fix test failures - Add ErrTestBinary guard in getBdBinary() to prevent tests from recursively executing the test binary when calling bd subcommands - Update claude_test.go to use new check names (CLI Availability, Prime Documentation) - Fix syncbranch test path comparison by resolving symlinks (/var vs /private/var on macOS) - Fix permissions check to use exact comparison instead of bitmask - Fix UntrackedJSONL to use git commit --only to preserve staged changes - Fix MergeDriver edge case test by making both .git dir and config read-only - Add skipIfTestBinary helper for E2E tests that need real bd binary * test(doctor): skip read-only config test in CI environments GitHub Actions containers may have CAP_DAC_OVERRIDE or similar capabilities that allow writing to read-only files, causing the test to fail. Skip the test when CI=true or GITHUB_ACTIONS=true.
110 lines
2.4 KiB
Markdown
110 lines
2.4 KiB
Markdown
# Testing Strategy
|
|
|
|
This project uses a two-tier testing approach to balance speed and thoroughness.
|
|
|
|
> **Testing Philosophy**: For guidance on what to test, anti-patterns to avoid, and target metrics, see [TESTING_PHILOSOPHY.md](TESTING_PHILOSOPHY.md).
|
|
|
|
## Test Categories
|
|
|
|
### Fast Tests (Unit Tests)
|
|
- Run on every commit and PR
|
|
- Complete in ~2 seconds
|
|
- No build tags required
|
|
- Located throughout the codebase
|
|
|
|
```bash
|
|
go test -short ./...
|
|
```
|
|
|
|
### Integration Tests
|
|
- Marked with `//go:build integration` tag
|
|
- Include slow git operations and multi-clone scenarios
|
|
- Run nightly and before releases
|
|
- Located in:
|
|
- `beads_hash_multiclone_test.go` - Multi-clone convergence tests (~13s)
|
|
- `beads_integration_test.go` - End-to-end scenarios
|
|
- `beads_multidb_test.go` - Multi-database tests
|
|
|
|
```bash
|
|
go test -tags=integration ./...
|
|
```
|
|
|
|
## CI Strategy
|
|
|
|
**PR Checks** (fast, runs on every PR):
|
|
```bash
|
|
go test -short -race ./...
|
|
```
|
|
|
|
**Nightly** (comprehensive, runs overnight):
|
|
```bash
|
|
go test -tags=integration -race ./...
|
|
```
|
|
|
|
## Adding New Tests
|
|
|
|
### For Fast Tests
|
|
No special setup required. Just write the test normally.
|
|
|
|
### For Integration Tests
|
|
Add build tags at the top of the file:
|
|
|
|
```go
|
|
//go:build integration
|
|
// +build integration
|
|
|
|
package yourpackage_test
|
|
```
|
|
|
|
Mark slow operations with `testing.Short()` check:
|
|
|
|
```go
|
|
func TestSomethingSlow(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skipping integration test")
|
|
}
|
|
// ... slow test code
|
|
}
|
|
```
|
|
|
|
## Local Development
|
|
|
|
During development, run fast tests frequently:
|
|
```bash
|
|
go test -short ./...
|
|
```
|
|
|
|
Before committing, run full suite:
|
|
```bash
|
|
go test -tags=integration ./...
|
|
```
|
|
|
|
## Performance Optimization
|
|
|
|
### In-Memory Filesystems for Git Tests
|
|
|
|
Git-heavy integration tests use `testutil.TempDirInMemory()` to reduce I/O overhead:
|
|
|
|
```go
|
|
import "github.com/steveyegge/beads/internal/testutil"
|
|
|
|
func TestWithGitOps(t *testing.T) {
|
|
tmpDir := testutil.TempDirInMemory(t)
|
|
// ... test code using tmpDir
|
|
}
|
|
```
|
|
|
|
**Platform behavior:**
|
|
- **Linux**: Uses `/dev/shm` (tmpfs ramdisk) if available - provides 20-30% speedup
|
|
- **macOS**: Uses standard `/tmp` (APFS is already fast)
|
|
- **Windows**: Uses standard temp directory
|
|
|
|
**For CI (GitHub Actions):**
|
|
Linux runners automatically have `/dev/shm` available, so no configuration needed.
|
|
|
|
## Performance Targets
|
|
|
|
- **Fast tests**: < 3 seconds total
|
|
- **Integration tests**: < 15 seconds total
|
|
- **Full suite**: < 18 seconds total
|