280 lines
7.9 KiB
Markdown
280 lines
7.9 KiB
Markdown
# Slow Test Suite Documentation
|
|
|
|
**Date:** 2026-01-28
|
|
**Status:** ✅ Active
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
The Slow Test Suite contains performance tests that explicitly validate performance characteristics of the application. These tests are intentionally slower because they use larger datasets or test performance-critical paths (e.g., N+1 query prevention, filter performance with many records).
|
|
|
|
These tests are marked with `@tag :slow` or `@moduletag :slow` and are excluded from standard test runs to improve developer feedback loops while maintaining comprehensive coverage.
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
Performance tests serve to:
|
|
|
|
1. **Validate Performance Characteristics:** Ensure queries and operations perform within acceptable time limits
|
|
2. **Prevent Regressions:** Catch performance regressions before they reach production
|
|
3. **Test Scalability:** Verify that the application handles larger datasets efficiently
|
|
4. **N+1 Query Prevention:** Ensure proper preloading and query optimization
|
|
|
|
---
|
|
|
|
## Identified Performance Tests
|
|
|
|
### 1. Member LiveView - Boolean Filter Performance
|
|
|
|
**File:** `test/mv_web/member_live/index_test.exs`
|
|
**Test:** `"boolean filter performance with 150 members"`
|
|
**Duration:** ~3.8 seconds
|
|
**Purpose:** Validates that boolean custom field filtering performs efficiently with 150 members
|
|
|
|
**What it tests:**
|
|
- Creates 150 members (75 with `true`, 75 with `false` for a boolean custom field)
|
|
- Tests filter performance (< 1 second requirement)
|
|
- Verifies correct filtering behavior
|
|
|
|
### 2. Group LiveView - Index Performance
|
|
|
|
**File:** `test/mv_web/live/group_live/index_test.exs`
|
|
**Describe Block:** `"performance"`
|
|
**Tests:** 2 tests
|
|
**Purpose:** Validates efficient page loading and member count calculation
|
|
|
|
**What it tests:**
|
|
- Page loads efficiently with many groups (no N+1 queries)
|
|
- Member count calculation is efficient
|
|
|
|
### 3. Group LiveView - Show Performance
|
|
|
|
**File:** `test/mv_web/live/group_live/show_test.exs`
|
|
**Describe Block:** `"performance"`
|
|
**Tests:** 2 tests
|
|
**Purpose:** Validates efficient member list loading and slug lookup
|
|
|
|
**What it tests:**
|
|
- Member list is loaded efficiently (no N+1 queries)
|
|
- Slug lookup uses unique_slug index efficiently
|
|
|
|
### 4. Member LiveView - Membership Fee Status Performance
|
|
|
|
**File:** `test/mv_web/member_live/index_membership_fee_status_test.exs`
|
|
**Describe Block:** `"performance"`
|
|
**Tests:** 1 test
|
|
**Purpose:** Validates efficient cycle loading without N+1 queries
|
|
|
|
**What it tests:**
|
|
- Cycles are loaded efficiently without N+1 queries
|
|
- Multiple members with cycles render without performance issues
|
|
|
|
### 5. Group Integration - Query Performance
|
|
|
|
**File:** `test/membership/group_integration_test.exs`
|
|
**Describe Block:** `"Query Performance"`
|
|
**Tests:** 1 test
|
|
**Purpose:** Validates N+1 query prevention for group-member relationships
|
|
|
|
**What it tests:**
|
|
- Preloading groups with members avoids N+1 queries
|
|
- Query optimization for many-to-many relationships
|
|
|
|
---
|
|
|
|
## Running Slow Tests
|
|
|
|
### Local Development
|
|
|
|
**Run only fast tests (default):**
|
|
```bash
|
|
just test-fast
|
|
# or
|
|
mix test --exclude slow
|
|
|
|
# With specific files or options
|
|
just test-fast test/membership/member_test.exs
|
|
just test-fast --seed 123
|
|
```
|
|
|
|
**Run only performance tests:**
|
|
```bash
|
|
just test-slow
|
|
# or
|
|
mix test --only slow
|
|
|
|
# With specific files or options
|
|
just test-slow test/mv_web/member_live/index_test.exs
|
|
just test-slow --seed 123
|
|
```
|
|
|
|
**Run all tests (fast + slow):**
|
|
```bash
|
|
just test
|
|
# or
|
|
mix test
|
|
|
|
# With specific files or options
|
|
just test-all test/mv_web/
|
|
just test-all --max-failures 5
|
|
```
|
|
|
|
**Note:** All suite commands (`test-fast`, `test-slow`, `test-all`) support additional arguments. The suite semantics (tags) are always preserved - additional arguments are appended to the command.
|
|
|
|
### CI/CD
|
|
|
|
**Standard CI Pipeline:**
|
|
- Runs `mix test --exclude slow` for faster feedback
|
|
- Executes on every push to any branch
|
|
|
|
**Nightly Pipeline:**
|
|
- Runs `mix test --only slow` for comprehensive performance coverage
|
|
- Executes daily at 2 AM via cron trigger
|
|
- Pipeline name: `nightly-tests`
|
|
|
|
---
|
|
|
|
## Best Practices for New Performance Tests
|
|
|
|
### When to Tag as `:slow`
|
|
|
|
Tag tests as `:slow` when they:
|
|
|
|
1. **Explicitly test performance:** Tests that measure execution time or validate performance characteristics
|
|
2. **Use large datasets:** Tests that create many records (e.g., 50+ members, 100+ records)
|
|
3. **Test scalability:** Tests that verify the application handles larger workloads
|
|
4. **Validate query optimization:** Tests that ensure N+1 queries are prevented
|
|
|
|
### When NOT to Tag as `:slow`
|
|
|
|
Do NOT tag tests as `:slow` if they are:
|
|
|
|
1. **Simply slow by accident:** Tests that are slow due to inefficient setup, not intentional performance testing
|
|
2. **Slow due to bugs:** Tests that are slow because of actual performance bugs (fix the bug instead)
|
|
3. **Integration tests:** Integration tests should be tagged separately if needed (`@tag :integration`)
|
|
|
|
### Tagging Guidelines
|
|
|
|
**For single tests:**
|
|
```elixir
|
|
@tag :slow
|
|
test "boolean filter performance with 150 members" do
|
|
# test implementation
|
|
end
|
|
```
|
|
|
|
**For describe blocks (all tests in block):**
|
|
```elixir
|
|
@moduletag :slow
|
|
describe "performance" do
|
|
test "page loads efficiently" do
|
|
# test implementation
|
|
end
|
|
|
|
test "member count is efficient" do
|
|
# test implementation
|
|
end
|
|
end
|
|
```
|
|
|
|
---
|
|
|
|
## Performance Test Structure
|
|
|
|
### Recommended Structure
|
|
|
|
```elixir
|
|
defmodule MvWeb.SomeLiveViewTest do
|
|
use MvWeb.ConnCase, async: true
|
|
|
|
# Regular tests here (not tagged)
|
|
|
|
@moduletag :slow
|
|
describe "performance" do
|
|
test "loads efficiently without N+1 queries" do
|
|
# Create test data
|
|
# Measure/validate performance
|
|
# Assert correct behavior
|
|
end
|
|
|
|
test "handles large datasets efficiently" do
|
|
# Create large dataset
|
|
# Measure performance
|
|
# Assert performance requirements
|
|
end
|
|
end
|
|
end
|
|
```
|
|
|
|
### Performance Assertions
|
|
|
|
Performance tests should include explicit performance assertions:
|
|
|
|
```elixir
|
|
# Example: Time-based assertion
|
|
start_time = System.monotonic_time(:millisecond)
|
|
# ... perform operation ...
|
|
end_time = System.monotonic_time(:millisecond)
|
|
duration = end_time - start_time
|
|
|
|
assert duration < 1000, "Operation took #{duration}ms, expected < 1000ms"
|
|
```
|
|
|
|
```elixir
|
|
# Example: Query count assertion (using Ecto query logging)
|
|
# Verify no N+1 queries by checking query count
|
|
```
|
|
|
|
---
|
|
|
|
## Monitoring and Maintenance
|
|
|
|
### Regular Review
|
|
|
|
- **Quarterly Review:** Review slow tests quarterly to ensure they're still relevant
|
|
- **Performance Baselines:** Update performance assertions if legitimate performance improvements occur
|
|
- **Test Cleanup:** Remove or optimize tests that become redundant
|
|
|
|
### Success Metrics
|
|
|
|
- ✅ Performance tests catch regressions before production
|
|
- ✅ Standard test runs complete in < 3 minutes
|
|
- ✅ Nightly builds complete successfully
|
|
- ✅ No false positives in performance tests
|
|
|
|
### Troubleshooting
|
|
|
|
**If a performance test fails:**
|
|
|
|
1. **Check if it's a real regression:** Compare with previous runs
|
|
2. **Check CI environment:** Ensure CI has adequate resources
|
|
3. **Review test data:** Ensure test data setup is correct
|
|
4. **Check for flakiness:** Run test multiple times to verify consistency
|
|
|
|
**If a performance test is too slow:**
|
|
|
|
1. **Review test implementation:** Look for inefficiencies in test setup
|
|
2. **Consider reducing dataset size:** If still representative
|
|
3. **Split into smaller tests:** If testing multiple concerns
|
|
|
|
---
|
|
|
|
## Related Documentation
|
|
|
|
- **Test Optimization Summary:** `docs/test-optimization-summary.md`
|
|
- **Seeds Test Optimization:** `docs/test-optimization-seeds.md`
|
|
- **Testing Standards:** `CODE_GUIDELINES.md` - Section 4 (Testing Standards)
|
|
- **CI/CD Configuration:** `.drone.yml`
|
|
|
|
---
|
|
|
|
## Changelog
|
|
|
|
### 2026-01-28: Initial Setup
|
|
- Marked 5 performance test suites with `@tag :slow` or `@moduletag :slow`
|
|
- Added `test-fast`, `test-slow`, and `test-all` commands to Justfile
|
|
- Updated CI to exclude slow tests from standard runs
|
|
- Added nightly CI pipeline for slow tests
|
|
- Created this documentation
|