For me a Unit Test is a test of an 'unit’. The only question is how big is that 'unit’.
If you go to Wikipedia page for List of Unit Testing Frameworks you will see a large list of ‘unit test’ frameworks which range from traditional ‘unit tests’ (on individual function or procedure) all the way to:
- integration tests,
- production tests,
- e2e tests (end-to-end)
- performance tests
- smoke tests, etc…
- (i.e. every-type of automate-able test).
Once we have something that runs in one of those frameworks, we having something that:
- runs automatically (in multiple devices)
- fits into a continuous integration cycle
- is repeatable/replicable (by others)
- is a much better language to communicate between all the parties in a development life cycle.
I look at tests and see are how we should be communicating.
Sometimes devs can get quite focused on the concept that a unit test is ‘supposed to be’ a very small piece of test. For me, the key definition is 'unit’. A unit isn’t just a bit of code, a unit is what you are testing. Sometimes you are testing a little bit of code, sometimes you are testing a lot of code (the more code we are able to run on tests that execute in milliseconds the better).
One of the bad side effects that I see happening when the focus is on testing a discrete amount of code, is that you end up creating a lot of mocks.
These mocks have to replicate the behaviour of the application, but after a while, you start to have to maintain your mocks, even worse, your mocks might not represent reality anymore.
From my point of view, you want to run as much code as possible, all the time, and it has to be fast.
My benchmark for unit test is milliseconds, anything that runs slower than that, is most likely doing more than it should be doing at that moment in time.
The reason you want to run as much of your code as possible during your test, is because that means that you are testing more parts of the real application (i.e. of reality).