GridPlacement 6.0 C# Test Parameterization Guidelines
This guide explains when and how to use parameterized tests
(xUnit [Theory] + InlineData) in the GridPlacement 6.0 C# suites.
It is intentionally short and opinionated.
When Parameterization Is Worth It (≥ 7/10)
Use [Theory] when all of the following are true:
- Same behavior shape
- The test body is identical for each case.
- Only the input data and expected outcome differ.
- Clearer coverage map
- InlineData rows make scenarios easier to scan than many tiny Facts.
- Easy to extend
- Adding new cases is just adding more InlineData rows.
- No complex branching in the test body
- Avoid
if/switchper-case logic.
- Avoid
Examples in this repo
GridMathTests- Distance, region, and bounds checks with different integer inputs.
GridPositionTests- Manhattan/Chebyshev distances and adjacency matrices.
BoundsValidationTest- Area and tile-count calculations.
PhysicsMatchingUtilsTest- Bitmask→layers and mask matching shapes.
PlaceableCatalogTestsTryGet_ReturnsExpectedResultBasedOnIdfor existing vs unknown IDs.
PlaceableSequenceTestsGetTier_IndexOutOfRange_ThrowsArgumentOutOfRangeExceptionfor invalid indices.
These tests are good parameterization targets because:
- The intent is the same across rows.
- The behavior is essentially a pure function.
- The assertion pattern does not change.
When To Prefer Separate [Fact] Tests
Keep individual [Fact] tests when any of these hold:
- Different behaviors or domains
- Each test exercises a different branch of business logic.
- Example: start vs cancel vs complete flows in
ManipulationServiceTests.
- Different assertion shapes
- One test checks events, another checks exceptions, another checks state.
- High-level scenario or integration tests
- Smoke tests, workflows, or end-to-end adapter paths.
- Parameterization would require branching
- If you need
if (case == "X")inside the test, prefer multiple Facts.
- If you need
Examples kept as Facts on purpose
ManipulationStateTests/ManipulationServiceTests- Lifecycle, events, validation, and per-mode behaviors.
SelectionAdapterTests- Catalog init, empty catalog handling, category filters, end-to-end build mode.
PlaceableCollectionTests- Many distinct behaviors (add/remove, categories, metadata), each short and focused.
- Godot smoke tests
- Minimal service-level scenarios; typically 1–2 tests per class.
Practical Heuristics
When you consider parameterization, ask:
- Does this reduce duplication without hiding intent?
- Would a future engineer understand the behavior from InlineData alone?
- Will adding more scenarios stay simple?
- Does the test body stay branch-free and readable?
If the answer is yes to most of these, parameterize.
If not, keep (or split into) small, explicit [Fact] tests.
Style Notes (for GridPlacement 6.0)
- Prefer descriptive test method names over cryptic data.
- Keep InlineData values small and readable (ints/strings/booleans over complex objects).
- For more complex data, favor simple helper methods in the same test class
instead of trying to stuff everything into
InlineData. - Do not parameterize just to “reduce line count” if it hurts clarity.
These guidelines are intentionally conservative: we want parameterization where it meaningfully improves maintainability and coverage, not everywhere by default.