I have a love/hate relationship with testing. I love the idea of having robust tests built out and having the confidence that when I make a code change all I have to do is run the test suite and verify I didn’t break anything. However, I hate writing tests. God bless the QA departments, because I could never do that as a full time job.
I have had the privilege of working on some of the best tested code bases in the world. That is probably where I get my love for testing. Every single change was verified against an exhaustive set of tests so breaking changes were caught immediately. When working on massive code bases with a lot of team members, this kind of testing is pivotal. The major difference I have seen in these successful teams is the use of either Unit Tests or Integration Tests.
I say either or, and not both for a good reason. On the teams I have worked on it has been considered overkill to do both.
Why? I hear you ask. It takes a lot of work to build out just one testing framework. Building two, by extension, is twice as much work. In my experience there aren’t a lot of frameworks that can do both styles of testing very well. That means you either set up two distinct testing frameworks, or you hodge-podge together a Frankenframework that allows you to do both. Or, you pick one.
Are you on board with this being an
either/or situation? No? Ok, good luck! Let me know how much time you spend writing tests vs actually producing valuable code. Now that we have that out of the way, let’s get to the heart of the matter. How do you pick which style of testing to pursue?
There are a lot of different criteria you could come up, but for me it actually comes down to just one issue. How connected is the application I am writing? Does it need to talk to multiple 3rd party apps or other internal microservices? If yes, this is a job very well suited for integration testing. Push in a known input and make sure you get the expected output back.
If you are working on a application that is stand-alone (or very little external dependencies) I suggest going the unit test route. You probably could do integration tests for isolated applications (i.e. UI tests) but you won’t be able to exercise as much of your code in isolation as you can with Unit Tests. In my opinion you should always try to do Unit Tests over Integration Tests. They give you a lot more flexibility when it comes to developing an application on any team size. Where they fall short is being able to emulate a lot of external moving parts. There are mocking frameworks to help with this, but mocking can be very messy and lead to you testing the wrong things without even realizing it. Nothing is more frustrating that tracing through a test and discovering that every single piece of real code has been bypassed by mock objects!
Basically, if you are looking to add tests to your project take a step back and evaluate the state of the world. If it looks like there are a lot of external dependencies, go ahead and save yourself some time and pick up an integration test framework. Otherwise, stick with using Unit tests, and keep those mocked objects to a minimum.