DEV Community

Jan Duris
Jan Duris

Posted on Originally published at coderlegion.com

Your Tests Passed. That Still Doesn’t Mean You Should Release.

Your tests passed.

CI is green.

The build succeeded.

So you release.

Seems reasonable, right?

Not necessarily.

One of the most dangerous assumptions in modern software delivery is that a successful test suite automatically means a release is ready for production.

It doesn't.

Passing tests tell us that the checks we wrote passed.

A release decision asks a much larger question:

Do we have enough evidence to accept the risk of shipping this change?

Those are not the same thing.


What does a passing test actually prove?

Every automated test checks a specific expectation.

A unit test might verify that a function returns the expected result.

An API test might verify that an endpoint responds with 200.

An end-to-end test might confirm that a user can complete checkout.

All of these are useful.

But every test is created around assumptions.

Someone decided:

  • what should be tested,
  • which scenarios matter,
  • which data should be used,
  • which environments should be covered,
  • and which failure modes were worth checking.

So when a test passes, what we really know is:

Under the conditions we tested, the expected behavior occurred.

That is valuable evidence.

But it is not the same as:

This release is safe.


A release contains more risk than your test suite can see

Imagine this release:

Unit tests PASS
Integration tests PASS
E2E tests PASS
Lint PASS
Build PASS

Everything looks perfect.

But the same release also includes:

Database migration HIGH IMPACT
Authentication changes YES
Dependency upgrade YES
Rollback recently tested NO
Observability coverage PARTIAL
Deployment blast radius HIGH

None of those conditions necessarily need to make a test fail.

Yet every one of them can influence whether releasing is a good idea.

This is where we often confuse two different activities:

verification and decision-making.

Tests verify behavior.

Release decisions evaluate risk.

Green CI is a signal

A common delivery model effectively looks like this:

Tests pass
+
Build succeeds
+
Artifact exists
=
Deploy

For small systems and simple changes, this can work remarkably well.

But the larger the system becomes, the weaker that assumption gets.

A release can have a perfectly healthy CI pipeline and still be operationally risky.

For example:

green pipeline
+
critical service change
+
large migration
+
weak rollback confidence
+

limited observability

???

The individual checks are green.

The combined risk might not be.

Tests should be evidence, not the final decision

I think a better mental model is this:

             RELEASE DECISION
                    ▲
                    │
    ┌───────────────┼───────────────┐
    │               │               │
 Tests           Changes        Operations
    │               │               │
 Security       Dependencies     Rollback
    │               │               │
    └──────────── Evidence ─────────┘
Enter fullscreen mode Exit fullscreen mode

Tests remain one of the strongest signals we have.

But they are one signal among several.

A release decision may also need to consider:

change size,
affected services,
security findings,
dependency changes,
database migrations,
production incident history,
deployment timing,
rollback readiness,
observability,
required approvals.

Not every team needs every signal.

The important part is the distinction:

Test results are evidence presented to a release decision. They are not the release decision itself.

This gets more important with AI-generated code

AI coding tools are making software creation dramatically faster.

They can generate implementation code.

They can generate tests.

They can fix failing tests.

And they can do all of that very quickly.

That creates an interesting situation:

More code
More tests
More automation
More green checks

But potentially:

Less human understanding of every individual change

An AI-generated implementation can satisfy the tests while still introducing:

a new architectural assumption,
an unexpected dependency,
different runtime behavior,
operational complexity,
or a failure mode nobody encoded into the tests.

The solution is not to stop using AI.

And it isn't simply to generate even more tests.

The solution is to become better at evaluating evidence around the release.

CI systems are excellent at execution

Modern CI/CD systems are incredibly capable.

They can:

run thousands of tests,
scan dependencies,
build containers,
validate infrastructure,
generate artifacts,
and deploy applications.

But there is one question many pipelines are surprisingly bad at answering:

Why are we comfortable releasing this version?

Ask that question after a deployment.

You may get answers like:

"Everything was green."

or:

"The PR was approved."

or:

"The pipeline allowed it."

Those answers describe what happened.

They don't necessarily explain the actual release decision.

What would a release decision layer look like?

Instead of:

CI green → deploy

we could think about delivery like this:

Code change

CI / QA / Security / Operational signals

Evidence collection

Risk evaluation

Policy

Release decision

Deploy

That decision does not always need to be binary.

For example:

GO

The evidence is sufficient and the risk is acceptable.

CONDITIONAL GO

The release can proceed, but only with an approval, mitigation, feature flag, additional monitoring, or another condition.

NO GO

The available evidence or risk does not justify releasing yet.

This is much closer to how experienced engineers already think.

The difference is making that reasoning explicit instead of leaving it inside someone's head.

Green should have a precise meaning

There is nothing wrong with green CI.

We want green builds.

We want passing tests.

We want fast feedback.

The problem begins when we give those signals more meaning than they actually contain.

A green pipeline should mean:

The checks we defined passed.

A release decision should mean:

Given the available evidence and our risk policy, we are willing to ship this change.

Those statements are related.

But they are not identical.

And as software development becomes faster, more distributed, and increasingly AI-assisted, I think that distinction is going to matter much more.

How does your team decide that something is ready to release?

Is a green pipeline enough?

Or is there another decision layer after CI?

Top comments (0)