Timeline for Unit-Tests and databases: At which point do I actually connect to the database?
Current License: CC BY-SA 3.0
15 events
| when toggle format | what | by | license | comment | |
|---|---|---|---|---|---|
| Aug 3, 2020 at 8:44 | comment | added | Olivier | If you're a nodejs dev, you should check out my lib github.com/oguimbal/pg-mem to get rid of the isolation problem :) | |
| Sep 20, 2019 at 15:54 | comment | added | Jeryl Cook | Never test against a database in unit tests. which is suppose to be isolated and fast. | |
| Dec 1, 2016 at 19:49 | comment | added | 425nesp | Testing against a database is fine, but that's not a unit test. That's an integration test. | |
| Aug 1, 2013 at 16:40 | comment | added | KeithS | @leo: yes, because they would test two different things. The unit test, asserting on generated SQL, would assert that the SQL matched what you expected the generator to produce, which is what you want to know when you're coding the generator. The integration test that used this SQL to retrieve results from the RDBMS would then test many other things, mostly ensuring that the generator, when plugged in, works as expected in the larger system. | |
| Aug 1, 2013 at 16:34 | comment | added | leo | @KeithS What if your code is a database abstraction layer? Should one simply assert on the generated SQL string and then replicate nearly identical tests for the integration suite? | |
| Jul 30, 2013 at 16:35 | comment | added | KeithS | I think we are as well. I use a "unit-testing framework" (NUnit) for my integration tests as well, but I do make sure to segregate these two categories of tests (often in separate libraries). The point I was trying to make is that your unit test suite, the one you run several times a day prior to each check-in as you follow the iterative red-green-refactor methodology, should be completely isolatable, so that you can run these tests several times a day without stepping on your co-workers' toes. | |
| Jul 30, 2013 at 15:45 | comment | added | Reactgular | @KeithS I think we're debating over semantics. It's not about what the definition of a unit test is or an integration test is. I use fixtures to test code dependant upon a database connection. If that's an integration test, than I'm fine with that. I need to know that test passes. I couldn't care about the dependencies, performance or risks. I won't know if that code works unless that test passes. For the majority of tests there are no dependencies, but for the ones where there are, then those dependencies can't be uncoupled. It's easy to say they should be, but they simply can't be. | |
| Jul 30, 2013 at 15:38 | comment | added | KeithS | @gbjbaanb - That sounds fine at first, but in my experience it's very dangerous. Even in the best-architected test suites and frameworks, the code to rollback this transaction may not execute. If the test runner crashes or is aborted inside a test, or the test throws out a SOE or OOME, best-case is you have a hanging connection and transaction in the DB that will lock up the tables you touched until the connection's killed. The ways you prevent this causing problems, such as using SQLite as a test DB, have their own downsides, for instance the fact you're not really exercising the real DB. | |
| Jul 30, 2013 at 15:29 | comment | added | KeithS | Call me a purist, but I hold to the tenet that a unit test should not perform any actions that leave the "sandbox" of the testing runtime environment. They shouldn't touch databases, file systems, network sockets, etc. This is for several reasons, not the least of which is dependency of the test on external state. Another is performance; your unit test suite should run quickly, and interfacing with these external data stores slow tests by orders of magnitude. In my own development, I use partial mocks to test things like my repositories, and I'm comfortable defining an "edge" to my sandbox. | |
| Jul 30, 2013 at 15:21 | history | edited | Reactgular | CC BY-SA 3.0 | added 193 characters in body |
| Jul 30, 2013 at 15:19 | comment | added | Reactgular | @gbjbaanb yea, that is what fixtures do in CakePHP. They build and insert the data for you, easily and quickly. It doesn't change unless you change the unit test. The majority of Cake developers have a database they can use for testing. | |
| Jul 30, 2013 at 15:17 | comment | added | gbjbaanb | I assume he means you are dependent on the data in the DB, but you simply set up a DB connection in your unit test framework, start a transaction, truncate the relevant tables, insert known data, then rollback at the end. Its exactly how you unit test a stored procedure, for example. | |
| Jul 30, 2013 at 15:03 | comment | added | Reactgular | @KeithS what side effects????? | |
| Jul 30, 2013 at 14:59 | comment | added | KeithS | I disagree. A test requiring a database connection is not a unit test, because the test by its very nature will have side effects. That doesn't mean you can't write an automated test, but such a test is by definition an integration test, exercising areas of your system beyond your codebase. | |
| Jul 30, 2013 at 14:52 | history | answered | Reactgular | CC BY-SA 3.0 |