How Do I Generate Automated Tests from an Existing Project?

Zheshi Du
How Do I Generate Automated Tests from an Existing Project? cover

Most projects reach the same point eventually.

The product is live. Users are active. The codebase has grown past the point where any one person understands all of it. And somewhere along the way, the team skipped writing tests. Not out of negligence, but because there was always something more urgent to ship.

Now the cost of that trade-off shows up every time someone touches the code. A change in one place breaks something unexpected somewhere else. Nobody is sure what's safe to refactor. Every deploy feels like a risk.

The answer is generating automated tests from what already exists. The question is how to do it without spending weeks writing test files that are outdated before they're finished.

The Problem with Generating Tests by Reading the Code

The obvious approach is to point a tool at your codebase and let it generate tests from what it finds.

Code-layer test generation reads your source files, traces function signatures and component structures, and produces test scripts that assert against the current implementation. It's fast. It produces coverage numbers. And it has a fundamental problem that shows up the first time someone runs the suite against a real environment.

Tests generated from code inspection are assertions about what the code does today. They're not assertions about what the product should do. If the existing code has bugs, which every existing project does, those bugs get encoded as expected behavior. The generated tests pass. The bugs stay.

There's a second problem. A test suite generated from code inspection is a snapshot of the implementation at a specific moment. The moment the product changes, which it will the same day the tests are generated in a team using AI coding tools, the tests start decaying. Selectors break. Assertions fail against updated return values. The maintenance burden begins immediately.

Generating tests that are actually useful requires a different starting point. Not the code. The product.

Start from What the Product Does, Not What the Code Says

The right way to generate tests from an existing project is to start from the running application, explore how it actually behaves, and build a test suite grounded in that observed behavior.

That's what a QA engineer does when they're brought into a project that has no test coverage. They don't read the source files first. They open the application, walk through every feature they can find, note what each one is supposed to do, and start building test cases from those observations.

They're testing the product, not the code. The resulting tests are grounded in product behavior. They'll survive refactors that don't change what the product does for users, because the tests describe user-observable outcomes, not implementation details.

TestSprite automates exactly this process.

How TestSprite Explores an Existing Project

When TestSprite is pointed at an existing project, it doesn't begin with the codebase. It begins with the running application.

Through the TestSprite MCP Server inside Claude Code, Cursor, Windsurf, or any MCP-compatible AI IDE, a single instruction kicks off the full discovery process:

"Help me test this project with TestSprite."

A fleet of parallel exploration agents visits the live application and navigates it the way real users would. They move through every discoverable feature, click through UI flows, interact with forms and modals and navigation, and build a structured map of what the product actually does.

Other verification tools read your code and guess. TestSprite opens your app and uses it.

The agents aren't looking for functions to assert against. They're looking for user journeys to verify. The output of the exploration phase is a structured model of real product behavior: what users can do, what paths they follow, what outcomes they should reach. That model becomes the basis for test generation.

If a PRD or specification exists, TestSprite parses it and anchors test goals to product intent. When one doesn't, the MCP server reverse-engineers intent from the codebase itself, treating route definitions, API contracts, and component structures as evidence of what the product was built to accomplish. Either way, the resulting tests are grounded in what the product should do, not what the current implementation happens to produce.

What Gets Generated and Why It Holds Up

The tests TestSprite generates from an existing project cover the full surface of what the exploration agents discovered.

Frontend flows get covered by test cases that describe user interactions and expected outcomes. The agent navigated a checkout flow, observed the steps, and generated a test that runs those steps and verifies the outcome at each point. The agent found a multi-step onboarding wizard, traced the paths through it, and generated tests that cover the happy path and the edge cases it discovered while exploring.

Backend APIs get covered through Backend Testing 2.0. Before generating any API test, the agent calls the endpoint and observes the real response: actual status codes, actual field names, actual response shapes. Assertions are grounded in that observation. CRUD lifecycle tests capture real IDs from real create responses and pass them to downstream steps automatically. The full lifecycle runs end to end on the first attempt.

What holds these tests up over time is that they're anchored to behavior, not implementation. A test that describes what a user does and what they should see survives a refactor that changes how the code produces that result. A test that asserts against a specific function's return value doesn't.

Running Without a Local Environment

One of the practical barriers to generating tests from an existing project is the environment setup. A team that has never had formal test infrastructure often hasn't set up a test environment either. Running a test suite locally means dealing with database state, external service dependencies, authentication configurations, and environment variables that may or may not be documented.

TestSprite handles this through its ephemeral cloud sandbox. Tests execute in a secure, isolated environment that spins up in seconds, runs the suite, and tears down automatically. There's no local environment to configure, no test database to maintain, no infrastructure to provision.

The team points TestSprite at the staging or preview environment URL. The exploration agents visit it, generate the tests, and execute them in the cloud sandbox. The results come back to the IDE. The team has a running test suite without setting up any test infrastructure.

The Maintenance Problem, Handled at the Start

Any team that has lived through a legacy test suite knows the real cost isn't generating the tests. It's keeping them running six months later.

TestSprite's Auto-Heal Rerun addresses this directly. When a test fails on rerun after a product change, the agent determines whether the failure reflects a genuine behavioral regression or a UI update that doesn't affect the underlying flow. A renamed component, a moved button, a restyled form: the test adapts rather than failing falsely.

The suite stays current as the product evolves. Genuine regressions surface clearly. The team doesn't spend maintenance cycles updating selectors after every design change.

For teams integrating CI for the first time alongside their test suite, the GitHub Actions integration brings the pipeline directly into the pull request workflow. Every code change gets automated coverage. Results post as PR comments. The transition from no test coverage to CI-integrated automated testing happens in a single setup, not a multi-month migration project.

Auto-Auth handles the authentication layer for projects with login flows. Password endpoints, OAuth refresh tokens, and AWS Cognito configurations run automatically before every test execution. Scheduled regressions don't fail on stale credentials.

Conclusion

Generating automated tests from an existing project doesn't have to mean spending weeks producing a test suite that's already outdated.

The approach that actually holds up is the one that starts from the running product rather than the source code. Explore how the application behaves. Build tests grounded in that observed behavior. Cover the full product surface, including frontend flows, backend APIs, and authenticated paths, from a single starting point.

TestSprite does this autonomously. Its exploration agents navigate the live application like real users, generate tests from what they observe, and maintain those tests through Auto-Heal as the product evolves. The team goes from no test coverage to a running, CI-integrated suite without writing a single test case by hand.

Generate your first automated test suite from your existing project with TestSprite

today.