Skip to main content
deleted 9 characters in body
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21

Refactoring is indeed a way to go, but I really don't want to 'unroll' all combinations manually in my tests: it is verbose, ugly and good be hard to understand to. However

However I'll keep this answer as a preliminary mandatory step: break the expression into smaller pieces before anything else.

I found this interesting, but outdated, article about test combination in Groovy.
The tool they spoke about is out of search engine radar, so it must be dead !
However I'll useduse the same pattern:

Refactoring is indeed a way to go, but I really don't want to 'unroll' all combinations manually in my tests: it is verbose, ugly and good be hard to understand to. However I'll keep this answer as a preliminary mandatory step: break the expression into smaller pieces before anything else.

I found this interesting, but outdated, article about test combination in Groovy.
The tool they spoke about is out of search engine radar, so it must be dead !
However I'll used the same pattern:

Refactoring is indeed a way to go, but I really don't want to 'unroll' all combinations manually in my tests: it is verbose, ugly and hard to understand.

However I'll keep this answer as a preliminary mandatory step: break the expression into smaller pieces before anything else.

I found this interesting, but outdated, article about test combination in Groovy.
The tool they spoke about is out of search engine radar, so it must be dead !
However I'll use the same pattern:

added 879 characters in body
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21

Edit: about the retained solution.

Refactoring is indeed a way to go, but I really don't want to 'unroll' all combinations manually in my tests: it is verbose, ugly and good be hard to understand to. However I'll keep this answer as a preliminary mandatory step: break the expression into smaller pieces before anything else.

Once the refactoring is done and the test still result in combinatory tests, then I'll use the TruthTable solution proposed. I'll just generate the combinations and not declare everything.

I found this interesting, but outdated, article about test combination in Groovy.
The tool they spoke about is out of search engine radar, so it must be dead !
However I'll used the same pattern:

assertThat(permutations, expectations, instanceObject)

Where

  • permutation is all possible values to assign to properties in a 'condensed map': (a:[true, false], b:[true, false], ...)
  • expectation is all combinations that return a specific value, all other combination will be checked against a default value.

Edit: about the retained solution.

Refactoring is indeed a way to go, but I really don't want to 'unroll' all combinations manually in my tests: it is verbose, ugly and good be hard to understand to. However I'll keep this answer as a preliminary mandatory step: break the expression into smaller pieces before anything else.

Once the refactoring is done and the test still result in combinatory tests, then I'll use the TruthTable solution proposed. I'll just generate the combinations and not declare everything.

I found this interesting, but outdated, article about test combination in Groovy.
The tool they spoke about is out of search engine radar, so it must be dead !
However I'll used the same pattern:

assertThat(permutations, expectations, instanceObject)

Where

  • permutation is all possible values to assign to properties in a 'condensed map': (a:[true, false], b:[true, false], ...)
  • expectation is all combinations that return a specific value, all other combination will be checked against a default value.
added 368 characters in body
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21

When I write an unit test I usually provide a context (plain object or mocked/stubbed object) that I setup in some ways and then I can run assert statement on the context:

note: code is in pseudo-code; groovy like syntax:

test myTest() {
  def o = getTestContext();
  o.string = "testme"
  o.number = "2"
  assert o.mult() == "testme testme" 
}

But how to organize the test when you need to test a complex boolean expression that takes many parameters ?

EDIT: I have replaced the one line expression with something more readable to avoid confusion.

//this is not a real class, this is an example. Naming is bad, for conciseness sake
//the expression is coming from randomness realm, so it is probably refactorable and simplifiable, but complex real world expression still exists.
enum Type {X,Y,Z}
class C {
  boolean a,b,c,d;
  Type t; 


  boolean isEnabled(boolean anotherFlag) { 

    def //thiscondition1 is= (a condensed fake expression.|| b)
    def //Realcondition2 one= will(c have&& properd)
 names, intermediate variables, anddef maybegoodType1 sub-functions
= t == X return|| (t (a== ||Y
 b) || (c &&def d)goodType2 )= anotherFlag && (t == XZ || t == Y)Z ||&& !condition1 

    return (anotherFlag && tcondition1 == Z|| condition2 ) && a(goodType1 || goodType2) 
  }
}

All tests for this kind of methods I've read so far are very verbose, not complete and hard to understand.

And it is quite a shame that such a small line of code, even if it is 'complex', generates awful tests.

I've tried to break the boolean expression into smaller sub methods, but sometime it is not so convenient and the permutation count is still high. I also usually break the expression into intermediate variables, but this is not helping in unit test world...

How should I test something like this to have test code matching the briefness of the tested code and the completeness that must assert that my code works as expected ?

When I write an unit test I usually provide a context (plain object or mocked/stubbed object) that I setup in some ways and then I can run assert statement on the context:

note: code is in pseudo-code; groovy like syntax:

test myTest() {
  def o = getTestContext();
  o.string = "testme"
  o.number = "2"
  assert o.mult() == "testme testme" 
}

But how to organize the test when you need to test a complex boolean expression that takes many parameters ?

enum Type {X,Y,Z}
class C {
  boolean a,b,c,d;
  Type t;
  boolean isEnabled(boolean anotherFlag) {
     //this is a condensed fake expression. 
     //Real one will have proper names, intermediate variables, and maybe sub-functions
    return ( (a || b) || (c && d) ) && (t == X || t == Y) || (anotherFlag && t == Z && a)
  }
}

All tests for this kind of methods I've read so far are very verbose, not complete and hard to understand.

And it is quite a shame that such a small line of code, even if it is 'complex', generates awful tests.

I've tried to break the boolean expression into smaller sub methods, but sometime it is not so convenient and the permutation count is still high. I also usually break the expression into intermediate variables, but this is not helping in unit test world...

How should I test something like this to have test code matching the briefness of the tested code and the completeness that must assert that my code works as expected ?

When I write an unit test I usually provide a context (plain object or mocked/stubbed object) that I setup in some ways and then I can run assert statement on the context:

note: code is in pseudo-code; groovy like syntax:

test myTest() {
  def o = getTestContext();
  o.string = "testme"
  o.number = "2"
  assert o.mult() == "testme testme" 
}

But how to organize the test when you need to test a complex boolean expression that takes many parameters ?

EDIT: I have replaced the one line expression with something more readable to avoid confusion.

//this is not a real class, this is an example. Naming is bad, for conciseness sake
//the expression is coming from randomness realm, so it is probably refactorable and simplifiable, but complex real world expression still exists.
enum Type {X,Y,Z}
class C {
  boolean a,b,c,d;
  Type t; 


  boolean isEnabled(boolean anotherFlag) { 

    def condition1 = (a || b)
    def condition2 = (c && d)
    def goodType1 = t == X || t == Y
    def goodType2 = anotherFlag && t == Z || t == Z && !condition1 

    return (  condition1  || condition2 ) && (goodType1 || goodType2) 
  }
}

All tests for this kind of methods I've read so far are very verbose, not complete and hard to understand.

And it is quite a shame that such a small line of code, even if it is 'complex', generates awful tests.

I've tried to break the boolean expression into smaller sub methods, but sometime it is not so convenient and the permutation count is still high. I also usually break the expression into intermediate variables, but this is not helping in unit test world...

How should I test something like this to have test code matching the briefness of the tested code and the completeness that must assert that my code works as expected ?

added 121 characters in body
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21
Loading
added 112 characters in body
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21
Loading
Source Link
Guillaume
  • 2.2k
  • 1
  • 19
  • 21
Loading