Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing: Is it a good practice to have assertions in setup methods?

In unit testing, the setup method is used to create the objects needed for testing.

In those setup methods, I like using assertions: I know what values I want to see in those objects, and I like to document that knowledge via an assertion.

In a recent post on unit tests calling other unit tests here on stackoverflow, the general feeling seems to be that unit tests should not call other tests: The answer to that question seems to be that you should refactor your setup, so that test cases do not depend on each other.

But there isn't much difference in a "setup-with-asserts" and a unit test calling other unit tests.

Hence my question: Is it good practice to have assertions in setup methods?

EDIT:

The answer turns out to be: this is not a good practice in general. If the setup results need to be tested, it is recommended to add a separate test method with the assertions (the answer I ticked); for documenting intent, consider using Java asserts.

like image 836
avandeursen Avatar asked Sep 03 '09 07:09

avandeursen


People also ask

Why assertions are used in unit testing?

Assertions replace us humans in checking that the software does what it should. They express the requirements that the unit under test is expected to meet. Assert the exact desired behavior; avoid overly precise or overly loose conditions.

Should unit tests only have one assertion?

I should definitely use only one assert in test method! Using many asserts may be the code smell that you are testing more than one thing. Moreover, there is a chance that somebody can add new assert into your test instead of writing another one.


2 Answers

Instead of assertions in the setup to check the result, I used a simple test (a test method along the others, but positionned as first test method).

I have seen several advantages:

  • The setup keeps short and focused, for readability.
  • The assertions are run only once, which is more efficient.

Usage and discussion :

For example, I name the method testSetup().

To use it, when I have some test errors in that class, I know that if testSetup() has an error, I don't need to bother with the other errors, I need to fix this one first.

If someone is bothered by this, and wants to make this dependency explicit, the testSetup() could be called in the setup() method. But I don't think it matters. My point is that, in JUnit, you can already have something similar in the rest of your tests:

  1. some tests that test local code,
  2. and some tests that is calls more global code, which indirectly calls the same code as the previous test.

When you read the test result where both fail, you already have to take care of this dependency that is not in the test, but in the code being called. You have to fix the simple test first, and then rerun the global test to see if it still fails. This is the reason why I'm not bothered by the implicit dependency I explained before.

like image 65
KLE Avatar answered Sep 16 '22 14:09

KLE


Having assertions in the Setup/TearDown methods is not advisable. It makes the test less readable if the user needs to "understand" that some of the test logic is not in the test method. There are times when you do not have a choice but to use the setup/teardown methods for something other than what they where intended for.

There is a bigger issue in this question: a test that calls another test, it is a smell for some problem in your tests. Each test should test a specific aspect of your code and should only have one or two assertions in it, so if your test calls another test you might be testing too many things in that test. For more information read: Unit Testing: One Test, One Assertion - Why It Works

like image 27
Dror Helper Avatar answered Sep 20 '22 14:09

Dror Helper