4 ms·
What is an unit? Is it the wheel or the car? When you start to see that the car is the unit the difference between an unit test and an integration test gets blu
by rypskar 8y ago
What is an unit? Is it the wheel or the car? When you start to see that the car is the unit the difference between an unit test and an integration test gets blurry.
- twodave 8y agoThe basic rule I go by is whether or not the test is self-contained. For example if you are making a trip to a database or hitting a 3rd party dll then it’s an integration test. I thought this was pretty widely accepted.
- jondubois 8y agoWikipedia disagrees with that definition: "Intuitively, one can view a unit as the smallest testable part of an application. In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure. In object-oriented programming, a unit is often an entire interface, such as a class, but could be an individual method.[2] Unit tests are short code fragments[3] created by programmers or occasionally by white box testers during the development process. It forms the basis for component testing.[4] Ideally, each test case is independent from the others. Substitutes such as method stubs, mock objects,[5] fakes, and test harnesses can be used to assist testing a module in isolation. Unit tests are typically written and run by software developers to ensure that code meets its design and behaves as intended." https://en.wikipedia.org/wiki/Unit_testing https://en.wikipedia.org/wiki/Unit_testing
- twodave 8y agoI don’t think that definition necessarily is in conflict with my point.
- rypskar 8y agoI would say that for most CRUD applications it is much easier to have the tests run against an sqlite database instead of mocking it, so would let unit tests update the database and write tests to check if the data in the database match what I would expect from the input. If you change how you store the data, it isn't a side effect of changes you are doing but the main effect so the test could be rewritten anyway. Some call that an integration test
- hopler 8y agoMocking is a last resort and usually the wrong choice and used incorrectly. In memory fakes like sqlite (or better, running your real database in a small local inmemory footprint) is usally the way to get fast, correct, stable tests.
- hopler 8y agoMocking is a last resort and usually the wrong choice and used incorrectly. In memory fakes like sqlite (or better, running your real database in a small local inmemory footprint) is usually the way to get fast, correct, stable tests.
- twodave 8y agoI wouldn’t mock a data layer unless I was unit testing (for example) response codes on a route depending on the data layer. In those cases you aren’t interested in the data as much as how it is handled. I like to be able to point an integration test at a “clean” database in order to test a data layer. In this way you can have separate tests to basically ensure your API responses and database queries are all valid given your database is in a valid state and the API request is valid. With this kind of setup I rarely actually have to run an application anymore to feel it is in good working condition, and that saves me a LOT of time.
- jondubois 8y agoUnit tests should test individual subcomponents of your system in isolation. If your project is to build a car from scratch, then the unit cannot be the car. If your project is to build an autonomous fleet of self-driving cars, then from your project's perspective, the car could be a unit; the project to build the autonomous car would have different units from the project which manages the fleet of cars.
- rypskar 8y agoExactly, context matter. Most cases when some is writing for or against unit testing they miss the part about finding what they define as an unit. If the class need other classes to work, the whole set can be seen as one unit. Who didn't want to test a private method before they see that a unit is more than a function?
- Jach 8y agoI like to call it the 'system under test' / SUT. Then I can go on to say a unit test is a test that's fast and if it fails points to a specific problem in the SUT. Smaller SUTs obviously help satisfy both. If setting up collaborators in a bigger SUT leads to either unacceptable runtimes or too much brittleness from many things being able to go wrong, it's a signal you're not getting the value of unit testing in that place. (The test itself may or may not be valuable, other types of testing have their own value propositions.)
- jbergens 8y agoThis means that the unit tests will miss a lot of possible errors. Nothing wrong with that, just use integration testing or functional tests to cover the other part.
- adrianhel 8y agoIt does not matter. Are your tests preventing defects? Is it possible to run new or affected tests quickly? Are your tests reasonably easy to maintain? When I am testing an application that is basically a layer between my app and a database, it does not make sense to mock the database. What then am I actually testing. When I am testing a package that is pure logic, it makes sense to testing it in isolation. When I am building a user interface that is in flux, the best tests are manual. My definition of a unit test: The smallest piece of functionality that can be tested in isolation and provide value. This does not test a damned thing: assert.equal(dbQuery, "SELECT * FROM users")