Skip to content

Add --shuffle and --seed options for randomizing test execution order#531

Merged
tclune merged 8 commits intodevelopfrom
feature/530-shuffle-tests
Mar 10, 2026
Merged

Add --shuffle and --seed options for randomizing test execution order#531
tclune merged 8 commits intodevelopfrom
feature/530-shuffle-tests

Conversation

@tclune
Copy link
Copy Markdown
Member

@tclune tclune commented Mar 10, 2026

Summary

Implements #530: Add command-line options to randomize test execution order within each test suite to help detect hidden test dependencies.

Changes

Core Implementation:

  • Add --shuffle flag to enable random test ordering
  • Add --seed=N option to specify random seed (0=time-based, implies --shuffle)
  • Implement Fisher-Yates shuffle algorithm in TestSuite
  • Tests are shuffled within each suite, preserving suite boundaries

Modified Files:

  • src/funit/core/TestSuite.F90: Added shuffle functionality with set_shuffle() and shuffle_tests() methods
  • src/funit/FUnit.F90: Added CLI argument parsing for --shuffle and --seed options

New Tests:

  • tests/funit-core/Test_TestSuite_Shuffle.F90: Comprehensive unit tests (6 test cases)
    • Deterministic order without shuffle
    • Reproducibility with same seed
    • Shuffle actually changes order
    • Edge cases (empty suite, single test)
    • Suite boundary preservation
  • tests/funit-core/ShuffleIntegrationTests.pf: Integration test suite
  • tests/funit-core/test_shuffle.sh: Shell script for command-line testing

Testing

All tests pass:

  • ✅ 82 unit tests (including 6 new shuffle tests)
  • ✅ 6/6 integration test scenarios
  • ✅ No regressions in existing tests

Usage Examples

# Run tests with random order (time-based seed)
./my_tests.x --shuffle

# Run tests with specific seed for reproducibility
./my_tests.x --seed=12345

# Verify reproducibility
./my_tests.x --seed=12345  # Run 1
./my_tests.x --seed=12345  # Run 2 - same order as Run 1

Implements issue #530: Add command-line options to randomize test execution
order within each test suite to help detect hidden test dependencies.

Changes:
- Add --shuffle flag to enable random test ordering
- Add --seed=N option to specify random seed (0=time-based, implies --shuffle)
- Implement Fisher-Yates shuffle algorithm in TestSuite
- Tests are shuffled within each suite, preserving suite boundaries
- Add comprehensive unit tests (Test_TestSuite_Shuffle.F90)
- Add integration tests (ShuffleIntegrationTests.pf, test_shuffle.sh)

All tests pass, including reproducibility with same seed and verification
that shuffle actually changes test order.
@tclune tclune changed the base branch from main to develop March 10, 2026 14:24
tclune added 7 commits March 10, 2026 10:29
Extract helper subroutines to improve code readability:
- initialize_random_seed(): Handles seed initialization logic
- swap_tests(): Encapsulates test swapping with move_alloc

This reduces maximum nesting level from 4 to 2 and makes
each subroutine have a single, clear responsibility.
Replace complex array-based shuffling with simpler index-based approach:
- Shuffle integer indices array instead of Test objects
- Build new vector by accessing tests in shuffled index order
- Eliminates TestReference type, temp array allocations, and swap_tests()

This is cleaner, more efficient (no polymorphic object copying), and
easier to understand.
- Use array constructor indices = [(i, i=1, n)] instead of explicit loop
- Remove superfluous explicit deallocate() for allocatable arrays
- Eliminate else clause by setting default seed_array first
- Replace magic number 1000 with 997 (prime) and add explanatory comment
When user_seed==0, just use Fortran's default random_seed()
initialization instead of manually constructing a time-based seed.
The compiler's default is perfectly adequate for non-reproducible
randomization.
@tclune tclune requested a review from mathomp4 March 10, 2026 14:46
@tclune tclune merged commit 7384c67 into develop Mar 10, 2026
16 checks passed
@tclune tclune deleted the feature/530-shuffle-tests branch March 10, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants