Files
negative-converter/.claude/agent-memory/test-quality-guardian/test-landscape.md
Christoph K. 3f0cf5a0fa 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>
2026-03-14 09:58:53 +01:00

184 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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