Automated Testing for Lovable Apps: Built-In or External?
TL;DR: Automated testing for Lovable apps should start with Lovable’s built-in browser, frontend, and backend checks while you build. Add an independent browser test against the published URL for the few flows you need to prove after every release. The useful setup is not one tool replacing the other; it is Lovable for fixing the project and an outside check for verifying what a user can actually do.
Lovable can now build an app, open it in a browser, click through a flow, write frontend tests, and check backend functions. That is a big improvement over treating the preview as proof that everything works.
It also changes the question. You no longer need to ask whether automated testing for Lovable apps exists. You need to decide which checks belong inside the builder, which ones should run against the published app, and which two or three flows are important enough to repeat.
What automated testing for Lovable apps already includes
Lovable’s own testing documentation separates testing into three useful layers.
Browser testing drives the app like a user. It can navigate pages, fill forms, submit requests, take screenshots, and inspect console and network activity. Use it when you are debugging a visible problem or checking a multi-step flow such as onboarding or checkout.
Frontend tests check a specific rule in a simulated browser. Lovable writes these with Vitest and React Testing Library, so they are a good fit for questions such as, “Does this error appear when the email is invalid?” They run quickly and live beside the component they protect.
Backend verification calls an edge function directly or adds a test for it. That is the right layer for permissions, calculations, and other rules that are hard to prove by clicking through the interface.
If you are still building the feature, start here. Lovable can see the project, inspect failures, change the code, and run the relevant check again. An outside browser tool cannot match that level of diagnosis because it sees the rendered app, not the files behind it.
Why test the published URL separately
Publishing is a real boundary. Lovable describes a publish as deploying a snapshot of the current project to a live URL; later edits do not reach that URL until you publish again. The publishing guide also makes clear that a custom domain, access rules, and the live version are managed separately from your work in the editor.
That boundary creates failures an in-project test can miss if you only run it before publishing. An environment value can be absent on the live deployment. An email confirmation link can point to an old host. An OAuth callback can accept the Lovable address but reject your custom domain. A cookie can behave differently once the origin changes.
An independent test is useful here because it starts with the same thing a new user has: the public URL. It does not know that the preview worked. It only knows whether the live signup form accepts an email, whether the confirmation link returns to the right domain, and whether the dashboard loads after login.
This is a complement to Lovable’s testing, not a verdict against it. Use the builder to understand and fix the code. Use the outside check to prove that the version people can visit still completes the flow. If you are close to launch, the broader QA checklist for a Lovable or Bolt app covers the one-time checks that sit around this loop.
Choose the first flows by damage, not convenience
Do not begin by asking an agent to explore every page. A broad crawl creates a long report, but it can still miss the one path your business depends on.
Write down the two or three failures that would cost you a user or a payment. For most small apps, the list starts here:
- A new visitor can create an account and reach the correct first screen.
- A returning user can sign in and complete the main action the app exists for.
- Data created by that action is still there after a reload or a fresh login.
Make each instruction end with something visible. “Test signup” is vague. “Create an account with a new email, sign in, and confirm that the empty dashboard appears” gives the browser a finish line.
Keep destructive actions out of recurring tests unless you have a safe test account and a cleanup plan. If your flow sends email, creates records, or touches a payment provider, use test data and the provider’s sandbox. Automation that leaves a trail of fake customers is not saving you work.
Put those flows in a two-layer testing habit
The simplest process fits around the way you already ship.
While you are building, ask Lovable to browser-test the changed flow. If the bug is a precise UI rule, ask it to add a frontend test. If the failure sits in an edge function, test that function directly before clicking through the whole app again.
After you publish, run the critical flow against the published URL in a fresh session. This is where you catch the domain, session, redirect, and live-data problems that only exist outside the editor.
Then re-run the same outside flow after every release that could affect it. Do not rewrite the instruction each time. A stable sentence gives you a stable expectation even when Lovable rearranges the page beneath it. That repeated check is regression testing; the practical version for a one-person team is explained in regression testing without a QA engineer.
Lovable notes that most of its verification tools run when you ask for them, not silently in the background. That is fine for active development. The outside layer earns its place when you want the live check to be repeatable without reopening the project and remembering every step yourself.
How WayRunner handles the outside layer
WayRunner starts with the published URL and a plain-English instruction. A Planner looks at the current page and decides one action. A separate Executor carries it out in a real Chromium browser, returns a fresh observation, and lets the Planner decide what comes next. The test follows the rendered app instead of a stored list of selectors, so moving a button does not automatically make the instruction meaningless.
The part that took more care was unattended testing. Some flows stop at a challenge that genuinely needs a person. Others request a credential that has not been approved for that run. WayRunner’s scheduler pauses in those cases instead of clicking around, claiming a pass, or repeatedly burning runs. You resolve the human step, then decide when the schedule is safe to resume.
Credentials take a separate path too. An isolated broker holds the secret, while the planning model sees only an opaque reference. The real value is fetched in memory at the moment the Executor types it. That lets a login flow run without putting the password into the model’s reasoning transcript.
This outside view has a deliberate limit: it can tell you what the user-visible flow did, capture where it stopped, and explain the failure in plain English. It cannot inspect your Lovable project and patch the source. When it finds a problem, take the evidence back to Lovable, fix it there, publish the new snapshot, and run the same external check again.
The takeaway
Automated testing for Lovable apps works best as two connected loops. Use Lovable’s own tools to test and repair the project while you build; use an independent browser against the published URL to protect the few journeys your users cannot afford to lose. Start with one signup flow and one core action. If those checks stay reliable, add the next flow because it matters, not because a testing dashboard looks empty.
If you want to run that outside check with a URL and a sentence, join WayRunner’s early access.