3 ms·
Disagree about DB tests. If you want to test queries, then it's bad idea to mock DB. If you don't want to test queries, don't call your tests coverage full.
by EugeneOZ 11y ago
Disagree about DB tests. If you want to test queries, then it's bad idea to mock DB. If you don't want to test queries, don't call your tests coverage full.
- narrator 11y agoThe best way to do db testing is with an empty db and in a specialized dao test. Try to make these dao tests non-overlapping so that the dao test is the only test that hits that part of the schema. Also, if your dao tests are the only thing that hit I/O you can safely do all the other non-integration tests concurrently. Service layer tests should have mocks of the dao and web service calls. You should do most of your testing here and with unit tests for tricky algorithms. Integration tests should hit the full stack, but those should run on a continuous integration server asynchronously and also take place in their own empty database. The key to dao and integration testing is the empty database. Don't let it fill up with test crud between tests. PostgreSQL is pretty fast when your test db only has a couple of rows.
- raducu 11y agoThis is by far my favorite way to test; not something I invented but something I picked up start with an EMPTY DATABASE (with tables setup), then every test: begins a transaction,asserts the db is empty, sets up the data (via factories and DAOs), performs its queries (via DAOs) rolls back the transaction for the next test.
- lmm 11y agoIt's a fast approach that gives some test coverage, but some of the most important things to test are around the interaction of multiple transactions, which you can't do if you're using a single big transaction to run your test.
- mattmanser 11y agoAn empty DB? Some major bugs are caused by people not testing their code with enough data.
- EugeneOZ 11y agoNot production DB, obviously :) Generate data before tests, collect list of created records during tests, remove collected items after all tests - if DB is not empty after it, you can see something unexpected has happened. If it's not possible to collect records (because of too opaque ORM), just flush DB.
- waffle_ss 11y agoSame. Not only to ensure I wrote queries or scopes correctly, but also because I like to add extra validation constraints to be sure my application code can't sneak junk into the database. How can I really ensure my CHECK constraints / DOMAINs, unique indexes, RAISE EXCEPTION in insert/update triggers, etc. are correctly implemented if I'm not testing against a real Postgres database?
- whoisthemachine 11y agoI would recommend writing tests specifically for testing the PostgreSql changes, ideally you can write them purely in PostgreSql, maintaining a nice separation of your code and your SQL. Also, the only thing that should really need proper testing are stored procedures, your check constraints can't possible be so complicated that they warrant tests. The unit tests that test out your business logic should use mock data - it's just much more reliable, reproducible, and faster.
- tracker1 11y agoThat doesn't mean your data/db access needs to be in the same project, or tests as the rest of the application... if you haven't touched the db bits, don't run the db tests. It's about creating appropriately sized discrete modules.
- EugeneOZ 11y agoOne of things unit-tests gives is fearless refactoring. When you can easily change behavior in one module and tests shows other modules are not affected (or affected). When you test only one module/layer you don't see the whole picture and such tests are much less representative and useful.
- bpicolo 11y agoOnly fearless if you're not using mocks/stubs/etc. With mocks and stubs in a dynamically typed language it's not quite as fearless.
- douche 11y agoDynamically typed languages are an anti-pattern, where they are not unavoidable - i.e. web front-ends.
- collyw 11y agoBollocks. If your database schema changes right at the heart of the data model, a load of unit tests are not going to save you from some serious hassle.