From the Inside January/February 2016 : Unit Testing on a MultiValue Systems
One of the major trends in MultiValue application development is Unit Testing. For those of you that are new to MultiValue, you are likely saying, "Well Duh! Unit Testing is not a trend. That is what you are always supposed to do." For those that have been in the MultiValue Community for a long time, you are saying, "But why test my existing code? It doesn't have bugs in it".
Unit Testing in a MultiValue application brings a new twist compared to other systems. The reason for this, you ask? Because MultiValue doesn't describe just database repositories, nor is it just an application development platform. MultiValue is both. This causes us to have to re-evaluate the way Unit Testing will be used and written in our environment.
Unit Testing a Database
Many developers who are new to MultiValue are likely coming from a three-tier coding environment that doesn't include complex access to a database; or perhaps the developer has not truly coded against a business database at all. In a three-tier application, Unit Testing is a bit easier to implement since the second tier (business rules) can be tested with mock data, or static/hardcoded data collections.
This is an important part of any application, but not the only part. The assumption is that as long as the business rules work with the mock data that the Unit Tests provide, then there are no bugs. There is even a hard rule in Unit Testing that states: "Never create a unit test against a database or external information source. Assume it is providing correct information."
Anyone that has worked with any form of database application knows that a database is never static, and it is never 100% clean and correct. Which leads to the other reason for the never-create-unit-tests-against-a-database rule; it is really really hard to do when the data is never the same.
The main issue with databases and Unit Testing is the fact that the test data can and should change. Which makes creating the normal hard-and-fast-test-against-static-data impossible. I've seen suggestions that say you should always reset your data back to the same point every time you start a new Unit Test run, but think about that for a minute. Many of the bugs found in "long-standing, solid, bug-free code" have to do with the changes in the data.
Business software developers know that the power of databases and software comes from flexibility. Ever changing business logic is required to meet the needs of a dynamic business model. So, new data is added, existing data is adapted for new uses, and new features are added because the "why" of the original data has evolved to mean something different.
Unit Testing just the business rules should be done, but that only addresses 80% of the issues. A Unit Test is designed to point out when a developer breaks something, but every day there are new problems to address due to the changing nature of the data itself. As much as we try, a developer can't think of everything. Which is one of the reasons that there are bugs to begin with.
I believe this is why it is so important to create a Unit Test against the database in addition to tests against the business rules. There are several ways to address the issues inherent in working with ever-changing data, which is an article in-and-of-itself. This is also a popular topic at the International Spectrum Conferences. That format — the conference — allows our presenters to go more in-depth than what an article or two can cover.
Unit Testing Legacy Code
The other issue that exists for developers is legacy code. I want to make a clarification here: Legacy code is not bad code. It is not out-of-date code. It is just code that has been in place for many years and is perceived to be solid.
When implementing Unit Testing for an existing application, do you create Unit Tests for your legacy code? It depends. Writing Unit Tests takes a lot of time. In the short term, adding more of them seems like a waste of time, but over the long term, Unit Testing can save a software developer hours and companies tons of money.
Most systems have tens of thousands of hours of code already written. The vast majority of that code does not have Unit Test written for it. On top of that, much of that legacy code has proprietary UIs. Do you need to create a Unit Test for that code right away? Most of the time… no.
A common practice with legacy code is to not create Unit Tests for it unless you are working with new code that must interact with the legacy code. In that case, a Unit Test is important because the new code — and the new data — may cause the legacy code to respond differently.
If there are no Unit Tests already created for your legacy code, I wouldn't worry about it. If you find that you are calling a common subset of the legacy code often in the new software, then you should have a Unit Test for that subset.
Any new code should have Unit Tests, even if it is to test known input and output. Unit Tests may build on each other, but you should always start with the simplest test using statically known parameters and work toward the complexity of dynamic data.
To continue this conversation, please join us at the Spectrum Conference or look at the webinars that are available on the topic.