skip to content

Which copy of a chart test does `helm test` run - your working tree's or the release's?

level: middleimportance: nice to knowfreq 26%

answer

  1. A release operation, not a chart one
  2. Nothing on disk is read
  3. The rendered copy was kept at deploy time
  4. Stored beside the manifest in the release record
  5. Edits need an upgrade before they run

basics

~20 s

The release's. Helm loads the installed release from its storage record, which already holds the rendered hook manifests, and runs those - so edits to a test file on disk have no effect until you upgrade the release.

solid answer

~40 s

`helm test` never reads chart source. It loads the release from its storage record - the Secret named `sh.helm.release.v1.<name>.v<rev>` in the release namespace - which stores the rendered hook manifests alongside the release's manifest and values, and it runs the ones marked as test hooks. Three consequences follow. You can test from any machine with cluster access and no chart checkout at all. Fixing a broken test in `templates/tests/` changes nothing until you run an upgrade that re-renders and re-stores it, which surprises people iterating on a test. And after a rollback you are running the restored revision's test, because the new revision carries that older revision's stored hooks. `helm get hooks RELEASE` shows you exactly what a run would execute.

code

bash · 5 lines
bash
# what a test run would actually execute for this release
helm get hooks ledger-api -n payments

# the record it comes from
kubectl get secret sh.helm.release.v1.ledger-api.v14 -n payments

go deeper

for a junior

Remember that the command takes a release name, not a chart path, and that it runs what was deployed rather than what is currently in your editor.

for a middle

Explain that hooks are stored as rendered manifests in the release record and that the command reads them from there - then derive the consequences for editing a test, for rollback, and for needing no checkout.

for a senior

Use it operationally: confirm what a release will actually execute before trusting a result, and recognise the edit-upgrade-test loop as the reason a colleague's 'fixed' test keeps failing.

for a principal

Frame the general principle for the team: a release is a self-contained stored record, so verification runs against what was deployed, and any process assuming the repository is the source of runtime truth needs a reconciliation story.

## Where the test definition lives When Helm installs or upgrades a release it renders the chart once and stores the result. That storage record - by default a Secret named `sh.helm.release.v1.<name>.v<rev>` in the release's namespace - holds the release's manifest, the values it was rendered with, its chart metadata, and its **hooks** as already-rendered manifests. Test resources are hooks, so a chart's tests are part of that stored record. `helm test` uses it. The command loads the release, filters its stored hooks down to the ones marked as test hooks, and creates those. It reads no chart directory, no packaged archive and no repository. That is why the command takes a release name and not a path, and why it works fine in a shell that has never seen the chart. ## Consequence one: no chart checkout needed Anyone with cluster access and the release name can smoke-test it. An on-call engineer investigating a payments release at 02:00 does not need to find which chart version it came from, clone anything, or match a values file - `helm test <release> -n <namespace>` is enough, and what runs is exactly what that release was installed with. For a chart that wraps a vendor image and is assembled from a large environment-specific values file, that property is worth a lot: there is no risk of testing a locally rendered variant instead of the deployed one. ## Consequence two: local edits are inert This is the surprise that makes the question interesting. Someone iterating on a failing test edits the test manifest under `templates/tests/`, re-runs `helm test`, and sees the identical failure - because the release still holds the old rendered copy. The edit only takes effect after an upgrade re-renders the chart and writes a new revision. There is no flag that makes the command pick up working-tree source; the loop for developing a test is edit, upgrade, test. The same applies to values. The test was rendered with the values that were in effect at install or upgrade time, so a values change you have not deployed is not reflected in the test that runs. ## Consequence three: rollback changes the test `helm rollback` produces a *new* revision whose content is copied from the target revision, hooks included. So after rolling back, `helm test` runs the restored revision's test, not the one from the revision you were on a minute ago. If the newer chart version had added or tightened a test, that assertion is gone until you roll forward again. This is worth knowing before you conclude from a green test that a rolled-back release is verified to the same standard as the version it replaced. ## Seeing what would run `helm get hooks RELEASE_NAME` prints the release's stored hook manifests, which is the direct way to answer "what will `helm test` actually execute?" It is also the honest check for whether a release carries any test at all - useful because a release with no tests passes silently. Reading that output beats reasoning about the chart source, because the chart source is not what runs. ## Framing it in an interview The crisp version is: `helm test` is a *release* operation, not a *chart* operation. Everything else follows. Candidates who think of Helm as a template renderer expect the command to render the chart again and are then confused by all three consequences above. Candidates who have internalised that a release is a stored, self-contained record of what was deployed get every one of them for free - and that framing is what the question is really probing.

  • You fixed a broken test in `templates/tests/` and re-ran `helm test`. Why is the failure identical?
    Because the release still holds the copy rendered at its last install or upgrade. `helm test` reads the release record, never the working tree, so the fix is invisible until an upgrade re-renders the chart and writes a new revision. The development loop for a chart test is edit, upgrade, test - there is no flag that points the command at source.
  • After a `helm rollback`, whose test runs?
    The restored revision's. A rollback creates a new revision copying the target revision's content, hooks included, so `helm test` executes the older definition. If the newer chart version had added a stricter assertion, it is not running any more - worth remembering before treating a green test on a rolled-back release as equivalent verification.

It is like a photocopy filed at signing time: the version in the filing cabinet is what gets executed, however much you have since annotated your own draft.

saying these in an interview costs you the question

  • Says helm test re-renders the chart from disk
  • Expects a local edit to a test file to take effect immediately
  • Thinks the chart directory must be present to run tests
  • Believes a rollback keeps the newer revision's tests
  • Assumes the test uses whatever values file is currently on disk

context