You’ve got the greenlight. Your team got the go-ahead to bring a handful of old dependencies up to date as part of your modernization efforts. They’ve all put in plenty of time working hard to make sure the public API wasn’t impacted. Several have even talked to other teams in the company to make sure they aren’t surprised. Everything is going smoothly until you get a frantic call after release that some poorly documented web service is making use of an old set of functionality that wasn’t properly tested.
We’ve all been there before. Some part of your codebase that has escaped documentation or manual tester’s efforts comes back to bite you. What went wrong? What could have prevented this?
Refactoring With Instant Feedback
Often the point of a refactor is to reduce your technical debt burden. It isn’t supposed to (or is required to not) impact customer experience. Knowing that you haven’t impacted customer experience is difficult to determine without lots of manual effort for testing. If the developers are the test team this means time not spent writing code. If the test team is a separate group that means a long developer cycle to have feedback. One might find that this is likely how the technical debt became a problem in the first place. If your developer loop is long you don’t have time to spend making incremental fixes over time.
Wouldn’t it be better, then, to have instantaneous feedback on your efforts?
Enter unit testing, that practice your team has been putting off for years. There is no better time to start writing unit tests than right before changing larger aspects of your application. Unit tests, as the name implies, are testing units of your code. They’re meant to only be testing the public boundary of your code; the parts other applications can interface with. Writing test cases that exercise this interface can give you feedback about what effects your modifications might be having to what other outside applications are expecting.
And the instantaneous part? Visual Studio has you covered. The Live Unit Testing feature in Visual Studio Enterprise will continuously execute these unit tests in the background, bubbling up the results to you right to the side of the lines of code they’re testing. Make a change that breaks something? Receive immediate results indicating what went wrong and what tests to investigate. Fix your typo? Get lovely green checkmarks letting you know everything is back on track.
Several other IDEs have plugins granting similar feature sets, and .NET Core has its own system. Scott Hanselman discussed dotnet watch on his blog.
Low Barrier to High Reward
We often hear a discussion on unit testing starting with responses along the lines of “That’ll take too much time and the developers are already overworked”, or “We simply can’t fit unit testing into our scrum cycles now.” I’ve always found it a curious sort of statement, as even just a handful of simple unit tests exercising a shared library can prevent of back-and-forth bugfixing sessions between the QA and Dev departments.
Creating a unit test project in Visual Studio for C# is as simple as right-clicking the method you want to test and selecting ‘Create Unit Tests‘. You’ll be presented with a few fields to fill out related to common project information. In under a minute you can go from no tests to having your framework set up and ready to accept any new tests.
Being unit tests indicates that the tests should be short in length but great in number. Two tests per if statement is a good ballpark to start with, but even that can be optional for overworked teams. Simply writing unit tests whenever you can will start to grow their count in your system, and any unit tests in the system can help avoid simple mistakes before anything gets handed off to a different team.
Adding new unit tests to your unit test project is as simple as adding a new method to the class, or adding a new test class to mirror your own project’s structure as it grows. Unit tests themselves often require far less intensive thought than adding new features, or working with complicated logic. This means that half-hour between two meetings is no longer unproductive time. It’s plenty of time to bash out a series of unit tests for a handful of functions that you’ll be rewriting after the meeting.
Rather than spending 10 minutes talking about how unit tests are hard to write, take those 10 minutes and just write up one or two tests. Having the framework ready to go reduces the already low barrier to entry on getting started writing your tests cases.
Investment in the Future
Once those cases are written out they become part of your codebase. Living in version control, being compiled in the same build server, and most important of all being pulled down onto every developer’s machines for them to run before trying to commit code back up. When written out these test cases can be executed many times very quickly whenever change happens. Gating check-ins on not only a successful build but also a successful run of available unit tests is a very common practice once companies start rolling out these tests. The more unit tests you have available the more areas of your code will provide feedback on changes when they occur. VSTS’s integration with running unit tests during build and release steps has only gotten better over time.
It’s not uncommon to see unit tests live longer than the guts of the function they’re testing. Larger unit tests that lean more towards functional testing can last even longer, surviving through multiple refactorings if the public API they’re testing isn’t supposed to be changing. Therefore the time spent writing and maintaining tests is rarely wasted, and the benefits can continue to be reaped throughout the lifetime of the code they’re testing.
Even just small amounts of time dropped into writing unit tests can go a long way to preventing simple mistakes from slipping through your testing process. With a robust fleet of test cases being run every time a developer checks in code those mistakes might not ever see the test team at all, let alone your end users. The more time saved dealing with production issues and QA department feedback means more time spent making your users happy. Consider taking an hour or two out of your next sprint to get a few unit tests down in your git repo.
We’re Wrapping Up Our “App Modernization” Workshop Series!
We’ve been traveling around the Southeast the last couple of months hosting Application Modernization workshops and we’ve got one workshop left on Tuesday, March 27th in Atlanta, Georgia. If you can’t attend the workshop, we are also hosting a webinar, “Journey to the Cloud – Modernize Your Applications with Azure”, on Thursday, March 15th. Click here for more information and to register!