开发者

Test default value and setter in same test-case or separate test cases

开发者 https://www.devze.com 2023-03-10 12:34 出处:网络
Would you recommend doing any grouping of test cases within @Test methods, or have one @Test method per test scenario? For example, let\'s suppose that there are different ways to set the context in a

Would you recommend doing any grouping of test cases within @Test methods, or have one @Test method per test scenario? For example, let's suppose that there are different ways to set the context in an application.

Is the following idea acceptable?

@Test
public void testContextSetting() {
    // Test default setting
    assert(...)

    // Test setting a context variable
    assert(...)

    ...
}

Or, wo开发者_如何学运维uld you rather suggest having it like this, having each method as atomic as possible:

@Test
public void textDefaultSetting() {
    // Test default setting
    assert(...)
}

@Test
public void testSettingContextVar() {
    // Test setting a context variable
    assert(...)

    ...
}

Any feedback would be appreciated.


I prefer having one test case per method.

First it is easier to see what cases are being tested if they are split into methods as opposed to looking for comments embedded in the code. Most IDEs will give you a summary of methods, so instead of saying "did I test edgecase XYZ?" and then hunting for a comment, or looking for the code that sets up that edgecase, you just look for the method named setupContextEdgeCaseXYZ().

A second reason is if you have multiple cases together one may fail and then the others never execute.

 testDefaultCase()
 testInvalidInput()
 testEdgeCase1()
 testEdgeCase2()

With this structure it would be easier to determine that the input checking is bad and edge case 2 is handled improperly, but the others are OK (and you may find out that two failing cases are related and the problem is diagnosed faster).

A third reason is you may accidentally leave values from a previous test set that invalidates a latter test in a inconspicuous way. A simple example:

@Test
public void testMyMethod() {
  //test default
  String test = Foo.bar(null);
  assertEquals("foo", test);

  //test case 1
  Foo.bar(aValue);
  //Oops forgot to set value above, this passes regardless of 
  //what the above call does
  assertEquals("foo", test);
}

By breaking cases apart you can avoid mistakes as above as that would turn into a compile error or warning.


Best Practice is to have one test case per method. The method name describes the test that you are performing. It is easier to debug when your test fails when it is just one assert.


Divide et impera :) so split in multiple small cases ...easier to fix in case of errors.


You are confusing a test with an assertion. Your test method with multiple asserts tests multiple things: default setting and setting a context variable. But a test method that tests one thing can also have multiple asserts.

A good pattern to use is for each test-case to have four phases:

  1. Setup: where you create the objects you need to perform the test, and if necessary alter those objects to put them in the required initial states.
  2. Exercise: where you perform the operation that you are testing. This will be one method call, or a constructor call.
  3. Verify: where you check that the objects under test are in the correct state(s), and check the value returned by the method you called in the exercise phase, if it returned a value. This is where you place your asserts. If you use this pattern, there is nothing wrong with placing multiple asserts in the verify phase.
  4. Teardown: where you destroy or close the objects you used to perform the test.

That is the approach recommended in the book xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros.

Contrast that pattern with what you have in your first example, in which it seems you would do this:

  1. Initial setup
  2. Exercise constructor
  3. Verify default
  4. Exercise to set a context variable
  5. Verify setting of context variable
  6. Teardown


Eclipse generates unit test per method which seems to be a reasonable approach. If the tested method is too complex to test it using one test method then You may consider re factoring it.

But a much more better approach is to use TDD and write the tests upfront which will drive the rest of the design and implementation.

Personally I prefer to have one test per method along with the Java Code Coverage for Eclipse http://www.eclemma.org.

The tool will tell You what You're actually testing.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号