The honest starting point

If you cannot read the code, you cannot review the code, and you should stop feeling bad about that. The alternative is not reviewing; it is checking behavior. That is what your users will do anyway, and it catches a class of problem that reading would miss.

Where Lovable code bugs usually are

Generated apps fail in a predictable order. Check these first.

It looks saved but is notA form shows a success message, and the record is gone after a refresh. Always reload the page before believing a save.
Empty and error statesThe happy path was built and demonstrated. The zero-results and failed-request cases often were not. Try it with no data, and with a deliberately wrong input.
The second userEverything works for the account that built it. Permissions, ownership and visibility are the first things to break for anyone else. Sign in as a second account before you show anyone.

The check that keeps working

Checking by hand is fine for a weekend project and stops scaling the moment you keep prompting. Every new instruction can silently undo something that worked yesterday, and a manual pass gets shorter each time you do it.

What you want is for the checks to be written down and run automatically, described in plain language rather than in test code. Setup puts that capability in the agent's hands so the checking happens alongside the building.

All of this is available in the TestSprite dashboard too, which is usually the better route if the terminal is not where you work. The CLI details live in the CLI repository.

Three checks worth having from day one

  • Sign up, then sign in again. More generated apps break here than anywhere else, and it is the first thing a real user does.

  • Create something, reload, confirm it is still there. This single check catches the most common and most embarrassing failure.

  • Do the one thing your app is for, as a brand new account. If that works for a stranger, you have something.

How to describe a bug so the fix actually lands

When something is wrong, the instinct is to say "this is broken". That gives the agent very little, and you will get back a change that fixes something adjacent.

Three sentences do much better, and you do not need technical vocabulary for any of them. What you did, in order. What you expected. What happened instead. "I filled in the form and pressed save, I expected to see the new item in the list, the list was empty until I reloaded" is a genuinely good bug report, and it points straight at the defect.

The same three sentences are also the check you keep. Written down once, they can be re-run after every future change, which is how you stop the same problem coming back.

The order to check things in

There is a sequence that finds problems faster than clicking around, and it takes about ten minutes.

Start signed out and sign up as a brand new user, because that path is the one you have personally used least. Then do the single thing your app exists to do, all the way to the end, and reload the page before believing any of it. Then do it again wrongly: leave a required field blank, put text where a number goes, upload something absurd. Then delete something and confirm it is actually gone rather than hidden.

Each of those four takes a minute or two and each maps to a cluster where generated apps fail. Doing them in that order matters, because a broken signup makes everything after it untestable, and people routinely spend an hour on a feature that nobody can reach.

When you are ready to share it

Before an app goes anywhere real, have the checks run automatically on every change rather than when you remember. Two ways to do that:

Connect the repository from the dashboard and runs start from the deployment you already produce, or add a step to your own workflow instead.

How TestSprite does the checking for you

You describe what should be true in plain language and TestSprite does the clicking. No test code, no framework, no terminal required: create a project in the dashboard, point it at your app, and say what a working version looks like.

The four clusters in this page are exactly what it covers. It signs up as a new account, creates something and reloads to confirm it persisted, submits something invalid to check the app says so, and runs the same flow as a second user to catch the permission assumptions built into your own session.

The part that matters as you keep prompting is that the checks stay. Every change gets verified against everything that worked before it, which is what stops the loop where fixing one thing quietly breaks another.

Do I need to know how to code for this?

No. The checks are described in plain language and run against the app through its interface, the same way a person would use it.

Why does my app work for me and not for others?

Usually permissions or data ownership. The account that built the app has records and access that a new account does not. Testing as a second user surfaces this immediately.

Should I test before or after prompting more?

Both, and the second one matters more. A check that existed before your latest instruction is what tells you whether that instruction broke something.

What if the fix keeps breaking something else?

That is the signal to have checks running continuously rather than at the end. Each change gets verified against everything that worked before it.

Is this only for Lovable?

No. The same failures show up in anything generated quickly, whatever produced it. Lovable users hit them earlier because they ship sooner.

The short version

You cannot review the code. You can check the behavior.

Most Lovable code bugs are saves that do not persist, missing empty states and things that only work for the account that built them. Check those three first, then make the checks automatic before you share the app.