4 ms·
> To ensure each test has a clean slate, we clear the database between each test. The proposed solution to manually nuke the database state seems crazy to me.
by rraval 10y ago
> To ensure each test has a clean slate, we clear the database between each test.
The proposed solution to manually nuke the database state seems crazy to me. Some alternatives:
1. Run the entire test in a transaction, do flushes and assert as normal. At the end, ROLLBACK instead of COMMIT and now you have a pristine database again. [1]
2. Setup pristine DB state once and then use `CREATE DATABASE ... WITH TEMPLATE ...` to create a temporary database. Not sure what the perf hit is, but it's probably worth trying. [2]
[1] http://alextechrants.blogspot.ca/2013/08/unit-testing-sqlalchemy-apps.html http://alextechrants.blogspot.ca/2013/08/unit-testing-sqlalc...
[2] https://www.postgresql.org/docs/9.4/static/manage-ag-templatedbs.html https://www.postgresql.org/docs/9.4/static/manage-ag-templat...
CREATE DATABASE actually works by copying an existing database. By default, it copies the standard system database named template1.
- kevinburke 10y agoHi, I wrote the post. We'd love to use transactions but our ORM doesn't support it. More info here: https://kev.inburke.com/kevin/dont-use-sails-or-waterline/ https://kev.inburke.com/kevin/dont-use-sails-or-waterline/ We wrote our own transaction library and have been shifting queries over to it/a saner ORM. https://github.com/shyp/pg-transactions https://github.com/shyp/pg-transactions. I've never heard of database templates, I'll have to take a look.
- agf 10y agoIf your ORM doesn't know about transactions, that doesn't necessarily prevent you from wrapping your test runs in transactions. I was in a situation where I needed to start / rollback a transaction without ActiveRecord knowing about it, and was able to hack AR slightly to make that work -- so you can likely do the same. You even mention in the Waterline section of that blog post that you've written your own transaction library, so this shouldn't be too hard.
- rraval 10y agoOne advantage of the template approach is it allows for test level parallelism, which may address your primary goal of performance. > Waterline queries are case insensitive; that is, Users.find().where(name: 'FOO') will turn into SELECT * FROM users WHERE name = LOWER('FOO');. There's no way to turn this off. If you ask Sails to generate an index for you, it will place the index on the uppercased column name, so your queries will miss it. If you generate the index yourself, you pretty much have to use the lowercased column value & force every other query against the database to use that as well. What the actual fuck!