Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I have failing tests?

Tags:

unit-testing

Please note: I'm not asking for your opinion. I'm asking about conventions.

I was just wondering whether I should have both passing and failing tests with appropriate method names such as, Should_Fail_When_UsageQuantityIsNegative() , Should_Fail_When_UsageQuantityMoreThan50() , Should_Pass_When_UsageQuantityIs50().

Or instead, should I code them to pass and keep all the tests in Passed condition?

like image 617
Randika Wijekoon Avatar asked Dec 29 '14 19:12

Randika Wijekoon


3 Answers

When you create unit tests, they should all pass. That doesn't mean that you shouldn't test the "failing" cases. It just means that the test should pass when it "fails."

This way, you don't have to go through your (preferably) large number of tests and manually check that the correct ones passed and failed. This pretty much defeats the purpose of automation.

As Mark Rotteveel points out in the comments, just testing that something failed isn't always enough. Make sure that the failure is the correct failure. For example, if you are using error codes and error_code being equal to 0 indicates a success and you want to make sure that there is a failure, don't test that error_code != 0; instead, test for example that error_code == 19 or whatever the correct failing error code is.

Edit

There is one additional point that I would like to add. While the final version of your code that you deploy should not have failing tests, the best way to make sure that you are writing correct code is to write your tests before you write the rest of the code. Before making any change to your source code, write a unit test (or ideally, a few unit tests) that should fail (or fail to compile) now, but pass after your change has been made. That's a good way to make sure that the tests that you write are testing the correct thing. So, to summarize, your final product should not have failing unit tests; however, the software development process should include periods where you have written unit tests that do not yet pass.

like image 132
Daniel Avatar answered Oct 12 '22 09:10

Daniel


You should not have failing tests unless your program is acting in a way that it is not meant to.

If the intended behavior of your program is for something to fail, and it fails, that should trigger the test to pass.

If the program passes in a place where it should be failing, the test for that portion of code should fail.

In summary, a program is not working properly unless all tests are passing.

like image 22
Stephen Avatar answered Oct 12 '22 10:10

Stephen


You should never have failing tests, as others have pointed out, this defeats the purpose of automation. What you might want are tests that verifies your code works as expected when inputs are incorrect. Looking at your examples Should_Fail_When_UsageQuantityIsNegative() is a test that should pass, but the assertions you make depend on what fail means. For example, if your code should throw an IllegalArgumentException when usage quantity is negative then you might have a test like this:

@Test(expected = IllegalArgumentException.class)
public void Should_Fail_When_UsageQuantityIsNegative() {
    // code to set usage quantity to a negative value
}
like image 34
tddmonkey Avatar answered Oct 12 '22 10:10

tddmonkey