The UI says saved and no row is written — how do I assert on the database?
Asked 5,480 views3 answers
29votes
We keep getting the same class of bug: the form submits, the toast says saved, the UI shows the new item from local state, and nothing was persisted. It survives every UI assertion we have because the UI is not lying about what it believes.
I can see there is a database configured for SDODS itself. Is there a step to assert against our application's database from a scenario?
No database assertion steps in the shared library. There is an open issue with the step set designed — row counts, column values, capture-a-value-into-a-variable — and none of it is written.
The fixture is there though, so project steps over it are small. What you want is roughly:
gherkin
Then the table "items" should have 1 rows where "name" is "{{itemName}}"
Then the column "status" of the row in "items" where "id" is "{{itemId}}" should equal "active"
Write those two and you have covered the whole silent-success class, which is what you actually came for.
One design note while you are writing them: make the "where" a single indexed column rather than allowing arbitrary SQL through the step. A step that takes a fragment of SQL is a step nobody can review in a feature file.
Before you write those, check whether an API read gets you the same assertion. If there is a GET that returns the thing you just created, that is the far-side check, and it costs you nothing in coupling:
gherkin
When I send a GET request to "/items/{{itemId}}"
Then the response status should be 200
Then the response JSON path "status" should equal "active"
A database assertion binds your suite to the schema, so every migration becomes a test change. Worth it for things with no API surface — audit rows, side-effect tables, soft deletes — and not worth it for anything you can read back through the product.
If you do go direct, add the cleanup at the same time and not later. I register cleanup handles it where the API can delete the thing:
gherkin
When I register cleanup DELETE "/items/{{itemId}}"
We wrote the assertions first and the cleanup "next sprint", and spent a fortnight with a staging database full of test rows that then broke the row-count assertions we had just added.