Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unit test business rules?

I need a unit test to make sure I am accumulating vacation hours properly. But vacation hours accumulate according to a business rule, if the rule changes, then the unit test breaks.

Is this acceptable? Should I expose the rule through a method and then call that method from both my code and my test to ensure that the unit test isn't so fragile?

My question is: What is the right way to unit test business rules that may change?

like image 679
RAL Avatar asked Jun 19 '09 02:06

RAL


People also ask

How do you test business rules in Servicenow?

To debug a Condition field script, enable detailed Business Rule Debugging. To enable debugging, use the Application Navigator to open System Diagnostics >Session Debug > Debug Business Rule (Details).

What is unit testing in business?

Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.

How do you conduct a unit test?

A typical unit test contains 3 phases: First, it initializes a small piece of an application it wants to test (also known as the system under test, or SUT), then it applies some stimulus to the system under test (usually by calling a method on it), and finally, it observes the resulting behavior.


2 Answers

Your tests should ensure that the code properly obeys the business rule. Therefore, I wouldn't write tests that go around the business rule or rely on the business rule code itself. Rather, when the business rule changes, I would first change the test to reflect the new business rule, then when my code no longer passes the test, go and fix the code so that it passes the test.

What you don't want to happen is to write your test so that when you change how the same business rule is applied, that your test breaks. That's easier said than done, but essentially what you want to test is the minimum required to implement the rule without dictating too narrowly how the code is implemented. If the outcome of the rule is different, though, then you should be changing the test first, then the code to match it.

You also don't want the test to be coupled to specific data, either. Say when doing a tax calculation, your test shouldn't be written to assume that the class under test uses 5% as the tax. Instead, you should write your test so that it supplies the tax percentage, and then checks that the calculation is done correctly. Presumably, you'll have a range of values to test to make sure that out of range values are caught as well. One result of this is that you'll have a better design as this will help you to avoid hard-coded values and make your production code more flexible to changes in data.

like image 195
tvanfosson Avatar answered Oct 10 '22 19:10

tvanfosson


I have a similar setup - however my business rules are compiled but have configurable options (yours may differ). When a business rule changes a core way in which it operates, my unit tests break. This is actually expected - and good! It means that I can isolate any unexpected ripples throughout my system and update the tests to match the changes.

If your rules are external (some sort of script language or database sproc) then you will need to wrap them in an integration test and wire up your integration tests for automated execution. While no longer a unit test, integration tests are fairly important as well, and will help you in the same way as unit tests to prevent unexpected ripples due to a business rule change.

like image 35
cfeduke Avatar answered Oct 10 '22 18:10

cfeduke