In an answer to another question, I suggested creating a randomized value for input to a specific method. In my experience this has been useful for making tests more readable and it lets you skip the “trivial phase” where you hardcode specific results in a method.
Here’s the unit test code pasted from the other answer, for quick reference:
[Test]
public void FullHouseReturnsTrue()
{
var roll = AnyFullHouse();
Assert.That(sut.IsFullHouse(roll));
}
[Test]
public void StraightReturnsFalse()
{
var roll = AnyStraight();
Assert.That(sut.IsFullHouse(roll), Is.False);
}
A couple of comments in response suggested that this strategy would not work well, because the
helper method would need to be tested also. In my experience, I’ve never had a need to test methods like this, since creating the corresponding production code also tests my test code.
Do AnyStraight()
and AnyFullHouse()
need to have their own unit tests? If so, how do you solve the chicken-and-egg problem that presents?
EDIT
Would I still want to create dedicated unit tests for the AnyFullHouse
algorithm if I inlined the method?
[Test]
public void FullHouseReturnsTrue()
{
var roll = listOfHardCodedFullHouseRolls[_random.Next(0, listOfHardCodedFullHouseRolls.Length)];
Assert.That(sut.IsFullHouse(roll));
}
4
Why randomize the values? Having helper fields of AnyStraight
or AnyFullHouse
with hardcoded values is just as readable, still provides the reduction in magic values, and reduces the chance of error in your randomization (as well as guaranteeing that your tests are repeatable).
In my experience, as soon as your tests are not repeatable, people make excuses as to why they fail. Actual bugs are ignored and your tests are quickly ignored for not catching the bugs. Don’t start down that slope.
5
Test suites like PHPUnit and JUnit, etc, are developed using the same TDD principles (and are usually tested against themselves).
Of course, this means that there is a minimal bootstrap suite required, but by taking an axiomatic approach means you can easily build up from simple assertions like “true === true” and “0 !== false”.
In your case, you simply need to isolate the helpers and test them – it’s not really a chicken and egg, more of an inception: you need to go deeper.
Alternatively, you could assume that the helpers are correct – but then that limits your assumed confidence in your tests, and therefore limits the value of them.
2
This is an odd one. I’ve had to struggle with the same thought recently through some of my own tests.
While you really should test everything you write, i tend to have a general rule. If its to assist setup of a test, for example grouping setup methods for a interface using Moq, then no. However, everything else should be tested.
So in short, i think you would need to test those functions. Plus your generating data, which might be problematic (plus you really should know exactly what data your passing in/out while testing).