When we have multiple values for which we would like to test a given method should we loop through the values in a single test?
Or is it incorrect as in case of failure it might be harder to identify the cause?
Something like this:
testSomething(){
List myValues = {'value1', 'value2', 'value3', ...}
for(value: myValues){
assertTrue(Something(Value))
}
}
Documenting Your Code With AssertionsThe assert statement is an effective way to document code. For example, if you want to state that a specific condition should always be true in your code, then assert condition can be better and more effective than a comment or a docstring, as you'll learn in a moment.
An assert is inappropriate because the method guarantees that it will always enforce the argument checks. It must check its arguments whether or not assertions are enabled. Further, the assert construct does not throw an exception of the specified type. It can throw only an AssertionError .
Yes you can have loops in unit test, but with caution. As mentioned by Alex York, loops are acceptable if you test one thing; i.e. one expectation. If you use loops, then I recommend that you must do two things: As mentioned above, test for a non-empty iteration set.
A triggered assertion indicates that the object is definitely bad and execution will stop.
Not if you can avoid it
By which I mean, depending on what you're using to do your unit tests, you might not be able to realistically avoid it. In that case, do as needs must
If you run your assert in a loop, you effectively have one test which is testing an arbitrary number of things. That's going to get confusing.
What you want is multiple tests which test one thing each.
Some test frameworks (like NUnit for C#) allow you to define a test that takes parameters and then define the values to repeat the test with.
e.g.
[TestCase(1, 1, 2)]
[TestCase(2, 3, 5)]
[TestCase(0, -1, -1)]
public void MyTest(int a, int b, int expected) {
Assert.AreEqual(expected, a + b);
}
If your framework supports that, it's wonderfully easy to do.
Alternatively, if you're using a script language (e.g. javascript), you might be able to define your tests in a loop, rather than the asserts.
e.g.
describe('My tests', function() {
var testCases = [
{a: 1, b: 1, expected: 2},
{a: 2, b: 3, expected: 5},
{a: 0, b: -1, expected: -1}
]
testCases.forEach(function(t) {
it(`Adds ${t.a} and ${t.b} correctly`, function() {
assert.equal(t.expected, t.a + t.b);
});
});
})
This defines many tests, testing a single thing. Not one test testing many things. Which subsequently makes it much easier to see which one fails when it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With