Unit Testing

Unit testing helps ensure that the code fulfills the requirements at hand and that future changes (even in other packages) do not cause a regression. The unit test is written as a separate package that references the package it is testing. If we follow Test-Driven Development (TDD), we would write the tests early in the process, and some would argue first. TDD changes the way we think when writing code. Should we need to make a change to a project, we are forced to update the test-case code (as the tests will otherwise fail). This promotes a test-centric approach to development and naturally reduces the test cycles. Regression in other packages is caught by the build process. The build server will download all checked-in code, perform a build, and then look for tests to execute. Any tests that fail are reported and the build, depending on the build's setup, will be marked as failed.

Each partner or customer may have their own policies for unit testing. Some require that every piece of code is tested, while others will recommend that only key parts of the code are tested. It is common that the code of the unit tests has three times the amount of code as the code being tested, which may seem wrong at first. Writing test cases is an investment, the benefit of which isn't always apparent at the time of writing. This is because testing whether a piece of code works is usually pretty easy; the problem is that manual tests are not repeatable, often miss edge cases, and rarely spot regression caused by changes in other projects or a Microsoft update.

The biggest win, in my opinion, is the reduction in the risk of regression. This is where an apparently minor change (or a hotfix) is applied, and it affects a seemingly unrelated part of the system. These types of regression can easily make it into production since the testing procedures may only test that part of the system. This is compounded further by the fact that any fix will take at least a day to deploy since we are now forced to go through test and then production.

The following link provides some good advice on achieving balance in testing software: https://blogs.msdn.microsoft.com/dave_froslie/2016/02/03/achieving-balance-in-testing-software/.

Unit testing cannot catch everything. The test cases are preferably designed using the acceptance criteria and common patterns. Users will tend to evolve their use of the software, and modification can unknowingly break this usage scenario. This is where we could use the Regression Suite Automation Tool (RSAT). This tool uses task recordings from actual end-user scenarios that have been recorded and tested as part of the build quality management process. Although this is not in the scope of this chapter, the documentation for this from Microsoft is very good and can be found here: https://docs.microsoft.com/en-us/dynamics365/unified-operations/fin-and-ops/get-started/hol-use-regression-suite-automation-tool.

In this chapter, we will focus on unit testing and cover the following recipes: