Testing Java classes

Class-level testing exercises the interactions between the methods in a class or a small cluster of classes. The focus is to verify that the class supports all of the use cases required by its consumers and is robust enough to handle unexpected sequences of methods.

To test a Java class:

  1. Generate a test for the class.

    Use the scenario-based test pattern to generate a simple test case for the class. For example, you could invoke a constructor and a series of methods that represent the most common flows for that class. After the test is generated, add an initialization point and define some default test data values for the parameters of the constructor. In this simple scenario, for example, you could add an initialization point to set the object value to null. This allows the garbage collector to destroy the object and consequently to exercise the destructor code in your new class.

  2. Run the test.

    Run the test to make sure that everything is working properly. In this case, the test should pass the first time because you have not defined any expected values for the constructor. If you do not understand the results, use the debugger. Keep rerunning the test until it passes.

  3. Enhance the test to cover a real use case.

    When you test a class, the test case plays the role of one of the consumers of the class. Be sure to invoke a series of methods from your test behavior script just like any other consumer of the class.

    Use data partitioning techniques to define appropriate test data.

    Throughout the flow, be sure to define several validation actions. Each validation action should check that the actions executed since the last validation have modified the component-under-test in the appropriate way.

  4. Rerun the test.

    Run the test as often as needed until the test passes.

  5. Define use case variations.

    Define several use case variations by defining different test scenarios. Use state-based paths coverage analysis to help you think about different possible use cases. To define test variations, you can copy an existing test or create a new one.

  6. Mix different scenarios to check the integrity of the object.

    Most likely, the scenarios you have defined so far reflect the flows that are going to be used someday by a user of the class. It is also worth considering unexpected flows. The goal here is to check that your class can handle unexpected sequences of methods and ensure that the object is never corrupted.

    To test less common scenarios, define some properties that should be true throughout the life of the object. (These properties are called invariants.) Define random sequences of method calls, and, at the end of the test, define a validation action to check that the invariant is respected.

  7. Assess your test coverage.

    To assess your test coverage, go to the Coverage view in the Profiling perspective and observe the coverage for the methods that you were testing. If less than 100% of your lines are covered, add some new scenarios. Details about monitoring code coverage can be found in the online Help.

    To decide which data sets to add, identify the lines of code that are not covered. Usually those lines are related to decisions in your code, such as if statements. Very often, because the condition is always evaluated to false, the block of code following the decision is not covered. To cover this block of code, you need to understand the use case that the decision statement is intended to cover and create a test that represents that use case.

 

Related concepts

Test strategies
Java subsystems
State-based testing techniques

 

Related tasks

Testing Java methods
Inserting initialization points