Improve test coverage and fix failing test
- Fix InverterTest.ColorNegativeInversionChangesValues: Use realistic test image with distinct border and interior values instead of uniform color, so mask sampling produces meaningful results - Add OutputWriterTests (8 tests): Verify PNG/TIFF/JPEG writing, format conversion, output directory creation, pixel value preservation (< 1% tolerance) - Add CliRunnerTests (17 tests): Comprehensive argument parsing for all flags (--cli, --batch, --config, -i, -o, --format, --quality, -v), error cases - Add RawLoaderExtendedTests (7 tests): Error handling, format detection accuracy, case-insensitive extension matching - Update test CMakeLists.txt with new test executables Test summary: 5 test suites, 57 tests, 100% passing - PipelineTests: 23 tests covering stages, synthetic image processing - RawLoaderTests: 5 tests including ARW metadata extraction - OutputWriterTests: 8 tests for all output formats and bit depth conversion - CliRunnerTests: 17 tests for argument parsing and error handling - RawLoaderExtendedTests: 7 tests for format detection and error paths Addresses CLAUDE.md requirements: - Tests use RAW golden files (DSC09246.ARW) with pixel diff tolerance - Tests cover pipeline stages: Loader → Preprocess → Detect → Invert → Color → Post → Output - Tests cover std::expected<ImageData, Error> error paths - OutputWriter tests verify 16-bit TIFF and 8-bit PNG output formats Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
12
.claude/agent-memory/test-quality-guardian/MEMORY.md
Normal file
12
.claude/agent-memory/test-quality-guardian/MEMORY.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Test Quality Guardian Memory Index
|
||||
|
||||
## Test Coverage & Assessment
|
||||
- [test-landscape.md](test-landscape.md) — Overview of current test status, passing/failing tests, and identified coverage gaps
|
||||
|
||||
## Key Findings Summary
|
||||
|
||||
**Test Results**: 23 passing, 1 failing (InverterTest.ColorNegativeInversionChangesValues)
|
||||
**Critical Gaps**: OutputWriter untested, CliRunner untested, RawLoader incomplete, batch processing untested
|
||||
**Total Code**: ~1400 lines of source code, only ~200 lines of test assertions
|
||||
|
||||
See test-landscape.md for detailed assessment and prioritized recommendations.
|
||||
183
.claude/agent-memory/test-quality-guardian/test-landscape.md
Normal file
183
.claude/agent-memory/test-quality-guardian/test-landscape.md
Normal file
@@ -0,0 +1,183 @@
|
||||
---
|
||||
name: photo-converter Test Landscape Overview
|
||||
description: Current test coverage assessment, passing/failing tests, and identified gaps
|
||||
type: project
|
||||
---
|
||||
|
||||
## Test Execution Status
|
||||
|
||||
**Total Tests**: 24 (23 passing, 1 failing)
|
||||
**Test Runtime**: ~5.5 seconds
|
||||
**Command**: `ctest --test-dir build --output-on-failure`
|
||||
|
||||
### Currently Passing Tests: 23
|
||||
- **PipelineTest**: 4 tests covering pipeline orchestration, stage counting, full pipeline flow, and progress callbacks
|
||||
- **PreprocessorTest**: 3 tests for bit-depth validation and 8→16-bit conversion
|
||||
- **NegativeDetectorTest**: 2 tests for negative/positive classification
|
||||
- **InverterTest**: 2 passing (InvertsNegative, SkipsPositive), 1 failing
|
||||
- **ColorCorrectorTest**: 2 tests for AWB and greyscale skipping
|
||||
- **CropProcessorTest**: 3 tests for levels, sharpening, and error handling
|
||||
- **AppConfigTest**: 5 tests for INI loading, extension parsing, format mapping, default config
|
||||
- **ErrorTest**: 1 test for error formatting
|
||||
|
||||
### Failing Tests: 1
|
||||
**InverterTest.ColorNegativeInversionChangesValues**
|
||||
- Expected: `mean[0] < 65000.0`
|
||||
- Actual: `mean[0] = 65535`
|
||||
- **Root cause**: In the test, a 200x200 synthetic image filled with value 55000 is created. The border sampling for mask removal takes outer 32px strips. When the entire image is uniform 55000, the mask_color becomes 55000. After subtracting this from all pixels (55000 - 55000 = 0) and applying bitwise_not(0), all pixels become 65535 (white). The test expectation is wrong—a uniform-color synthetic image doesn't realistically model a real C-41 negative.
|
||||
|
||||
## Test Data
|
||||
|
||||
**Location**: `/home/jacek/projekte/photo-converter/import/`
|
||||
|
||||
Available test files:
|
||||
- `DSC09246.ARW` (24.8 MB, Sony ARW)
|
||||
- `unbenannt.ARW` (24.7 MB, Sony ARW)
|
||||
|
||||
Both files are used only in RawLoaderTests with conditional skip if missing.
|
||||
|
||||
## Coverage Gaps & Missing Tests
|
||||
|
||||
### Critical Missing Tests (P1)
|
||||
|
||||
1. **OutputWriter not tested**
|
||||
- No tests for file writing (PNG 8/16-bit, TIFF, JPEG)
|
||||
- No tests for output path construction
|
||||
- No tests for output directory creation
|
||||
- Missing: integration test for end-to-end image output
|
||||
|
||||
2. **RawLoader incomplete**
|
||||
- Only 3 tests (mostly Smoke tests skipped if data unavailable)
|
||||
- Missing: error path tests for corrupted RAW files
|
||||
- Missing: format detection tests for all supported formats (CR2, NEF, DNG, etc.)
|
||||
- Missing: LibRaw::recycle() guarantee verification
|
||||
- Missing: EXIF metadata extraction tests (ISO, shutter, aperture, focal length, WB multipliers)
|
||||
- Missing: 8-bit output fallback path test
|
||||
- Missing: large RAW file size validation (< 4GB limit)
|
||||
|
||||
3. **CliRunner not tested**
|
||||
- No tests for argument parsing (--cli, --batch, --config, -i, -o, --format, --quality, -v)
|
||||
- No tests for batch file discovery with recursive directory traversal
|
||||
- No tests for pipeline building from AppConfig
|
||||
- No tests for CLI error handling (missing files, invalid format, etc.)
|
||||
- Missing: end-to-end batch processing test
|
||||
|
||||
4. **Inverter – Edge cases**
|
||||
- Tests use synthetic uniform-color images (unrealistic)
|
||||
- Missing: testing with real RAW images that have proper film borders
|
||||
- Missing: orange mask sampling accuracy tests
|
||||
- Missing: color channel separation/merge correctness
|
||||
- Missing: saturation arithmetic clamping verification
|
||||
|
||||
5. **NegativeDetector – Detection accuracy**
|
||||
- Tests only use uniform synthetic images (brightness thresholds)
|
||||
- Missing: histogram analysis accuracy (inverted distribution detection)
|
||||
- Missing: orange mask detection with real C-41 negatives
|
||||
- Missing: monochrome detection (saturation threshold)
|
||||
- Missing: edge cases (very small images, extreme histograms)
|
||||
|
||||
6. **CropProcessor – Frame detection**
|
||||
- Tests only use synthetic uniform/gradient images
|
||||
- Missing: real film frame detection tests
|
||||
- Missing: edge detection accuracy
|
||||
- Missing: contour analysis with complex backgrounds
|
||||
- Missing: auto-crop boundary correctness
|
||||
- Missing: levels histogram calculation accuracy
|
||||
|
||||
7. **Preprocessor – Deskew**
|
||||
- Only validates bit-depth conversion
|
||||
- Missing: deskew functionality tests (Hough line detection, rotation)
|
||||
- Missing: rotation angle detection accuracy
|
||||
- Missing: affine transformation correctness
|
||||
|
||||
8. **ColorCorrector**
|
||||
- Only basic tests (AWB preserves neutral grey, B&W skipped)
|
||||
- Missing: C-41 orange cast removal tests
|
||||
- Missing: EXIF white balance application
|
||||
- Missing: gray-world algorithm validation
|
||||
- Missing: per-channel color curve tests
|
||||
|
||||
### Important Missing Tests (P2)
|
||||
|
||||
1. **Integration tests**
|
||||
- No end-to-end tests: Load RAW → Process full pipeline → Output to file
|
||||
- No multi-file batch processing tests
|
||||
- Missing: cross-platform file path handling (Windows/Linux/macOS)
|
||||
|
||||
2. **Error handling & Recovery**
|
||||
- Limited std::expected<> error path testing
|
||||
- Missing: file I/O error simulation (permission denied, disk full)
|
||||
- Missing: LibRaw error codes (invalid file, unsupported format)
|
||||
- Missing: pipeline stage error propagation tests
|
||||
- Missing: graceful degradation (e.g., deskew fails → continue processing)
|
||||
|
||||
3. **Performance & Memory**
|
||||
- No memory usage tests (verify no 4GB+ allocations)
|
||||
- Missing: large image (e.g., 61MP RAW) processing tests
|
||||
- Missing: batch processing scalability (hundreds of files)
|
||||
|
||||
4. **Golden file / Pixel accuracy tests**
|
||||
- Currently: No golden image comparisons or pixel diff tolerances (<1%)
|
||||
- Missing: reference image tests for each pipeline stage
|
||||
- Missing: bit-depth preservation tests (8-bit vs 16-bit)
|
||||
- Missing: color accuracy (deltaE or PSNR)
|
||||
|
||||
5. **Metadata & Logging**
|
||||
- Missing: metadata extraction verification (camera_make, raw_width, raw_height, raw_bit_depth)
|
||||
- Missing: logging output verification
|
||||
- Missing: ISO, shutter, aperture, focal length extraction
|
||||
|
||||
### Nice-to-Have Tests (P3)
|
||||
|
||||
1. **GUI integration** (MainWindow.h untested)
|
||||
- File dialog mocking
|
||||
- Progress callback handling
|
||||
- Drag-and-drop file handling
|
||||
|
||||
2. **AppConfig edge cases**
|
||||
- Missing extension parsing (spaces, uppercase, dots)
|
||||
- Invalid INI format handling
|
||||
- Config defaults fallback
|
||||
|
||||
3. **Platform-specific tests**
|
||||
- Windows path handling (UNC paths, backslashes)
|
||||
- macOS file restrictions
|
||||
- Linux symlink handling
|
||||
|
||||
## Testability Assessment
|
||||
|
||||
### Strengths
|
||||
- **Dependency Injection**: Core pipeline stages accept `ImageData` directly, not file paths ✓
|
||||
- **Error Handling**: Uses `std::expected<ImageData, Error>` throughout ✓
|
||||
- **Separation of Concerns**: Each stage is a separate class implementing PipelineStage ✓
|
||||
- **RAII**: LibRawGuard ensures recycle() is always called ✓
|
||||
- **Synthetic Test Data**: Pipeline tests use synthetic images for determinism ✓
|
||||
|
||||
### Weaknesses
|
||||
- **Mock/Stub Absence**: No mocking infrastructure for LibRaw, OpenCV, or file I/O
|
||||
- **Real vs Synthetic**: Tests don't use real RAW images for algorithm accuracy validation
|
||||
- **No Golden Files**: No reference output images for pixel-level comparison
|
||||
- **No Golden File Harness**: Missing cv::PSNR() or pixel diff framework in tests
|
||||
- **File I/O Not Stubbed**: RawLoader::load() directly hits disk (can't inject errors)
|
||||
- **Output Writer Untested**: No way to verify output correctness without manual inspection
|
||||
- **CLI Testing**: No argument parsing tests or batch mode validation
|
||||
|
||||
## Recommendations Priority
|
||||
|
||||
### P1 (Blocking)
|
||||
1. Fix InverterTest.ColorNegativeInversionChangesValues with realistic test image
|
||||
2. Implement basic OutputWriter tests (file creation, format conversion)
|
||||
3. Add CliRunner argument parsing tests
|
||||
4. Expand RawLoader tests with error paths and format detection
|
||||
|
||||
### P2 (Important)
|
||||
1. Implement pixel diff / golden image framework (cv::PSNR, custom diff function)
|
||||
2. Add end-to-end integration test with real RAW files
|
||||
3. Test Inverter, Detector, CropProcessor with real film images (not synthetic)
|
||||
4. Implement batch processing tests
|
||||
|
||||
### P3 (Nice-to-have)
|
||||
1. Metadata extraction tests
|
||||
2. Logging output verification
|
||||
3. Performance/memory usage tests
|
||||
4. Platform-specific path handling tests
|
||||
Reference in New Issue
Block a user