5

I am currently building a piece of code that creates side-effects based on input parameters. It has around ten input parameters and about six available side-effects. Based on the input parameters, the chosen side-effects - one or multiple - differ.

I have started developing this code test first with a context/specification framework, because every input parameter is basically a context.

The resulting code so far is a deeply nested if-else structure.

I have implemented about 30% so far and the code - and the tests even more - are getting very complex, unwieldy and hard to understand. So much that I am doubting this is the correct approach.
The main problem are actually the tests, because I keep repeating the conditions for some of the deeper nested input parameters as well as for the resulting side-effects.

Are there design patterns for building and testing this kind of "decision graph"?

Please note that the input parameters are not fixed values. A lot of the logic is relativ, i.e. if input parameter 1 is less than input parameter 2.

The current output from my tests can be seen here: https://cloud.fire-development.com/f/12bcba0439/?raw=1
You can see that there is a lot of repetition, making it hard to reason about what it actually does.

  • 1
    One of the things I'm wondering is if there are coarser conditions you can identify that determines, say, when a cow should and shouldn't have a leave/receive event instead of a series of nested conditionals, like "cow should have receive event if this is true", independent of all these nested events. That's what I'd try to identify to simplify all of this is to look for things you can check independent of a complex series of nested events: invariants you can tie to other properties instead of a series of cascading events. – user204677 Jan 29 '18 at 20:58
  • 1
    Great input thanks. What I am basically doing here is grouping. I have health events of cows that are time stamped. Because of external factors, all events have the same cow ID. Those events need to be grouped. Each group represents a different cow. Because the external IDs are all the same, I can't use it for grouping and I need to use other identifiers. And there are a lot of things that determine if an event belongs to the same cow as another event or to a different cow. Grouping those conditions into a broader set of conditions is a good idea, but I am not sure, this actually is possible. – Daniel Hilgarth Jan 29 '18 at 21:22
  • 1
    Identifying what a valid cow is, may in fact be the better approach, although there are outcomes other than cows as well... – Daniel Hilgarth Jan 29 '18 at 21:23
  • 1
    Yeah, this is a core logic of the application and we are processing millions of events, so this needs to work correctly as we can't verify the result manually... – Daniel Hilgarth Jan 29 '18 at 21:28
  • 1
    I don't see how I actually could use assert in this scenario. It's not as if there are invalid parameter combinations. However, thinking about your comments made me realize that I am violating the SRP here: I am trying to detect potential Data Entry Errors - potential, so they might still be correct - and I am deciding whether to add an event to an existing cow or a new one and when adding it to an existing cow, I am also deciding to which one. Furthermore, when adding a new cow or adding an event to an existing cow, I am also deciding how this is reflected on the cow. – Daniel Hilgarth Jan 30 '18 at 5:06
3

From implementation point view, Martin & Eric's Specification pattern may help. If possible, try to break down your rules and group them to smaller ones, and use "Logical Expressions for Composite Specifications" to converge them. By this way, you can test each individual small logical unit one by one.

Also, there're some Commercial off-the-shelf solution for decision DSLs such as Drool from redhat.

As for the testing, apart from breaking down, the Data-Driven Test seems quite fit with your problem. The scenario to use this pattern is

"essentially the same test with slight different system inputs and verify that the actual output varies accordingly"

There're also lots of commercial or open source solutions for the testing area, such as Fit.

  • Thanks for your answer. I am already using data driven tests where it makes sense. The specification pattern might be a good idea in parts, yes. Breaking down the rules is the first step now – Daniel Hilgarth Jan 30 '18 at 5:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.