Why teams automate test writing
Unit tests are valuable and tedious. Under schedule pressure they are the first thing skipped, and legacy modules often have none. An agent that can read a module, understand its behavior and write tests removes a backlog nobody wants to pick up.
The work suits automation well. The target is specific, the result is checkable by running it, and the change is additive. A new test file is low risk to merge compared with a change to production logic.
What separates a useful test from filler
A generated test can pass and still be worthless. Tests that assert nothing, assert only that a function returns something, or mirror the implementation line by line raise a coverage number without protecting behavior.
Useful tests encode intent. They check outcomes for meaningful inputs, cover error paths and boundaries, and fail when the behavior changes. A good generator starts from a plan: which functions matter, what could go wrong, which cases are worth covering.
There is also a subtle trap. A test written from the current code captures current behavior, including current bugs. A reviewer should read generated tests as a description of what the code does today and ask whether that is what it should do.
- Assertions on behavior, not just execution
- Error paths and boundaries, not only the happy path
- No dependence on network, time or ordering unless controlled
- Readable names that state the expected behavior
Failure modes to guard against
An agent told to make tests pass has several shortcuts available. It can change the production code to fit the test. It can weaken an existing assertion. It can delete a failing test, add an ignore marker, or edit the coverage configuration.
None of these should be possible in a test generation task. The fix is scope: declare which paths the task may touch and check the actual diff against that scope before anything is published. A violation should stop the change, not produce a warning.
Flaky tests are the other cost. A test that fails intermittently takes more from a team than it gives. Run generated tests through the same validation as everything else and review them for hidden dependencies.
How PWR generates tests
In PWR, test work is done by the QA role. The Generate Unit Tests workflow creates a task scoped to tests only. The Create a Test Plan workflow returns a risk matrix, test cases and coverage targets before any code is written.
Scoped tasks carry an explicit list of allowed and forbidden paths. Before a push, a guard checks the diff. Changes to production files, deleted tests, lost assertions, coverage-ignore markers and coverage configuration edits are violations. A violation stops the push and nothing leaves the worker.
The tests then follow the normal path. Your validation command runs them, a pull request is opened, an independent review reads it, and a person approves. When a bug is fixed through the Fix a Bug workflow, the task carries a criterion to write the regression test first. The guard has a stated limit. It detects weakened assertions by counting assertion lines, so a rewrite that keeps the count but loosens the check can pass it. Review is the backstop for that case.