1

So I'm writing a program that runs quite a few different tests. Which tests are ran varies based on which UI elements are selected by the user. For example, on one form I have 7 radio buttons and 6 check boxes. For each variation, anywhere from 2-5 different tests are ran. The user is able to select any combination (with the exception of only a single radio button) and run the tests for that selection. My method for determining which tests to run is very redundant and I was wondering if there was a more clean approach. Here is an example:

if(radiobutton1.checked)
{
  if(checkbox1.checked)
  {
    runtest1(param a, param b);
    runtest2(param b, param f);
  }
  if(checkbox2.checked)
  {
    runtest1(param f, param n);
    runtest2(param c, param l);
    runtest3(param f, param d);
  }
}
else if(radiobutton2.checked)
//and so on...

So I have 42 use cases and I'm running 2-5 sub tests for each. Is there a better way to do this?

  • why are you not running all the tests all the time? – Ewan Jul 18 '18 at 21:38
  • @Ewan Because most the time only a small handful of tests needs to be ran – emsimpson92 Jul 18 '18 at 21:46
  • 2
    Nice question, always good to be thinking about how to improve it. Code review stack exchange is also a good place for this sort of stuff, by the way. – JᴀʏMᴇᴇ Jul 19 '18 at 8:18
5

You can approach problem from opposite direction.
Create type with two functions, one for running test and another which check is test need to be run.

public class Test
{
    public Action Run { get; set; }
    public Func<bool> CanRun { get; set; }
}

Then you simply define all tests with their own predicate

var test1 = new Test
{
    Run = () => runtest1(param a, param b),
    CanRun = () => radiobutton1.checked && checkbox1.checked
};
var test2 = new Test
{
    Run = () => runtest2(param b, param f),
    CanRun = () => radiobutton1.checked && checkbox1.checked
};
var test3 = new Test
{
    Run = () => runtest1(param f, param n),
    CanRun = () => radiobutton1.checked && checkbox2.checked
};
var test4 = new Test
{
    Run = () => runtest2(param c, param l),
    CanRun = () => radiobutton1.checked && checkbox2.checked
}

// Then tests execution will looks much simplier
var testsToRun = 
    new[] { test1, test2, test3, test4 }.Where(test => test.CanRun());

foreach (var test in testsToRun)
{
    test.Run();
}

Approach above should make maintenance easier, where every test is isolated from others, when adding or removing tests you don't need to touch code related to other tests.

  • I think it can be simplified further. CanRun can be reduced to a collection (array?) of checkboxes and a reused method from a base class (or shared from elsewhere). – Frank Hileman Jul 18 '18 at 23:58
  • @FrankHileman, true if CanRun based only on checkboxes. Predicate on other hand leave more freedom in adding conditions. But good idea, OP can use checkboxes collection inside CanRun, which will simplified current implementation and leave freedom to add more conditions later if needed. – Fabio Jul 19 '18 at 1:20
  • That's a really nice approach. Was reading the OP thinking about a cleaner way and couldn't come up with anything. +1. – JᴀʏMᴇᴇ Jul 19 '18 at 8:18

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.