I have written a hell of a lot on unit testing, and given a lot of thought to this over the years - not necessarily on dev.to . I think I put some stuff on Quora too. I don't include any code samples in here, just thinking through unit testing and integration testing. Am referring to c# .Net/.Net Core in this article.
I would advise the very old, but fantastic book - the art of unit testing.
Here is one article I wrote on thinking about data external to tests rather than stubbing way back to tease out integration testing and opening up unit tests to testers.
Unit tests, thinking them through
unit tests are documentation
I see unit tests as being there only as a living document on how the code works or is arranged. I barely write them despite having been through the process a lot.
unit tests prove that calculations work - good use case for unit tests
Most unit test benefit is gained when evaluating calculations and operations - small functions/units etc. The idea of isolating external resources/dependencies seems overbaked too.
unit tests involving testing data are probably best off being integration tests
NBI was a great .Net Data Testing framework. Seems like Cedric took his site down. Shame. It was a much better approach to use integration testing than unit test stubs for data logic testing.
unit tests enterprises vs software houses
- Enterprises - low unit tests/high integration tests
- Software Houses - high unit tests / low integration tests
Is creating unit tests valuable?
I really have to ask, if in most situations - unit testing is a worthy pursuit? The reason I ask this is for the following reasons;
- The true number of test cases is far higher than can be manually coded.
- Focusing on units does not necessarily focus on workflows.
- Tests can go green without proving the unit works. False sense of security.
- Business logic within unit tests can quickly become stale as domain logic requirements changes.
- Black box testing. Testers hate unit tests as they are buried in code.
The satisfying part about unit tests?
- Knowing certain code is covered.
- Seeing a sea of green as the tests pass.
- Integrating error checking/reporting through a CI tool to check whether the tests pass.
- The team can see errors on the Continuous Integration Server and resolve them quickly.
- A measurable indicator.
Thinking about unit tests
I wrote this article because it is abundantly clear to me that writing thousands of unit tests just to have a sea of green, that nobody knows how they work is probably a huge waste of time. Heresy we say. Development projects can be more about test coverage than the product.
The right unit tests are great at explaining the code. Furthermore, unit tests can signify breaking changes and this is great.
When developing complex logic, or using Test Driven Development, unit tests can be a good way to give other team members that the code works.
There is a final thing which escapes many people. Stable, well written code/applications which accepts consistent inputs and produces consistent testable outputs may not need any unit tests at all.
- > Written with StackEdit.
Top comments (12)
One advantage of unit tests you've missed out is that they are fast. Both fast to write and fast to run. This means you can have a lot of coverage with minimal overheads.
I would say that is much more of an advantage than
Seeing a sea of green as the tests pass. What purpose is seeing a sea of green if there is no trust in the tests you've written?
I know that what you say sounds fine - completely, there is faster feedback on unit tests - no doubt! As said, am not against them - when people focus on test coverage - it is a false dawn, unattainable.
Calculations and logic are perfect reasons for adding unit tests, but that most "proof is in the pudding". For example, deploying to a test environment with sufficient test coverage will reveal more than esoteric unit tests.
Also agree on your point re sea of green and no trust :)
Are they really? I can se how this might apply to the early stages of a project with enough discipline and experience also thrown into the mix. But what about legacy/existing code. Sprinkling some small changes into a method wo UTs would result in a couple of hours of mocking, stubbing and dummy-ing.
I would agree that retroactively trying to add unit tests to code that you're not familiar with / didn't write can be a little more tricky but not impossible. This isn't unique to unit tests though as the same applies to integration and E2E.
In saying that, if you're working with legacy code, I think it is fair to assume that you're still adding code / features / bug fixes. It is at this time when you can add those tests (unit or otherwise) as you have more familiarity with the code. This would be akin to following the boy scout rule.
I am coming from it more that if we write applications which are data focused - integration tests are better. A great example could be coding in a portfolio swap for a known test case, if this is stubbed that stub can become stale quickly. In this example, I may store the stub as a json file (deserialised IList). This allows testers and analysts to put in their own test cases. I wrote about this here (kind of) dev.to/zakwillis/novel-tips-on-uni...
I think your point is valid, imagine if there is legacy code. Yes, I would probably setup up a separate unit test project as a means of understanding the code. However, where legacy systems exist, they are only understood by their outputs - which again leans towards integration testing, despite how slow the process may be compared to unit testing.
One of the other benefits of unit tests and TDD is better domain and code design.
Is it? Truly? In practice or theory? One thing I have gotten more into is "the code that writes the code". It then becomes more about how the application is configured and set up than developed.
Honestly. I think unit testing is a paradigm shift in many circumstances, it just concerns me when we have umpteen layers all needing unit test coverage.
Kent Beck's book on Test Driven Development is a good place to start on this subject.
I think in terms of the things you've mentioned we're beyond the scope of pure unit tests. You'd have to do a lot of mocking, and dependent on what is under test they'd need to be backed up by integration tests to generate confidence. So I agree with you in many ways.
The reason unit tests, and TDD in particular, help with code design is because they push you towards code isolation. They drive you to abstract domain logic away from I/O and orchestration, because the code becomes easier to test. This also reduces code complexity, makes debugging easier, and increases confidence.
I've barely (almost never actually) used or written unit tests in 26 years of professional development. It's totally possible to not use them
Hi Jon, for the last 3 years, I have predominantly been building applications for my startup efforts. The only time I write them is;
In contract/commercial settings, I can see some benefits - but I think integration testing is better.
Agree with you, probably if you know what you are doing, it is a rare requirement.
Yes, I agree with this. I am really a data person - not sure on your exact areas of expertise. I like unit testing mainly for all the reasons others don't. Like a scratchpad for example.