5 ms·
Just use a new transaction for each test and have them all roll back when the test finishes. It leaves the db in a clean state for the next test
by weird-eye-issue 6y ago
Just use a new transaction for each test and have them all roll back when the test finishes. It leaves the db in a clean state for the next test
- hobs 6y agoThat is much slower for any test of meaningful size.
- weird-eye-issue 6y agoEh I have run hundreds of tests in Django in like 15 seconds
- hobs 6y agoThe count of tests is not important, the size of the data is.
- weird-eye-issue 6y agoIt was a huge monolith schema. As far as the size of the data being created during the tests, quite small, since they would test individual pieces. Very data intensive tests seems like an outlier for most types of tests I've seen.
- hobs 6y agoYep, I mostly am working integration tests for large ETLs, unit tests dont need this.
- tfussell 6y agoWhat if your test includes a transaction already?
- branko_d 6y agoWe make tests robust in the face of existing data. For example, each name is "GUID-ified", we only compare specific subsets of rows that we know will be isolated from the rest etc... We still use transaction rollback for most of our tests, but all tests are written with the assumption of existing data, to accommodate for the few tests that must commit their transactions (such as concurrency tests).
- augustl 6y agoThis is the way to go imo! It also enables parallelization of test runs :) And it also makes testing databases with limited transaction APIs (like DynamoDB) much easier.
- eloff 6y agoTypically the approach I take is monkey patch out the transaction methods (begin, commit, rollback) in the test harnesses and wrap each test in a real transaction. Some test runners have this built in. This is easy in dynamic languages, really hard in in static languages.
- tpetry 6y agoCouldnt you just patch the transaction logic to savepoints? So even tests building on transactional behaviour would work correctly.
- eloff 6y agoI seem to recall savepoints differ in some ways that can make this difficult - but without remembering the specific problem I hesitate to say anything concrete about that.
- chrisandchris 6y agoSo you‘re testing against a database some process that you expect to fail ond you would like to test whether the rollback is done properly. And because you abstracted all your transaction logic away for the tests, your test result is not worth anything. IMHO, there are only 2 ways to achieve proper database testing: 1) new db for each test (very slow) or delete all data from all tables before the test (ok for smaller projects) 2) tests do absolutely have no impact on other tests with the data they added/modified/dropped (very hard to achieve). Edit: typo