Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Much Should Each Unit Test Test?

How much should each of my unit tests examine? For instance I have this test

[TestMethod]
public void IndexReturnsAView()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ActionResult result = activityController.Index();
    Assert.IsInstanceOfType(result, typeof(ViewResult));
}

and also

[TestMethod]
public void IndexReturnsAViewWithAListOfActivitiesInModelData()
{
    IActivityRepository repository = GetPopulatedRepository();
    ActivityController activityController = GetActivityController(repository);
    ViewResult result = activityController.Index() as ViewResult;
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(List<Activity>));
}

Obviously if the first test fails then so will the second test so should these two be combined into one test with two asserts? My feeling is that the more granular the tests and the less each test checks the faster it will be to find the causes of failures. However there is overhead to having a huge number of very small tests which might cost time in running all the tests.

like image 837
stimms Avatar asked Jun 07 '09 21:06

stimms


People also ask

How much unit testing should you do?

Generally, this means a percentage of the team's work week or something. From now on, spend 90% of your time writing code and 10% working on unit tests. One or more of these things, they reason, will ensure that the team does "enough" unit testing. Let's now get down to brass tacks.

Why is most unit testing a waste?

A great quote in the "why most unit testing is waste" paper is that unit tests should have a "broad, formal, independent oracle of correctness, and ... ascribable business value" The quality of the tests is much more important than the quantity. One good test is worth any number of bad tests. (in fact a bad test has a negative value).

Why are unit tests important in software testing?

Since unit tests act as a safety net, developers become more confident when changing the code. They can refactor the code without fear of breaking things, driving the general quality of the codebase up. Unit tests might contribute to better application architecture.

Should normal testing be done more expensively?

Normal testing should be done even more extensively. Because imagine that right now, when someone creates a code, he will write unit tests based on its structure and understanding of the story. Often times, the one that makes code review doesn't understand 100 percent, in-depth all pieces of the code and tests.


2 Answers

I'd recommend breaking them down as much as possible.

There are lots of reasons for this, IMHO the most important ones are:

  • When one of your tests fails, you want to be able to isolate exactly what went wrong as quickly and as safely as possible. Having each test-method only test one single thing is the best way to achieve this.

  • Each test needs to start with a clean slate. If you create the repository once and then use it in 2 or more tests, then you have an implicit dependency on the order of those tests. Say Test1 adds an item to the repository but forgets to delete it. Test2's behavior will now be different, and possibly cause your test to fail. The only exception to this is immutable data.

Regarding your speed concerns, I wouldn't worry about it. For pure code-crunching like this, .NET is very fast, and you'll never be able to tell the difference. As soon as you get out of code-crunching and into things like databases, then you'll feel the performance issues, but as soon as you do that you run into all the "clean slate" issues as described above, so you may just have to live with it (or make as much of your data immutable as possible).

Best of luck with your testing.

like image 177
Orion Edwards Avatar answered Sep 28 '22 04:09

Orion Edwards


The more fine-grained the better. When an assert fails in a test case, the test case is not run any further. The latter parts of the case could potentially uncover other errors.

If there's shared code between test cases, use setup/teardown functions to take care of that without repeating yourself too much. Time cost is often negligible. If the setup/teardown takes too much time, you're probably not doing unit testing but some higher level automated testing. Unit tests ideally should not have file system, network, database etc. dependencies.

like image 33
laalto Avatar answered Sep 28 '22 03:09

laalto