The "intent" behind unit tests - what should I be aiming for?
I wrote a series of tests today around a method that takes an input value and returns a different array of data depending whether the value passes some (internal) validation test, i.e.
[TestMethod]
public void IsValidForValueFour()
{
var result = myComponent.Validator(4);
Assert.IsTrue(result[0], "Blah");
}
The Validator()
method basically does a lookup in a (hardcoded) table stored privately in myComponent
.
This felt wrong. I was effectively testing the values in a private lookup table. Should I care about the values passed in and out? Should I be testing the length of the output array rather than its conte开发者_Python百科nts? Or is it right to test for specific responses given some input value?
In short, what should the intent be behind a unit test like this?
This is valuable, as you now know that the function is returning what it should.
In the future, if you change implementation, you can rest sure that it still does what it should, so long as the tests all pass.
As for should you test such things? It is up to you how much testing you want to preform and the value you believe you are getting from such tests.
A unit test should test a small piece of code, like one object or even one method and should look for ways the method/class might break. IMHO, A unit test which never breaks may as well not exist. ;)
If the contract of your method is that it returns "Blah"
for an input of 4
, then yes, you should be testing that!
The the contract for MyComponent.Validator(4)
is that it returns an array whose first element is true
, then this test is useful. However, it really depends on how complicated the logic behind that method is. One of the rules I follow is that by writing short, simple methods you can skip a lot of the testing: if something is so simple it can be visually verified, it's often not worth testing.
If Validator()
accepts two hundred valid integers and returns a unique result from an internal array for each one, I wouldn't bother writing two hundred tests. I would write tests for the endpoint values and move on.
You should be testing it by passing in many, many valid pieces of data, and even more invalid pieces of data to make sure it works like its supposed to. That's the entire point. Your method must do what it's supposed to do, otherwise it needs to be reworked. That way the consumer of this information (either you or possibly another developer), can work with that data without being concerned about the internal implementation of your method.
In fact, if you have a paragraph of comments that contains text from a novel your reading (which is silly, I admit), but your method accepts and returns what it says it should, then the consumer will never know or care how you implemented that method.
If it is important from the requirements point of view, you should test this. If it is important that value four must return “Blah” then you have valid test – But I would also certainly extract number 4 into a meaningful variable name and pass it into validator. So whoever read your test will know why you pass value four. If you are testing some kind of an algorithm try to use a tool like Pex to generate input for you. This will also ensure your logic within the SUD (System Under Test) behave as expected.
精彩评论