The tests and the HTML report are where AI-written database code becomes visible. Generate them, run them against the real database, and read exactly what each function does before you trust it.
Every branch the AI wrote, run and shown
The expected value is what it really returns, not what the prompt claims
Uncovered lines named, so you see what the AI left unreachable
Free and local, no CI needed to look
Where the output shows up
Community Edition. You wrote a function, or an assistant did. One command generates the tests, runs them, and writes a report you open in the browser.
Install pgTAP and plpgsql_check; connect with DATABASE_URL or the PG* variables.
Run the default command and point it at an HTML report:
unitautogen --schema public --html report.html --out unit_tests
Open report.html. Every function is there with its coverage; click one for its per-test results and annotated source.
Nothing to write, the tests and the seed data are generated
Runs on your own database, nothing leaves your machine
Put it in the assistant's loop
The assistant that wrote the function can check its own work against the report, but only if you tell it to, step by step.
Install once. The binary, plus pgTAP and plpgsql_check in your development database. Connect with DATABASE_URL or the PG* variables.
Add a project rule, or paste the prompt below, so the assistant runs UnitAutogen every time it writes or changes a function.
Give the assistant this prompt.
After you add or change any PL/pgSQL function, run this and wait for it to finish.
unitautogen --schema public --json report.json --html report.html --out unit_tests
Then read report.json. For every function you touched:
1. Confirm its branch coverage is 100 percent.
2. Open its generated test in unit_tests/ and read the value each branch returns.
3. If a branch is uncovered, or a returned value is not what I asked for, change
the function and run the command again.
Never edit or delete the generated tests to make them pass. When you are done, tell me
which functions you changed, their coverage, and any behaviour in the report I should confirm.
The assistant reads report.json, you open report.html to see the same thing
It fixes the function, never the test, so a green result still means something
What the report makes visible
One row per function, with its measured line and branch coverage
Click a function for each generated test and whether it passed
The annotated source, covered lines in green and uncovered in red
Each expected value captured by running the real function, so the report shows what the code does, not what it was meant to do
Every uncovered line explained, so a branch the AI left unreachable is named, not hidden
Why AI-written code needs it
You did not write the function, so you cannot hold its behaviour in your head, and the model's own summary of what it did is one more guess.
The report is the function's real behaviour, executed against your database
A branch the AI got subtly wrong shows up now, in the loop, not in review
A line the AI wrote that nothing can reach is surfaced as an uncovered line
You see it before you commit, while the change is still cheap to fix
This is transparency, not a gate. It shows you what the AI produced. Once you have looked and you trust it, the same generated tests become your regression guardrail, so the next change that moves that behaviour fails before production.
The platform points you to local pgTAP tests you run and read as you build.
Supabase shows you writing pgTAP tests and running them locally with supabase test db for immediate pass or fail. UnitAutogen writes those tests for you and adds the coverage report. Supabase, Testing overview →
Supabase ships pgTAP as its unit-testing extension for functions and policies. UnitAutogen emits standard pgTAP, so the report reads the same tests you would run by hand. Supabase, pgTAP unit testing →
Your privacy
We would like to log your visit to see how the site is used. That records the page, the site you came from, your IP address and browser, and a random id for this tab. We delete it once we no longer need it.