Skip to content

Parameterized Test Cases for User Output #128

Description

@josecelano

Overview

Refactor the UserOutput test suite to use parameterized tests with rstest, eliminating significant code duplication. Currently, many tests are nearly identical, differing only in the method called, expected symbol, verbosity level, and output channel. By using parameterized tests, we can express the same behavior matrix with much less code while maintaining clarity and improving maintainability.

Current State: The codebase already has simplified test infrastructure (Issue #123) with TestUserOutput helper, providing the foundation for this refactoring.

Specification

See detailed specification: docs/issues/128-parameterized-test-cases.md

(Link will be updated after issue number assignment and file rename)

🏗️ Architecture Requirements

DDD Layer: Presentation (Tests)
Module Path: src/presentation/user_output.rs (test module)
Pattern: Parameterized unit tests with rstest

Key Changes

  • Add rstest dependency to Cargo.toml dev-dependencies
  • Create parameterized tests for channel routing (stdout vs stderr)
  • Create parameterized tests for verbosity level behavior
  • Create parameterized tests for message formatting
  • Remove duplicate test methods
  • Maintain or improve test coverage

Implementation Plan

Phase 1: Setup and Dependencies (30 minutes)

  • Add rstest = "0.18" to dev-dependencies
  • Verify rstest works with simple test case

Phase 2: Identify Test Patterns (1 hour)

  • Analyze existing tests to identify duplication patterns
  • Document the test matrix (what combinations need coverage)

Phase 3: Create Parameterized Channel Routing Tests (2 hours)

  • Write parameterized test for all message types
  • Verify all cases pass

Phase 4: Create Parameterized Verbosity Tests (2 hours)

  • Write parameterized verbosity tests for normal messages
  • Write tests for error messages (always shown)
  • Verify all verbosity combinations are covered

Phase 5: Create Parameterized Formatting Tests (1 hour)

  • Write parameterized formatting test
  • Add test cases for all symbols

Phase 6: Remove Duplicate Tests (1 hour)

  • Identify tests covered by parameterized tests
  • Remove duplicate test methods
  • Keep unique tests not covered by parameterization

Phase 7: Validation and Documentation (1 hour)

  • Run full test suite
  • Check test coverage hasn't decreased
  • Document the test matrix

Phase 8: Integration Testing (30 minutes)

  • Run pre-commit checks
  • Run all E2E tests

Estimated Total Time: ~8.5 hours

Acceptance Criteria

Quality Checks:

  • Pre-commit checks pass: ./scripts/pre-commit.sh

Task-Specific Criteria:

  • rstest dependency is added to dev-dependencies
  • Parameterized tests exist for channel routing (stdout vs stderr)
  • Parameterized tests exist for verbosity level behavior
  • Parameterized tests exist for message formatting
  • Duplicate test methods have been removed
  • Test coverage is maintained or improved (verify with cargo llvm-cov)
  • All tests pass without failures
  • Test matrix is documented in code comments
  • Code is more maintainable (less duplication, clearer intent)

Coverage Requirements:

  • All message types are covered (progress, success, warning, error, result, steps)
  • All verbosity levels are tested (Quiet, Normal, Verbose)
  • Both output channels are tested (stdout, stderr)
  • All message symbols are verified

Related

Benefits

✅ Reduced Duplication - one test implementation covers multiple cases
✅ Easier to Extend - adding new cases is as simple as adding a #[case(...)] line
✅ Clear Specification - test cases act as behavior documentation
✅ Maintainability - changes affect one test instead of many
✅ Better Coverage - easier to ensure all combinations are tested
✅ Consistent Testing - all cases use the same testing logic

Test Matrix

Message Type | Symbol | Verbosity | Channel | Always Shown
-------------|--------|-----------|---------|-------------
progress     | ⏳     | Normal    | stderr  | No
success      | ✅     | Normal    | stderr  | No
warning      | ⚠️     | Normal    | stderr  | No
error        | ❌     | Quiet     | stderr  | Yes
result       | (none) | Quiet     | stdout  | Yes
steps        | (none) | Normal    | stderr  | No

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions