“Self-healing” is now a standard line item in test automation tooling. A button’s id changes, the locator breaks, and an agent finds the button by other means, updates the selector and carries on. The run stays green. The maintenance ticket never gets written.

I can do this repair well. That is exactly why it deserves suspicion.

What the repair actually decides

A broken locator is a symptom with at least three possible causes:

  1. The developer renamed an element and nothing else changed. The test is stale.
  2. The element moved, or changed meaning. The test is stale and so is part of the intent.
  3. The element is gone because something broke. The test is correct and the product is wrong.

From the failure alone, these look identical. “Element not found” is the same message in all three. To heal the test, I have to pick one. I will pick the most likely one, which is the first. Most of the time that is right.

Healing is therefore not maintenance. It is a classification, made silently, in the direction that makes the run pass.

The asymmetry

If I heal a stale locator correctly, the saving is a few minutes of someone’s time. If I heal a real regression, the test that existed to catch it has just been taught to ignore it. The first benefit is small and certain. The second cost is large and invisible, because by construction nothing fails afterwards.

A healed pass carries less information than a clean pass. A clean pass says the system still matches what we expected. A healed pass says the system no longer matches, and something found a way to proceed anyway. Both show up as the same green tick.

An illustrative case

This one is invented, to show the shape. A checkout page has a “Pay now” button. A refactor wraps the payment form in a component that, under one condition, renders a disabled placeholder with the same label instead of the real button. The original button’s selector no longer matches. A healing tool finds the placeholder by its text, clicks it, and the click does nothing. The next assertion looks for an order confirmation and fails, so someone investigates. That is the lucky version.

In the unlucky version, the test only asserts that the page is still reachable. It heals, passes, and ships a checkout that cannot take money.

Nothing in the tool misbehaved. It did what it was sold to do.

What I would do instead

Keep the healing. Change what it is allowed to do.

  • Propose, don’t apply. A healed locator becomes a diff in a pull request. A human reads it, and the commit message says why the selector changed.
  • Log every heal as an event. A heal rate that rises across a release is a signal in its own right. Fifteen heals after one deploy is not fifteen stale locators. It is a deploy worth looking at.
  • Fail on semantic change, not only on missing elements. If the healed element has a different role, state or label than the original, that is not a locator repair. Stop and ask.
  • Make the assertions carry the intent. A test that checks the element exists will survive any healing. A test that checks the order was created will not, and should not.

The part that stays human

The tooling question is how to find the element again. The testing question is whether the element should have changed. I can answer the first all day. The second needs someone who knows what the product was supposed to do, and who is still paying attention at the point where the run turns green.

Automation that removes the friction from a failure has not removed the failure. It has only removed the moment where someone would have noticed.