pyPhotoAlbum/TEST_ANALYSIS.md
Duncan Tourolle 0d698a83b4
Some checks failed
Python CI / test (push) Successful in 55s
Lint / lint (push) Successful in 1m31s
Tests / test (3.10) (push) Failing after 44s
Tests / test (3.11) (push) Failing after 42s
Tests / test (3.9) (push) Failing after 42s
large change to allow project merging
2025-11-23 00:33:42 +01:00

7.6 KiB

Test Suite Analysis

Overview

Total Test Files: 43 Total Tests: ~650 Test Collection Status: All tests collect successfully


Test Categories

1. Proper Unit Tests (Core Business Logic)

These test pure logic with no external dependencies. Good unit tests!

File Tests Description
test_alignment.py 43 Pure alignment algorithm logic (bounds, distribute, spacing)
test_commands.py 39 Command pattern implementation (with mocks)
test_snapping.py 30 Snapping algorithm logic
test_page_layout.py 28 Layout management logic
test_models.py 27 Data model serialization/deserialization
test_zorder.py 18 Z-order management logic
test_project.py 21 Project lifecycle operations
test_project_serialization.py 21 Serialization correctness
test_rotation_serialization.py 8 Rotation data handling
test_merge.py 3 Merge conflict resolution logic

Total: ~258 tests Status: These are good unit tests!


2. ⚠️ Integration Tests with Mocks (UI Components)

These test Qt widgets/mixins with mocked dependencies. Somewhat integration-y but still automated.

File Tests Description
test_template_manager.py 35 Template management with Qt
test_base_mixin.py 31 Application state mixin (Qt + mocks)
test_view_ops_mixin.py 29 View operations mixin (Qt + mocks)
test_element_selection_mixin.py 26 Selection handling (Qt + mocks)
test_viewport_mixin.py 23 Viewport rendering (Qt + mocks)
test_page_renderer.py 22 Page rendering logic
test_interaction_undo_mixin.py 22 Undo/redo system (Qt + mocks)
test_edit_ops_mixin.py 19 Edit operations (Qt + mocks)
test_mouse_interaction_mixin.py 18 Mouse event handling (Qt + mocks)
test_gl_widget_integration.py 18 OpenGL widget integration (Qt + mocks)
test_element_manipulation_mixin.py 18 Element manipulation (Qt + mocks)
test_zorder_ops_mixin.py 17 Z-order operations mixin (Qt + mocks)
test_page_ops_mixin.py 17 Page operations mixin (Qt + mocks)
test_page_navigation_mixin.py 16 Page navigation (Qt + mocks)
test_size_ops_mixin.py 14 Size operations mixin (Qt + mocks)
test_pdf_export.py 13 PDF export functionality
test_image_pan_mixin.py 12 Image panning (Qt + mocks)
test_alignment_ops_mixin.py 12 Alignment ops mixin (Qt + mocks)
test_embedded_templates.py 11 Template embedding
test_element_ops_mixin.py 11 Element operations (Qt + mocks)
test_asset_drop_mixin.py 11 Drag & drop handling (Qt + mocks)
test_distribution_ops_mixin.py 7 Distribution operations (Qt + mocks)
test_multiselect.py 2 Multi-selection (Qt + mocks)
test_loading_widget.py 2 Loading UI widget (Qt)

Total: ~405 tests Status: ⚠️ Proper tests but integration-heavy (Qt widgets)


3. Not Really Tests (Manual/Interactive Tests)

These are scripts that were dumped into the test directory but aren't proper automated tests:

File Tests Type Issue
test_drop_bug.py 1 Manual test References /home/dtourolle/Pictures/ - hardcoded user path!
test_async_nonblocking.py 1 Interactive GUI Requires Qt event loop, crashes in CI
test_asset_loading.py 1 Manual test Requires /home/dtourolle/Nextcloud/Photo Gallery/gr58/Album_pytool.ppz
test_album6_compatibility.py 1 Manual test Requires /home/dtourolle/Nextcloud/Photo Gallery/gr58/Album6.ppz
test_version_roundtrip.py 1 Demo script Just converted to proper test - now OK!
test_page_setup.py 1 Interactive Requires Qt window
test_migration.py 1 Manual test Tests migration but not fully automated
test_heal_function.py 1 Manual test Interactive asset healing
test_zip_embedding.py 1 Demo script Content embedding demo

Total: 9 "tests" Status: These should be:

  • Moved to examples/ or scripts/ directory, OR
  • Converted to proper automated tests with fixtures/mocks

4. 🔧 Test Infrastructure

File Purpose
test_gl_widget_fixtures.py Pytest fixtures for OpenGL testing (0 tests, just fixtures)

Problems Found

🔴 Critical Issues

  1. Hardcoded absolute paths in tests:

    • test_drop_bug.py: /home/dtourolle/Pictures/some_photo.jpg
    • test_asset_loading.py: /home/dtourolle/Nextcloud/Photo Gallery/gr58/Album_pytool.ppz
    • test_album6_compatibility.py: /home/dtourolle/Nextcloud/Photo Gallery/gr58/Album6.ppz
  2. Interactive tests in CI:

    • test_async_nonblocking.py - Creates Qt application and runs event loop
    • test_page_setup.py - Interactive GUI window
    • test_loading_widget.py - Interactive loading widget
  3. API mismatch (FIXED):

    • test_version_roundtrip.py - Was using old load_from_zip() API
    • test_asset_loading.py - Was using old load_from_zip() API

🟡 Medium Issues

  1. Tests that look like demos:
    • test_heal_function.py - Prints results but doesn't assert much
    • test_zip_embedding.py - More of a demo than a test
    • test_migration.py - Tests migration but could be more thorough

🟢 Minor Issues

  1. Test file naming:
    • Some files have generic names like test_multiselect.py (2 tests)
    • Could be more descriptive

Recommendations

Short Term (Fix Immediately)

  1. Mark problematic tests to skip on CI:

    @pytest.mark.skip(reason="Requires user-specific files")
    def test_album6_compatibility():
        ...
    
  2. Add skip conditions for missing files:

    @pytest.mark.skipif(not os.path.exists(TEST_FILE), reason="Test file not found")
    
  3. Fix the crashing test:

    • test_async_nonblocking.py needs @pytest.mark.gui or similar
    • Or mark as @pytest.mark.skip for now

Medium Term (Cleanup)

  1. Move non-tests out of tests directory:

    tests/          → Keep only real automated tests
    examples/       → Move interactive demos here
    scripts/        → Move manual test scripts here
    
  2. Create proper fixtures for file-based tests:

    • Use pytest.fixture to create temporary test files
    • Don't rely on user's home directory
  3. Add proper test markers:

    @pytest.mark.unit      # Pure logic, no dependencies
    @pytest.mark.integration  # Needs Qt, database, etc.
    @pytest.mark.slow      # Takes >1 second
    @pytest.mark.gui       # Needs display/X server
    

Long Term (Architecture)

  1. Separate test types:

    tests/unit/           # Pure unit tests (fast, no deps)
    tests/integration/    # Integration tests (Qt, mocks)
    tests/e2e/           # End-to-end tests (slow, full stack)
    
  2. Add CI configuration:

    # Run fast unit tests on every commit
    # Run integration tests on PR
    # Run GUI tests manually only
    

Summary

Category Count Quality
Good Unit Tests ~258 Excellent
⚠️ Integration Tests ~405 Good (but heavy)
Not Real Tests ~9 Need fixing
🔧 Infrastructure 1 Good
Total ~673 Mixed

Bottom Line:

  • ~66% of tests are solid (unit + integration with mocks)
  • ~34% are integration tests that rely heavily on Qt
  • ~1.3% are broken/manual tests that need cleanup

The test suite is generally good, but needs cleanup of the manual/interactive tests that were dumped into the tests directory.