---
title: "Auto-Healing Tests"
sidebarTitle: "Auto-Healing"
description: "Set up automatic test repair in CI using GitHub Copilot and TestDriver"
icon: "bandage"
---

Auto-healing tests automatically fix themselves when your application changes. By integrating GitHub Copilot with TestDriver in your CI pipeline, you can have AI investigate test failures and propose fixes.

## How It Works

When a test fails in CI:

1. **GitHub Actions detects the failure**
2. **Copilot spawns the TestDriver agent** with access to the MCP server
3. **The agent investigates** by running the failing test and analyzing what changed
4. **Copilot creates a fix** by updating the test code
5. **A pull request is opened** with the proposed changes for review

## Setting Up Auto-Healing

<Steps>
  <Step title="Add Repository Secrets">
    Add your TestDriver API key to your repository secrets:

    1. Go to **Settings → Secrets and variables → Actions**
    2. Click **New repository secret**
    3. Add `TD_API_KEY` with your API key value
  </Step>

  <Step title="Create the Auto-Heal Workflow">
    Add a GitHub Actions workflow that triggers on test failures:

    ```yaml .github/workflows/auto-heal.yml
    name: Auto-Heal Tests

    on:
      workflow_run:
        workflows: ["Tests"]  # Your main test workflow
        types: [completed]
        branches: [main]

    jobs:
      auto-heal:
        if: ${{ github.event.workflow_run.conclusion == 'failure' }}
        runs-on: ubuntu-latest
        permissions:
          contents: write
          pull-requests: write

        steps:
          - uses: actions/checkout@v4

          - name: Setup Node.js
            uses: actions/setup-node@v4
            with:
              node-version: "20"

          - name: Install dependencies
            run: npm ci

          - name: Run failing tests and capture output
            id: tests
            continue-on-error: true
            run: |
              vitest run 2>&1 | tee test-output.txt
              echo "output<<EOF" >> $GITHUB_OUTPUT
              cat test-output.txt >> $GITHUB_OUTPUT
              echo "EOF" >> $GITHUB_OUTPUT
            env:
              TD_API_KEY: ${{ secrets.TD_API_KEY }}

          - name: Invoke Copilot to fix tests
            uses: github/copilot-action@v1
            with:
              prompt: |
                @testdriver The following tests failed:

                ${{ steps.tests.outputs.output }}

                Please investigate each failure by:
                1. Running the failing test
                2. Analyzing what changed in the UI or behavior
                3. Updating the test code to fix the issue

                Create a commit with your changes.
            env:
              TD_API_KEY: ${{ secrets.TD_API_KEY }}

          - name: Create Pull Request
            uses: peter-evans/create-pull-request@v5
            with:
              title: "Auto-heal: Fix failing tests"
              body: |
                This PR was automatically generated by the auto-heal workflow.

                ## Changes
                The following tests were updated to fix failures detected in CI.

                ## Review
                Please review the changes carefully before merging.
              branch: auto-heal/${{ github.run_id }}
              commit-message: "fix: auto-heal failing tests"
    ```
  </Step>

  <Step title="Configure Test Workflow">
    Make sure your main test workflow has a name that matches the `workflows` trigger:

    ```yaml .github/workflows/tests.yml
    name: Tests  # Must match the workflow_run trigger

    on:
      push:
        branches: [main]
      pull_request:

    jobs:
      test:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: "20"
          - run: npm ci
          - run: vitest run
            env:
              TD_API_KEY: ${{ secrets.TD_API_KEY }}
    ```
  </Step>
</Steps>

## Example: Button Text Change

Here's what auto-healing looks like when a button's text changes:

<Steps>
  <Step title="Application Changes">
    A developer changes a button's text from "Submit" to "Send":

    ```html
    <!-- Before -->
    <button>Submit</button>

    <!-- After -->
    <button>Send</button>
    ```
  </Step>

  <Step title="Test Fails">
    The test fails because it's looking for the old text:

    ```javascript
    // This now fails
    const submitButton = await testdriver.find("Submit button");
    ```
  </Step>

  <Step title="Auto-Heal Triggers">
    The auto-heal workflow runs, and Copilot investigates:

    ```
    The test is looking for a "Submit button" but I see a "Send button"
    on the page. The button functionality is the same, just the text changed.
    I'll update the test to use the new text.
    ```
  </Step>

  <Step title="PR Created">
    A pull request is opened with the fix:

    ```javascript
    // Updated by auto-heal
    const submitButton = await testdriver.find("Send button");
    ```
  </Step>
</Steps>

## Configuration Options

### Selective Auto-Healing

You can limit auto-healing to specific test files or patterns:

```yaml
- name: Run failing tests
  run: |
    # Only heal tests in the e2e directory
    vitest run tests/e2e/ 2>&1 | tee test-output.txt
```

### Manual Approval

For safety, you can require manual approval before auto-heal runs:

```yaml
jobs:
  auto-heal:
    environment: auto-heal  # Requires approval
```

Configure the environment in **Settings → Environments** with required reviewers.

### Limiting Changes

Add instructions to constrain what the AI can change:

```yaml
- name: Invoke Copilot to fix tests
  uses: github/copilot-action@v1
  with:
    prompt: |
      @testdriver Fix the failing tests.

      Rules:
      - Only update element selectors and text matching
      - Do not change test logic or assertions
      - Do not add or remove tests
      - Keep changes minimal
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always review auto-heal PRs">
    Auto-heal is a tool, not a replacement for human judgment. Review all changes before merging to ensure the test still validates what you intended.
  </Accordion>

  <Accordion title="Use descriptive element descriptions">
    Tests with clear, semantic descriptions are easier for the AI to heal:
    ```javascript
    // ✅ Good - describes purpose
    await testdriver.find("primary call-to-action button in the hero section");

    // ❌ Bad - too vague
    await testdriver.find("button");
    ```
  </Accordion>

  <Accordion title="Set up notifications">
    Configure GitHub notifications or Slack integration to be alerted when auto-heal PRs are created.
  </Accordion>

  <Accordion title="Track heal rate">
    Monitor how often tests need healing. High heal rates may indicate:
    - Tests are too brittle
    - Application is changing rapidly
    - Element descriptions need improvement
  </Accordion>
</AccordionGroup>

## Limitations

Auto-healing works best for:
- Element text changes
- Layout and styling updates
- Minor UI restructuring

It may struggle with:
- Major workflow changes
- New features requiring new assertions
- Complex multi-step interactions

For significant changes, create new tests manually using the [TestDriver agent](/v7/copilot/creating-tests).
