<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: RAAZU shanigarapu</title>
    <description>The latest articles on Forem by RAAZU shanigarapu (@raazu_shanigarapu_65af2ba).</description>
    <link>https://forem.com/raazu_shanigarapu_65af2ba</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2068686%2Ff9595322-28f3-409e-8d66-ce50bbf30b33.jpg</url>
      <title>Forem: RAAZU shanigarapu</title>
      <link>https://forem.com/raazu_shanigarapu_65af2ba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/raazu_shanigarapu_65af2ba"/>
    <language>en</language>
    <item>
      <title>Self-Healing Tests: My Pragmatic Approach Beyond the Hype</title>
      <dc:creator>RAAZU shanigarapu</dc:creator>
      <pubDate>Mon, 11 May 2026 12:26:45 +0000</pubDate>
      <link>https://forem.com/raazu_shanigarapu_65af2ba/self-healing-tests-my-pragmatic-approach-beyond-the-hype-1g3j</link>
      <guid>https://forem.com/raazu_shanigarapu_65af2ba/self-healing-tests-my-pragmatic-approach-beyond-the-hype-1g3j</guid>
      <description>&lt;p&gt;Self-healing tests are one of the most hyped concepts in QA right now.&lt;/p&gt;

&lt;p&gt;They're also real. I've shipped them. But the version I shipped looks nothing like what most vendors are selling.&lt;/p&gt;

&lt;p&gt;Let me break down the hype from what actually works in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "Self-Healing" Actually Means
&lt;/h2&gt;

&lt;p&gt;A self-healing test is one that can automatically recover from selector failures without a human intervention.&lt;/p&gt;

&lt;p&gt;That's the promise. An element moves, a class name changes, a data-testid gets renamed — and instead of your test suite turning red and blocking your pipeline, the system detects the change, finds the element through alternative means, fixes the locator, and continues.&lt;/p&gt;

&lt;p&gt;Sounds perfect. Here's why it's complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Most Self-Healing Implementations
&lt;/h2&gt;

&lt;p&gt;Most vendor self-healing tools work like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test fails because &lt;code&gt;[data-testid="submit-btn"]&lt;/code&gt; isn't found&lt;/li&gt;
&lt;li&gt;Tool takes a screenshot + DOM snapshot at failure point&lt;/li&gt;
&lt;li&gt;Tool compares to previous successful run&lt;/li&gt;
&lt;li&gt;Tool finds the "closest" element and retries&lt;/li&gt;
&lt;li&gt;Tool saves the new locator as a "healed" version&lt;/li&gt;
&lt;li&gt;Next run uses the healed locator&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works surprisingly well — for simple, isolated selector changes.&lt;/p&gt;

&lt;p&gt;It fails for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dynamic applications with state-dependent elements&lt;/li&gt;
&lt;li&gt;Elements that move position but retain the same selector&lt;/li&gt;
&lt;li&gt;Fundamental layout changes where "submit" button moved to a different form&lt;/li&gt;
&lt;li&gt;Race conditions and timing issues that look like selector failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The deeper issue: self-healing that silently patches locators is self-healing that hides problems. If your test healed 50 locators last week, you have 50 silent signals that the UI is changing faster than your team knows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Built
&lt;/h2&gt;

&lt;p&gt;The self-healing mechanism I implemented at Mendix works differently from the vendor pitch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 1: Locator Strategy Cascade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of a single selector, every element has a priority-ordered strategy list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;element_strategies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data-testid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;submit-btn&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;        &lt;span class="c1"&gt;# Primary — developer-maintained
&lt;/span&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;aria-label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Submit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;             &lt;span class="c1"&gt;# Secondary — accessibility
&lt;/span&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Submit&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;                   &lt;span class="c1"&gt;# Tertiary — visible text
&lt;/span&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;button[type=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;submit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;     &lt;span class="c1"&gt;# Fallback — structural
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the primary locator fails, the framework tries the next. If a fallback succeeds, it logs the incident, creates an alert, and flags the primary for review.&lt;/p&gt;

&lt;p&gt;No silent healing. The fix is flagged, tracked, and assigned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: Similarity Scoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When all strategies fail, I use a DOM similarity algorithm (not an LLM — a structured comparator) that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes the expected element's attributes and position&lt;/li&gt;
&lt;li&gt;Scans the current DOM for the closest structural match&lt;/li&gt;
&lt;li&gt;Returns a confidence score with a suggested locator update&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If confidence is above 85%, the test continues with the suggested locator and creates a PR-ready fix suggestion. If below, the test fails with a diagnostic report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3: Failure Intelligence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every failure generates structured metadata:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which locator strategy failed&lt;/li&gt;
&lt;li&gt;Which (if any) fallback succeeded&lt;/li&gt;
&lt;li&gt;The confidence score of any auto-suggestions&lt;/li&gt;
&lt;li&gt;The code diff context from the last 24 hours&lt;/li&gt;
&lt;li&gt;The element's historical stability score&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This feeds into a dashboard that shows which UI elements are highest-maintenance. Developers see this. When an element is flagged as high-drift, it becomes a conversation about whether the test or the element is the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Value: Not Just Fewer Red Tests
&lt;/h2&gt;

&lt;p&gt;The most valuable outcome of self-healing architecture isn't that fewer tests fail.&lt;/p&gt;

&lt;p&gt;It's that the &lt;em&gt;reason&lt;/em&gt; tests fail becomes data.&lt;/p&gt;

&lt;p&gt;Before: "Tests are failing, probably a UI change."&lt;br&gt;
After: "The submit button's primary selector has changed 4 times in 6 weeks. The Payments team is iterating fast. Let's add a &lt;code&gt;data-testid&lt;/code&gt; that's stable."&lt;/p&gt;

&lt;p&gt;That's a different conversation. A useful one.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Self-Healing Is Worth It
&lt;/h2&gt;

&lt;p&gt;Self-healing makes sense when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your application UI iterates faster than your test maintenance cadence&lt;/li&gt;
&lt;li&gt;You have a large legacy test suite with inconsistent locator strategies&lt;/li&gt;
&lt;li&gt;You have clear locator ownership and want to enforce it via automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Self-healing is not worth it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your core problem is test architecture (fix that first)&lt;/li&gt;
&lt;li&gt;You want it to mask flakiness rather than surface it&lt;/li&gt;
&lt;li&gt;You're hoping to avoid adding &lt;code&gt;data-testid&lt;/code&gt; attributes to your UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The vendors that promise "zero test maintenance" are selling a fantasy. The engineers who implement thoughtful self-healing architecture are solving a real problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Verdict
&lt;/h2&gt;

&lt;p&gt;Self-healing tests are worth building — not buying.&lt;/p&gt;

&lt;p&gt;The buy-vs-build question matters here more than anywhere. Commercial tools optimize for impressive demos. Custom implementations optimize for your specific app, your specific failure patterns, your specific team's workflow.&lt;/p&gt;

&lt;p&gt;The best self-healing system I've built took 3 weeks to implement and 6 months to refine based on real failure data. It's now the reason our test maintenance load is 40% lower than industry average.&lt;/p&gt;

&lt;p&gt;That's not magic. That's engineering.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://raju-shanigarapu.vercel.app/blog/self-healing-tests-hype-vs-reality" rel="noopener noreferrer"&gt;https://raju-shanigarapu.vercel.app/blog/self-healing-tests-hype-vs-reality&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>qa</category>
      <category>testing</category>
      <category>automation</category>
      <category>playwright</category>
    </item>
    <item>
      <title>Why Your Automation Framework is Failing (It's the Architecture)</title>
      <dc:creator>RAAZU shanigarapu</dc:creator>
      <pubDate>Fri, 08 May 2026 21:17:43 +0000</pubDate>
      <link>https://forem.com/raazu_shanigarapu_65af2ba/why-your-automation-framework-is-failing-its-the-architecture-489j</link>
      <guid>https://forem.com/raazu_shanigarapu_65af2ba/why-your-automation-framework-is-failing-its-the-architecture-489j</guid>
      <description>&lt;p&gt;I've seen it happen at every company I've joined.&lt;/p&gt;

&lt;p&gt;Someone built an automation framework 2 years ago. It has 800 tests. Half of them fail on any given day. Nobody touches it except to disable the failing ones. The team has silently agreed to stop trusting it.&lt;/p&gt;

&lt;p&gt;This is the most common QA failure mode. And it has almost nothing to do with the tool choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Reason Frameworks Fail
&lt;/h2&gt;

&lt;p&gt;Every post-mortem I've done on a dead automation framework finds the same root causes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Tests were written for the happy path, not the system.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The team automated what users &lt;em&gt;should&lt;/em&gt; do, not what the system &lt;em&gt;could&lt;/em&gt; encounter. The first time a timeout, a race condition, or an API degradation hit production, the tests were useless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. No ownership model.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Who fixes a failing test? If the answer is "whoever broke it," the answer is actually "nobody." Automation without explicit ownership is automation in decline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. The framework grew faster than its architecture.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Someone wrote &lt;code&gt;test_login.py&lt;/code&gt; and copy-pasted it 300 times. No page object model. No fixtures. No hierarchy. 300 tests that all fail when the login selector changes by one character.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. It wasn't treated as code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tests have linting standards, code reviews, and refactoring cadence — or they don't. Teams that treat test code as second-class code produce second-class automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. No feedback loop with engineering.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If developers can merge code without seeing automation results, the automation is decorative. Tests that don't block pipelines don't protect pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Good Architecture Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;I've built automation systems that outlive teams and survive platform migrations. Here's what they have in common:&lt;/p&gt;

&lt;h3&gt;
  
  
  A Single Source of Locator Truth
&lt;/h3&gt;

&lt;p&gt;Locators live in one place. Not scattered across test files. Not duplicated across 40 helpers. When the UI changes, you update one layer and every test that touches that element is fixed.&lt;/p&gt;

&lt;p&gt;Page Object Model is table stakes. If you're not using it, stop reading this and implement it today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Isolation as a Non-Negotiable
&lt;/h3&gt;

&lt;p&gt;Every test must be independently executable. No test should depend on another test having run first. No shared mutable state between tests.&lt;/p&gt;

&lt;p&gt;If you can't run &lt;code&gt;test_checkout_flow.py&lt;/code&gt; in isolation and have it pass, you don't have a test — you have a dependency chain waiting to cascade.&lt;/p&gt;

&lt;h3&gt;
  
  
  Retry Logic That's Honest
&lt;/h3&gt;

&lt;p&gt;Retry is not a solution. It's a suppressor. Use it sparingly, with a cap (3 retries max), with logging that exposes every retry. A test that passes on retry 3 is not a passing test — it's a flaky test with a mask on.&lt;/p&gt;

&lt;p&gt;Track your retry rate. If it's above 5%, you have a structural problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contract-First API Testing
&lt;/h3&gt;

&lt;p&gt;Before testing behavior, test the contract. Does the API schema match what you expect? Does it match what downstream services expect?&lt;/p&gt;

&lt;p&gt;API contract tests are the highest ROI automation you can write. They catch breaking changes before any UI test ever runs, and they run in milliseconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Integration From Day One
&lt;/h3&gt;

&lt;p&gt;Not after the framework "matures." Day one. Tests that don't run in the pipeline don't matter. Test results that don't block merges don't influence behavior.&lt;/p&gt;

&lt;p&gt;If you can't run your smoke suite in under 5 minutes, fix that before writing more tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Framework Health Checklist
&lt;/h2&gt;

&lt;p&gt;Before expanding any automation project, run this checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Can I run any single test in isolation?&lt;/li&gt;
&lt;li&gt;[ ] Does every test have an owner?&lt;/li&gt;
&lt;li&gt;[ ] Are failing tests blocking merges?&lt;/li&gt;
&lt;li&gt;[ ] Is the flaky test rate below 5%?&lt;/li&gt;
&lt;li&gt;[ ] Are locators centralized?&lt;/li&gt;
&lt;li&gt;[ ] Is test code reviewed like production code?&lt;/li&gt;
&lt;li&gt;[ ] Do tests run in CI on every PR?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If more than 2 of those are "no," you're building on sand.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture Decision That Matters Most
&lt;/h2&gt;

&lt;p&gt;Here's the one I see teams skip most often:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Define your test pyramid before writing test one.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How many unit tests? How many integration tests? How many E2E tests? What's the expected execution time for each tier?&lt;/p&gt;

&lt;p&gt;Without this contract, teams default to writing whatever's easiest. Usually E2E tests. Slow, brittle, expensive E2E tests that replace the fast, reliable tests that should have been written first.&lt;/p&gt;

&lt;p&gt;The pyramid isn't a suggestion. It's load-bearing.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Rule of Thumb
&lt;/h2&gt;

&lt;p&gt;If your automation framework requires more than 20% of QA time to maintain, it's not working for you — you're working for it.&lt;/p&gt;

&lt;p&gt;Good automation accelerates. Bad automation accumulates.&lt;/p&gt;

&lt;p&gt;The difference is almost always in the first 30 days of decisions.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://raju-shanigarapu.vercel.app/blog/why-automation-frameworks-fail" rel="noopener noreferrer"&gt;https://raju-shanigarapu.vercel.app/blog/why-automation-frameworks-fail&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>automation</category>
      <category>qa</category>
      <category>architecture</category>
      <category>testautomation</category>
    </item>
  </channel>
</rss>
