
How to Reduce AI Token Usage in Test Automation
Liviu Lupei
Founder & Solutions Architect, Endtest · June 2, 2026
AI is becoming a normal part of test automation.
Teams are using AI to create test cases, generate Playwright scripts, repair Selenium tests, understand failures, suggest locators, write assertions, and explain broken test runs.
But AI is not free to run, and that becomes obvious very quickly.
Most AI providers seem to be moving toward usage-based or token-based pricing. GitHub Copilot is a good example of this shift. Instead of treating AI as an unlimited feature, the industry is increasingly measuring usage based on how much context is sent to the model and how much output the model generates.
That matters a lot for test automation.
A test automation system can call AI many times per test. It can send page HTML, screenshots, logs, source code, selectors, test files, error messages, and previous attempts. If you are not careful, AI token usage can grow faster than your test suite.
This article explains how to reduce AI token usage in test automation without making your tests less useful, less reliable, or harder to maintain.
Why AI token usage matters in test automation
Tokens are the pieces of text that AI models process.
When you send a prompt to an AI model, the input consumes tokens. When the model generates an answer, the output also consumes tokens. The larger the prompt, the more expensive the request usually becomes.
In test automation, token usage can grow because AI often receives a lot of context:
- The full test file
- The current page DOM
- The error message
- Screenshots or visual descriptions
- Browser logs
- Network logs
- Framework configuration
- Related helper files
- Previous failed attempts
- Instructions about the testing framework
A simple request such as "fix this test" can become expensive if the AI needs to inspect thousands of lines of Playwright or Selenium code.
This is especially risky when AI is called automatically during test execution. If every click, assertion, locator lookup, or failure triggers an AI request, a normal test suite can produce a large amount of token usage every day.
For small teams, that can mean an unexpectedly high bill at the end of the month.
For larger teams, it can become a budget and governance problem.
And in the worst case, the team may need to reduce, pause, or suspend automated testing because the AI layer became too expensive to run.
The wrong approach: calling AI for everything
The easiest way to waste tokens is to use AI for tasks that do not need AI.
For example, you usually do not need AI to:
- Click a button when the locator is already known
- Fill an input field with a known value
- Check if an element exists
- Compare text against an expected value
- Wait for a page to load
- Run a normal assertion
- Reuse a locator that worked in previous executions
- Execute an existing test step
These are deterministic actions. They can be handled by the test automation engine without involving a language model.
AI should be used where it actually adds value:
- Creating a new test from natural language
- Suggesting a locator when the intent is unclear
- Explaining a complex failure
- Helping update a test after the application changed
- Verifying whether a failure is likely caused by a product change
- Repairing a test when normal recovery methods fail
The rule is simple. Do not call AI when traditional automation can complete the action reliably.
This keeps the AI layer focused on the parts of testing where reasoning is useful.
Use AI only at the right moments
A token-efficient test automation workflow should call AI only at specific moments.
The most common useful moments are:
- When creating a new test
- When updating an existing test
- When analyzing a failure
- When normal self-healing cannot solve the problem
- When verifying something that requires interpretation
This is very different from calling AI during every step of the test.
For example, a bad approach would be:
await ai.click("Click the login button");
await ai.type("Enter the email address");
await ai.type("Enter the password");
await ai.click("Click the submit button");
await ai.verify("Check that the dashboard is displayed");This approach may look simple, but it can become expensive. Every action may require the AI to inspect the page, understand the instruction, choose a locator, and decide what to do.
A better approach is:
await page.locator('[data-testid="login-button"]').click();
await page.locator('[data-testid="email"]').fill(email);
await page.locator('[data-testid="password"]').fill(password);
await page.locator('[data-testid="submit"]').click();
await expect(page.locator('[data-testid="dashboard"]')).toBeVisible();In this version, AI is not needed during normal execution.
AI could still be used when creating the test, improving the test, or repairing it after a real application change. But the normal execution path stays predictable and cheap.
Why AI with Playwright or Selenium can become inefficient
Playwright and Selenium are powerful frameworks. They give developers a lot of control.
But using AI with Playwright or Selenium can become token-heavy because the output is code.
That creates a few problems.
First, every test update may require the AI to read the existing code. If the test suite is small, this may not seem like a big issue. But as the codebase grows, each AI-assisted change may require more context.
The AI may need to understand:
- Test files
- Page objects
- Custom helper functions
- Fixtures
- Authentication setup
- Environment configuration
- Shared utilities
- Existing locator conventions
- CI behavior
- Previous test failures
Second, generated code can be inconsistent. One AI response may use one pattern, while the next response uses a different pattern. Over time, the test suite can become harder to maintain.
Third, AI-generated code often requires review. If the generated code is wrong, the team still needs to debug it. That means more AI calls, more prompts, more retries, and more tokens.
Fourth, every future update may become more expensive. The larger the codebase, the more context the AI may need to process.
This is why AI-generated Playwright or Selenium code can look efficient at the start, but become inefficient later.
The first test may be cheap.
The hundredth test may not be.
Avoid sending the entire codebase to the AI
One common mistake is giving the AI too much context.
Developers often send large files or entire folders because they are not sure which parts matter. That may improve the model's ability to reason, but it also increases token usage.
Instead, send the smallest useful context.
For example, when fixing a failed test, the AI may not need the entire repository. It may only need:
- The failing step
- The error message
- The locator that failed
- A small HTML snippet around the target element
- The expected behavior
- The previous successful locator, if available
Instead of this:
Here is my entire Playwright project. Fix the failing checkout test.Use something more focused:
This Playwright step failed:
await page.locator('[data-testid="checkout-button"]').click();
Error:
Element not found.
Expected behavior:
Click the button that opens the checkout page.
Relevant HTML:
<button aria-label="Continue to checkout" class="primary-action">
Checkout
</button>
Suggest a safer locator.That prompt is shorter, cheaper, and easier for the AI to answer.
Use stable locators before AI
The best way to reduce AI usage is to reduce the number of test failures that require AI.
That starts with stable locators.
Use reliable attributes whenever possible:
data-testiddata-testdata-qa- Stable
idvalues - Accessible labels
- Button text when it is stable
- Semantic roles
For example:
await page.getByTestId('checkout-button').click();is usually better than:
await page.locator('div:nth-child(4) > button:nth-child(2)').click();Unstable locators break more often. Broken locators trigger more repair attempts. More repair attempts usually mean more AI calls.
Token efficiency is about test design as much as prompts.
Better tests consume fewer AI tokens because they fail less often.
Do not use cheaper models as the main strategy
A common reaction to high token usage is to switch to a cheaper model.
That can help in some cases, but it should not be the main strategy.
Cheaper models may be less accurate for test automation tasks. They may hallucinate selectors, misunderstand the application flow, produce incorrect code, or fail to notice important details in the error message.
In test automation, a bad AI answer can break the entire testing workflow.
A cheaper model might produce:
- A locator that matches the wrong element
- A test that passes for the wrong reason
- A flaky wait strategy
- An assertion that does not verify the real requirement
- Code that works locally but fails in CI
- A false explanation of the failure
That can be more expensive than using a better model.
The real goal should be to reduce unnecessary AI calls, reduce unnecessary context, and use the right model only when it is actually needed.
Token efficiency should come from better architecture, not lower-quality reasoning.
Self-healing should not call AI first
Self-healing is one of the most useful AI-related features in test automation.
But it can also become one of the most expensive if implemented poorly.
A bad self-healing system calls AI every time a locator fails.
For example:
The locator failed. Ask AI to inspect the page and find a replacement.That sounds reasonable, but it can become very expensive at scale.
A better approach is to make self-healing work in layers.
The first layer should not be AI.
The system should store backup locators during successful test executions. When a test step works, the system can remember alternative ways to identify the same element.
For example, it might store:
- The primary locator
- A backup XPath
- A CSS selector
- Visible text
- ARIA label
- Element role
- Nearby labels
- Parent container information
- Historical locator versions
Then, if the primary locator fails, the system can try the backup locators first.
Only if those backup locators fail should the system call AI.
This makes self-healing much more efficient.
The flow should look like this:
Primary locator fails
↓
Try stored backup locators
↓
Try historical locator patterns
↓
Try nearby semantic matches
↓
Call AI only as a last resortThis approach reduces token usage because most locator changes can be handled without asking the AI model to reason from scratch.
AI should be the final recovery layer, not the first one.
Cache AI results whenever possible
If the same failure happens repeatedly, the system should not ask AI the same question repeatedly.
It should cache the result.
For example, if a locator changed from:
'[data-testid="submit-button"]'to:
'[data-testid="create-account-button"]'the system can store that repair.
The next time the same locator fails on the same page, the system can try the known fix before calling AI again.
Caching is especially useful for:
- Locator repairs
- Failure explanations
- Suggested assertions
- Generated test steps
- Repeated UI changes
- Common login flows
- Common checkout flows
Caching does not solve every problem, but it prevents repeated token usage for repeated problems.
That matters when tests run many times per day across multiple browsers and environments.
Keep test instructions structured
AI performs better when instructions are clear and structured.
A vague prompt often causes longer answers, more retries, and more token usage.
Instead of writing:
Fix this test. It does not work.Use a structured format:
Task:
Fix the failing locator.
Framework:
Playwright.
Failed step:
await page.locator('[data-testid="save"]').click();
Error:
Element not found.
Expected behavior:
Click the Save button in the profile form.
Relevant HTML:
<button aria-label="Save profile changes">Save changes</button>
Return:
Only the updated locator and one sentence explaining why it is better.This reduces unnecessary output.
It also makes the AI response easier to use.
A good prompt tells the model what to look at, what to ignore, and what format to return.
Limit AI output
Output tokens also cost money.
If you ask the AI to explain every detail, it may generate a long answer that consumes more tokens than necessary.
For test automation workflows, you often need short, structured answers.
For example:
Return only:
1. The corrected locator
2. The reason in one sentence
3. Whether this change is safe or riskyThis is better than:
Explain everything that could be wrong with this test and rewrite it.When using AI inside an automated system, keep the output format strict.
For example:
{
"locator": "button[aria-label='Save profile changes']",
"confidence": "high",
"reason": "The aria-label is more specific than the previous data-testid."
}Structured output is easier to parse and usually shorter than a long natural-language explanation.
Separate test creation from test execution
AI is often useful when creating a test.
For example, a tester might write:
Create a test that signs up a new user, verifies the confirmation email, clicks the activation link, and checks that the user can log in.AI can help transform that instruction into a test.
But after the test is created, normal test execution should not depend on AI for every action.
This distinction is important:
- Test creation can use AI.
- Test maintenance can use AI.
- Failure analysis can use AI.
- Routine execution should avoid AI when possible.
If a test needs AI every time it runs, the cost of that test increases with every execution.
A test that runs once per day may be manageable.
A test that runs across several browsers, several environments, and many pull requests can become expensive very quickly.
Track token usage per test
Teams should track where AI tokens are being consumed.
At a minimum, you should know:
- Which tests call AI most often
- Which steps trigger AI most often
- Which flows produce the highest token usage
- How many tokens are used for creation vs maintenance vs execution
- Which failures required AI and which were solved without AI
- How many AI calls were repeated for the same problem
Without this data, token usage becomes invisible.
And invisible usage usually becomes expensive usage.
A simple internal report can help:
Test: Checkout flow
AI calls this week: 42
Most common reason: Locator repair
Average input size: 8,200 tokens
Average output size: 900 tokens
Repeated failures: 17
Recommendation: Add stable data-testid attributes to checkout buttonsThis kind of reporting helps teams fix the root cause instead of paying AI to handle the same failures repeatedly.
Reduce DOM size before sending it to AI
Sending the entire page DOM to an AI model can be very expensive.
Most of the time, the AI does not need the entire page.
If the failing step is about a login button, the AI probably does not need the footer, analytics scripts, navigation menu, cookie banner, and unrelated sections.
Instead, extract only the relevant part of the DOM.
For example:
const buttonArea = await page.locator('form').innerHTML();Then send only the form HTML to the AI.
Even better, send a simplified version:
<form>
<input type="email" aria-label="Email" />
<input type="password" aria-label="Password" />
<button type="submit">Log in</button>
</form>Reducing the DOM context can dramatically reduce token usage.
It can also improve accuracy because the model has fewer irrelevant elements to consider.
Use AI for verification only when needed
Some verifications require AI.
For example, AI can help determine whether a generated invoice looks correct, whether a dashboard summary matches the expected meaning, or whether a visual change is acceptable.
But many verifications do not need AI.
For example:
await expect(page.locator('.success-message')).toContainText('Payment successful');This assertion is simple and deterministic.
There is no need to ask AI whether the payment was successful if the application already exposes a clear message.
Use AI verification for ambiguous cases, not basic assertions.
Good uses of AI verification include:
- Checking whether a generated document contains the right kind of content
- Reviewing a complex visual state
- Comparing a natural-language summary against expected meaning
- Understanding a failure that may have multiple causes
Poor uses include:
- Checking if text equals a known value
- Checking if a button is visible
- Checking if a URL contains a known path
- Checking if an element exists
The more deterministic the assertion, the less it needs AI.
Design tests so they are easy to update
AI token usage is also affected by how maintainable your tests are.
Tests that are hard to update require more AI help.
Tests that are easy to understand require less AI help.
Good tests should have:
- Clear step names
- Stable locators
- Reusable variables
- Simple assertions
- Minimal custom logic
- No unnecessary dependencies
- A clear connection between the test and the user journey
If a human cannot quickly understand the test, the AI will also need more context to understand it.
That means more tokens.
A test that is easy to read is usually cheaper to maintain with AI.
Why editable tests reduce token usage
Editable tests are more token-efficient than large AI-generated codebases.
When a test is represented as clear steps, the system can update a specific step without processing an entire source code file.
For example:
Step 1: Go to https://example.com
Step 2: Click "Sign up"
Step 3: Enter email
Step 4: Enter password
Step 5: Click "Create account"
Step 6: Verify confirmation emailIf step 5 breaks, the system can focus only on that step.
It does not need to analyze a full Playwright project with fixtures, helper functions, page objects, imports, and custom abstractions.
This is one reason why instruction-based and editable test automation can be more efficient than pure AI-generated code.
The AI can work on the test intent, not the entire codebase.
The risk of ignoring token usage
Ignoring token usage creates two major risks.
The first risk is financial.
You may get a large invoice at the end of the month because AI calls happened more often than expected. This is especially likely when AI is used during test execution, self-healing, or repeated failure analysis.
The second risk is operational.
If the cost becomes too high, the team may need to limit AI usage, reduce test runs, remove AI features, or suspend parts of the automated testing effort.
That defeats the purpose of automation.
The goal of test automation is to increase confidence and speed.
If the AI layer becomes too expensive to run, the test suite becomes harder to justify.
Token usage is an engineering metric as much as a billing detail.
Practical checklist for reducing AI token usage
Here is a practical checklist you can use:
- Do not call AI for simple clicks, typing, waits, or assertions.
- Use AI mainly for test creation, updates, failure analysis, and last-resort repair.
- Avoid sending the entire codebase to the AI.
- Send only the failing step, relevant error, and useful context.
- Use stable locators such as
data-testid, roles, and accessible labels. - Store backup locators during successful executions.
- Try backup locators before calling AI for self-healing.
- Cache AI-generated repairs.
- Keep AI prompts structured and specific.
- Limit AI output to the format you actually need.
- Track token usage per test and per failure type.
- Reduce DOM context before sending it to AI.
- Do not rely on cheaper models as your main optimization strategy.
- Use deterministic assertions whenever possible.
- Prefer editable tests that can be updated step by step.
These practices reduce waste without removing the benefits of AI.
How Endtest handles AI token usage
Endtest was designed to avoid many of the token problems that appear when teams bolt AI on top of code-based frameworks.
With Endtest, tests are editable, structured, and easier to maintain. AI does not need to process a large Playwright or Selenium codebase every time a test needs to be created or updated.
Endtest also provides Unlimited AI.
That means teams do not have to worry about token usage, monthly AI limits, or surprise invoices caused by automated testing activity.
We can offer this because Endtest uses highly optimized specialized models that were built and trained for test automation. Instead of using general-purpose AI for every action, Endtest uses models and workflows designed specifically for creating, maintaining, and improving automated tests.
Endtest is the only testing tool on the market that offers Unlimited AI, so teams can focus on building reliable test coverage instead of calculating how many tokens each test run might consume.
You can learn more about Endtest features on the product page or see the available plans on the pricing page.
Final thoughts
AI can make test automation faster, but only if it is used carefully. The goal is to use AI where it adds real value, not to remove it from testing.
Do not use AI for actions that deterministic automation can handle. Do not send huge codebases when a small snippet is enough. Do not call AI first for self-healing when stored backup locators can solve the problem. And do not assume that switching to cheaper models will preserve the same level of accuracy.
Token-efficient AI test automation is about architecture.
The best systems use AI for creation, maintenance, reasoning, and recovery, while keeping normal test execution stable, predictable, and affordable.