Skip to content

Add opt-in release_step_arguments setting - #6956

Draft
W0rma wants to merge 4 commits into
Codeception:mainfrom
W0rma:release-step-arguments
Draft

W0rma wants to merge 4 commits into
Codeception:mainfrom
W0rma:release-step-arguments

Conversation

@W0rma

@W0rma W0rma commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Codeception keeps every finished test until the suite ends, including the arguments of its recorded steps. Objects passed to $I->…, such as Doctrine entities or closures, stay in memory for the whole run, together with
everything they reference (entity managers, service containers). Memory use and garbage-collection time grow with every test. See Codeception/module-doctrine#15.

With the new setting, object arguments are replaced by the text Codeception displays for them once a test has finished and all TEST_END listeners have run:

settings:
    release_step_arguments: true

Step output stays the same, including the failure summary printed at the end of the run. The setting is off by default, because extensions might read the raw arguments of finished tests.

In a Symfony/Doctrine functional suite with about 800 tests, enabling it reduced run time from 3:51 to 2:51 and peak memory from 583 MB to 163 MB.

Changes

  • Step::stringifyObject() is extracted from stringifyArgument() so the release can reuse it
  • Step::releaseArguments() and Scenario::releaseStepArguments() release the recorded steps and their meta steps; Executor also drops its closure
  • The setting is passed from Configuration through SuiteManager and Suite to Test::realRun(), the same way as report_useless_tests
  • Unit tests for the release, plus a CLI test running a suite with the setting on and off

Behaviour notes

  • With the setting on, the displayed text of each object argument, e.g. its __toString(), is computed when the test finishes, for passing tests too. Before, it was only computed when a step was printed. If the conversion
    throws, the class name is used.
  • Objects nested in array arguments are replaced by their decoded JSON, so they're displayed the same way as before.

This PR was prepared with the help of AI.

W0rma added 4 commits November 9, 2026 14:39
Prepares reusing the display form of object arguments.
Step::releaseArguments() replaces object arguments with the text they
are displayed as, so the objects can be garbage collected while the
step is still printed the same way, e.g. in the failure summary at the
end of the run. If converting an object fails, its class name is used.
Objects nested in array arguments are replaced by their decoded JSON,
which is displayed the same way.

Scenario::releaseStepArguments() does this for all recorded steps and
their meta steps; Executor also drops its closure.
Codeception keeps every finished test until the suite ends, including
the arguments of its recorded steps. Objects passed to steps, e.g.
Doctrine entities or closures, stay in memory together with everything
they reference (entity managers, service containers), so memory and
garbage collection time grow with every test.

With `settings: release_step_arguments: true`, the steps' object
arguments are released once a test has finished and all TEST_END
listeners have run. Step output in reports is unchanged.

The setting is disabled by default because extensions might read the
raw arguments of finished tests.

See Codeception/module-doctrine#15
Runs a suite with the setting enabled and disabled and checks whether
the finished tests' steps still hold the objects passed to them, and
that the failure summary still shows the released arguments.
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.

1 participant