Some quick thoughts on msTest and automated unit tests for legacy applications
Automated unit tests are part of many development shops’ basic workflow and have long been considered a best practice.
However they are not well suited for applications that are heavily dependant on sql, and it can be very difficult to retrofit automated unit tests to existing code.
I’ve looked a little at msTest. I work in a Microsoft shop, and a fairly conservative one at that. Any non-Microsoft technology is looked at suspiciously, as if it might be an infectious disease. First nUnit, the thinking seems to go, then linux, then LAMP, then there goes the neighborhood.
From what I read, the nUnit vs msTest rivalry seems to follow the same pattern as most open source vs microsoft product rivalries do. nUnit is more customizable, perhaps has more features, but msTest is much, much easier to use, and supports integration with other microsoft tools (such as visual studio).
What I found when I tried to use msTest to add automated unit tests to some of our legacy C# code are these issues
To be tested, classes and functions must be public. The specific legacy applications that I am attempting to use this testing framework with are console applications intended to be executed by a task scheduler, and unfortunately at some point in the past someone decided that it would be a good practice to make the void main() entry points for these applications private. So immediately off the launch pad, code changes are required to make unit testing possible.
Unfortunately, our legacy code has been through many hands and some of those myriad developers are more inclined to good coding practices than others. The water here is pretty muddy, and many of our legacy applications have either many private global variables that keep track of various states and properties, or a single class with properties to keep track of those states that itself is declared as a private global variable.
Finally this legacy code includes a lot of inline sql. Inline sql is bad for many well-documented reasons and one of those reasons is that it is really difficult to construct unit tests for. This application used a custom data access class to encapsulate all data access. The custom data access class made it possible to mock the class and have the mock return a hard-coded data table when the inline sql was executed. Unit testing sql is a different topic, and there is actually an open source test framework, tSQLt, intended for this purpose. Red Gate Software sponsors tSQLt and provides a testing GUI, SQL Test, for creating and administering sql unit tests. For my experiment with msTest, I felt that building database unit tests using tSQLt was out of scope.
I found msTest to be easy to use. To add unit tests to an application, it’s first necessary to add a new test project to your solution. You then add references to the projects that you wish to test, such as assemblies, or console applications. You then create tests that provide values to functions in the referenced projects, and use assert to validate each function’s return value.
When you run the test project, each unit test is executed and a nice graphical display shows whether the test passed or failed, and how long the test took to run.