Skip to content

test-projects is silently ignored in solution mode, including non-existent paths #3795

Description

@ramedey

Summary

When solution is set in stryker-config.json, test-projects has no effect and is never validated. A test-projects entry pointing at a file that does not exist produces no error, no warning, and no log line — Stryker silently discovers and runs every test project in the solution instead.

The operating-modes docs say solution mode analyses the whole solution, so the "runs everything" half may well be intended. The half that looks unambiguously wrong is that an invalid test-projects path is accepted in silence. That is what makes the first half undiscoverable: the config looks like it is scoping the run, and there is no signal anywhere that it is inert.

Closest existing report I could find is discussion #2815, which hits the same wall but does not cover the silent acceptance of a non-existent path.

Minimal repro

A solution with one source project and two test projects — UnitTests (2 tests) and OtherTests (3 tests), both referencing Calc:

Repro.slnx
src/Calc/Calc.csproj
tests/UnitTests/UnitTests.csproj    # 2 tests
tests/OtherTests/OtherTests.csproj  # 3 tests

Case A — scope to one test project:

{ "stryker-config": {
    "project": "Calc.csproj",
    "solution": "Repro.slnx",
    "test-projects": ["tests/UnitTests/UnitTests.csproj"]
} }
[INF] Number of tests found: 5 ...

Expected 2. Both test projects ran.

Case B — point test-projects at a path that does not exist:

{ "stryker-config": {
    "project": "Calc.csproj",
    "solution": "Repro.slnx",
    "test-projects": ["tests/DoesNotExist/Nope.csproj"]
} }
[INF] Number of tests found: 5 ...

No error. No warning. Nothing in the log mentions the missing project at all.

Case C — the documented workaround, run from the test project directory with no solution key:

[INF] Analyzing 1 test project(s).
[INF] Number of tests found: 2 ...

Correct. So the scoping itself works; it is specifically inert in solution mode.

I reproduced the same behaviour with both "test-runner": "vstest" and "mtp".

Actual vs expected

actual expected
valid test-projects + solution silently ignored honoured, or a warning that it is ignored in solution mode
non-existent test-projects path silently ignored, exit 0 error, or at minimum a warning

Why this is worth fixing

On a real project this cost us roughly 20 minutes of CI wall-clock per run for weeks before anyone found the cause. test-projects named only the unit test suite, so the config read as correctly scoped. In fact the solution's integration test project was also being run — against every mutant — and each of those tests starts a PostgreSQL container via Testcontainers. That worked out to ~11s per mutant against a unit suite that runs in 209 ms, and it pushed the pipeline past its 30-minute job ceiling.

Nothing in the output suggested the config was being disregarded. The only reason we found it was noticing database containers churning during a mutation run. Switching to project mode dropped the step from 23m16s to about 30s.

Suggested fix

Either would have surfaced this immediately:

  1. Validate test-projects regardless of mode — error on an entry that does not resolve to an existing project file. This seems worth doing independently of anything else.
  2. Warn when test-projects is set but inert, e.g. test-projects is ignored in solution mode; all test projects in the solution will be run.

Honouring test-projects as a filter within solution mode would be the most useful outcome, but a diagnostic alone would have saved all of the above.

Environment

  • Stryker.NET 4.16.0
  • .NET SDK 10.0.400
  • macOS (Darwin 25.5.0), also observed on ubuntu-24.04 GitHub-hosted runners
  • xunit, both vstest and mtp test runners

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions