How to Generate Tests From an Existing Codebase

Most real projects don't have a PRD that's kept up to date, if they ever had one at all. The spec lives in commit messages, Slack threads, and the founder's memory.
That doesn't mean an ai test case generator is off the table. It means the starting point shifts from a document to the code itself. Here's how that works, and what to check before trusting what it produces.
Why code-only test generation is a different problem
When a written PRD exists, an agent can anchor test goals to what the product is explicitly supposed to do. Without one, the only available signal is what the code currently does, which introduces a specific risk: if the implementation has a bug, a test generated purely from that implementation can quietly encode the bug as correct behavior, since there's no independent statement of intent to check against.
Good codebase-inference doesn't just describe the current implementation. It has to infer intent, what the code is trying to accomplish, not just what it happens to do line by line. That distinction is what separates a genuinely useful inferred PRD from a test suite that just mirrors existing bugs back at you, and it's the specific problem TestSprite's MCP Server is built to handle.
How TestSprite infers intent without a PRD
Through the MCP Server in your IDE, TestSprite analyzes your project structure, route definitions, component hierarchy, and API contracts, and builds a normalized internal PRD from that analysis. It's not reading the code to describe what exists; it's reading the code to reconstruct what it was likely built to accomplish.
“Other verification tools read your code and guess. TestSprite opens your app and uses it.”
That second half matters as much as the first here. Static code analysis alone can miss flows that only show up when the product actually runs, a feature gated behind a user role, a multi-step wizard that only appears after a specific action. Pairing codebase inference with live exploration of the running app is what catches those.
The practical process
Point the agent at your codebase and your running application, not just one or the other. Setting up a new projectthrough the MCP Server is where this analysis starts, combining static structure with what the exploration agents find by actually navigating the app.
Review the inferred PRD before trusting generated coverage. This is the step that matters most when there's no written requirements document to check against. Read through what TestSprite concluded your product is supposed to do, and correct anything it got wrong before that becomes the basis for dozens of generated tests.
Check codebase clarity as a factor in reliability. A codebase with clear naming, consistent patterns, and visible structure gives an inference engine much more to work with than one that's grown organically without much internal consistency. This isn't a reason to avoid codebase-based generation on a messier project. It's a reason to expect the first review pass to matter more there.
Let exploration catch what static analysis alone would miss. Parallel exploration agents navigate the live application the way a real user would, reporting back a structured map of what they found. Watching that exploration happen is also a useful sanity check in itself: if the agents miss an important flow, that's worth acting on before you trust the resulting coverage.
When a written PRD is still worth writing
Codebase inference is a genuinely capable fallback, not a permanent substitute for intent documentation. If a project matures to the point where multiple people are working on it, or a feature's correct behavior genuinely isn't obvious from the code alone (a business rule with edge cases that only exist in someone's head), writing even a short PRD at that point will noticeably sharpen what TestSprite generates from it going forward. Once you do have one, adding coverage for a new feature from that PRD is the same workflow, just with a clearer source to start from.
How to tell whether the inferred PRD is actually accurate
Before trusting generated coverage on a codebase-only project, it's worth spending a few minutes comparing the inferred PRD against what you know the product is supposed to do, rather than assuming the inference got everything right. Look specifically for two failure modes: features described in terms of their current implementation rather than their intent (a sign the inference leaned too heavily on code structure and not enough on exploration), and missing edge cases that only exist because of a business rule nobody wrote down anywhere the agent could find it.
Neither failure mode means the approach doesn't work. Both are exactly the kind of gap a quick human review catches early, before it becomes the basis for a test suite that quietly validates the wrong thing. The more consistent and readable your codebase is, and the more thoroughly the exploration agents get to walk through your live application, the smaller this gap tends to be from the start.
A related check worth doing on an older codebase specifically: look for features that were clearly built, then partially abandoned or replaced, without the old code being removed. Inference has no way to know that a route or component is dead weight rather than an active feature, so it's worth flagging anything the inferred PRD describes that you know for a fact nobody uses anymore, before generated tests start verifying behavior nobody actually needs preserved. A short note in the review pass is usually enough to keep that dead weight out of the generated suite entirely.
Conclusion
Generating tests from an existing codebase without a PRD is a real, workable path, not a compromise. It shifts where your review attention needs to go: instead of checking that generated tests match a document you already trust, you're checking that TestSprite's inferred intent actually matches what you meant, before that inference becomes the basis for everything downstream.
TestSprite's MCP Server handles this inference directly from your codebase when no PRD exists, no separate documentation step required to get started. Try it on your own project for free and see what it infers. Comparing that inferred PRD against your own understanding of the product is usually the fastest way to find out whether the codebase is clear enough for this approach to work well, or whether a short written PRD would sharpen the results.