Features and functions
In this section the features and functions will be described.
Here an overview of the functions which are available after the installation of JUnit-Tools:
Function | Description | Trigger |
---|---|---|
Switch test-class and -subject | Switches between the corresponding class or method under test and the test-class/test-method. The other class will be opened in the editor. | context-menu, hot-key |
Generate test-class | Generates a junit-test-class, test-methods, test-cases and triggers the test-suites-generation. A Java class or method must be selected to start the generation. The test-project must also be available and created manually. The folders and packages are created automatically. | context-menu, hot-key, icon in the toolbar, function "Switch test-class and -subject" |
Generate test-suites | Generates nested test-suites. For every package a test-suite with all test-classes is generated. New classes are added to the test-suite of its package. The test-suite of a package is connected with the test-suite in the parent-package, if exists. | context-menu, function "Generate test-class" |
Generate mock-class | Generates a mock-class based on JMockit. A Java class or method must be selected to start the generation. | context-menu, hot-key |
Clean mock-classes | Cleans existing mock-classes. All the method references to the mocked class will be checked. If the referenced method was deleted, the mock-method will be deleted. If the parameters of the referenced method was changed, the mock-method will be updated. | context-menu |
Create report for necessary tests | For the report all methods of a Java project will be scanned. All detected methods with logic and without junit-tests are listed in the report with a testpriority depending on the complexity of the logic. New methods are marked. The result is a XML-file. | context-menu |
Automated updates | Renames, moves and deletions of test-elements or referenced elements of the test-elements trigger the automated update of the depending test-elements. | refactorings in Eclipse |
Most of the functions are available via the context-menu of the package-/project-explorer or the editor:
All functions can be triggered both from the subjects under test or the test elements. See the following table when the functions are active:
Function | Active when |
---|---|
Switch test-class and -subject |
|
Generate test-class |
|
Generate test-suites |
|
Generate mock-class |
|
Clean mock-classes |
|
Create report for necessary tests |
|
The main function "Generate test-class" can additionally be triggerd by the hot-key ctrl-shift-<
and an icon in the toolbar:
The switch function (switch between the corresponding classes and methods) can additionaly be triggerd by the hot-key ctrl+<
The action "generate mock-class" can additionaly be triggerd by the hot-key ctrl+M
, but only if the class and not the editor is selected.
Generation of JUnit test-elements
The main feature of the JUnit-Tools is to generate test-elements. There are tree different functions which generates test-elements:
- Generate test-class
- Generate test-suites
- Generate mock-class
Generate test-class
First you have to select or open a Java class with the production code you want to test or a existing test-class to start the test-class-generation.
Then you have three options to start the generation wizard:
- Select the JUnit-Tools icon in the toolbar
- Press the hotkey
ctrl-shift-<
- Open the context menu in the Package/Project Explorer and select JUnit-Tools/generate test-class
If you selected a method in the production code (for example in the editor or the package-explorer) the corresponding test-method is automatically selected in the generator wizard dialog. You can see this information in the header of the wizard.
If the package, the test-class and the test-method didn't exists they will be created automatically according to the name-settings.
There are two annotations used from JUnit-Tools:
- MethodRef and
- Testprio
The annotation @MethodRef
is needed to identify the unique corresponding methods. For example if there are more than one methods with the same name but with different parameters. Also for inner types it is not possible to identify the unique method with the name-settings. Therefore this annotation is needed.
The annotation @Testprio
is used to define a testpriority for a test-class. So it is possible to generate different test-suites which can run in different intervals for example. To generate different test-suites according to the testpriority is not implemented yet.
There are some other processings which will triggered with the test-class-generation:
- Test-case-generation
- Test-suite-generation
- Clean of method-references
- Initialization of the class under test
Test-case-generation
The code of the method under test will be analyzed to generate the test-cases with the corresponding values and assertions. If there are no test-cases found a default test-case with default values and assertions is produced. For for more informations see the section "Generate test-cases".
Test-suite-generation
If a new test-class was created the generation of the test-suites is triggered automatically and generates the necessary test-suites for the new test-class. If there is already a test-suite, the new test-class will be added to this test-suite. The difference to the seperate function "Generate test-suites" is that only the new elements were generated and not the complete tree of test-suites. For more informations see the section "Generate test-suites".
Clean of the method references
While a regeneration of a test-class all the method-references in the test-class will be updated automatically and if there is no conflict. It is not necessary to change the method-references manually.
Initialization of the class under test
In every test class a method will be generated to initalize the class under test. To initialize a class under test the constructors will be analyzed. For objects the analyzation will be triggered recursively until there is a default constructor or a constructor with primitive types. For primitive Types default values will be generated. For specific objects testdata-factories can be implemented and registered, see extension point org.junit.tools.generator.factory.testdata.
Generate test-suites
Generates nested test-suites. For every package a test-suite with all test-classes is generated. New classes are added to the test-suite of its package. The test-suite of a package is connected with the test-suite in the parent-package, if exists.
Generate mock-class
Generates a mock-class based on JMockit. A Java class or method must be selected to start the generation.
If you have selected a Java class in the package or project explorer you can start the generation with the hot-key ctrl-shift-M.
At first a wizard is shown. In this wizard you can select the methods you want to mock. For every selected method a mock-method with the annotation @Mock
will be generated. Furthermore some methods are created to determine the return value and to queck the executions after a test.
Synchronisation of existing test-elements
Once you have generated a test-class for a Java class a synchronisation of the existing test-elements is necessary with the next generation of the same Java class. The process is as follows:
At first the corresponding test-class is tried to find with the settings in the preferences
- If the test-project was found, the package will be resolved
- If the test-package was found, the test-class will be resolved
If the test-class was found, the test-methods will be analyzed (at this point it is a regeneration and not a new generation):
- All method-reference-annotations in the test-class will be read. In the method-references are all necessary informations available to detect the unique method under test.
- Already covered methods will be checked in the wizard:
If you select a new method in the test-class-generator wizard, this method will be added to the test-class. The test-class frame is not generated new. This is why with a regeneration the super class cannot be set. All manual changes will not be overriden, but you have deselect a existing test-method. This method will then be deleted.
In the generated mock classes the annotation @MethodRef
is also used to determine the corresponding method from production code. If you regenerate a mock-class the process is the same as the process with a test-class.
Automated updates of existing test-elements
If you refactor your production code, the dependencies to existing test-elements will be updated automatically in the following situations:
- If you change the class- or method-name under test (only with refactor-function in Eclipse),
the corresponding test-class- or test-method-name (with method-reference and private method calls) is changed too.
- If you move the class under test,
the corresponding test-class is moved and the test-suites will be updated automatically too.
- If you delete a class- under test,
the corresponding test-class is deleted and the test-suites will be updated automatically too.
- If you move or delete a test-class,
the corresponding test-suites will be updated automatically too.
Cleaning of existing test-elements
In the generated test- and mock-classes are references to methods in production code. These methods are marked with the annotation @MethodRef
. If changes were made in the production code without the refactoring tools of Eclipse, the references can be out of date. The clean function for test-classes is triggered with every regenaration of a test-class. It is not available as single function yet.
For the generated mock-classes there is the function "clean mock-classes". It is available in the context menu if you select a Java class (binary or source) or a class in the editor. If you have selected a class in the project-explorer you can start the function also with the hot-key ctrl-shift-M
.
The process is as follows:
- Read all
MethodRef
-annotations - Check for every method, if it is available in the production code yet
- If not, check if a method with the same name is available and unique.
In this case, the parameters will be updated in the method reference annotation.
- If no method with the same name is available, the method will be deleted (only if it is a mock-class).
If the resolving of a method is not unique, a user interaction is necessary. The difference between test- and mock-class-clean is that no methods in a test-class were deleted because of a wrong method-reference. In mock-classes wrong referenced methods will be deleted.
Switch between corresponding classes and methods
You can switch between the class and method under test and the corresponding test-elements. The function is available via the hot-key ctrl-<
or the context menu.
Test-coverage report
You can create a test-coverage report via the context menu and if you select a project. The report is saved in the folder "reports" of your test-distination. The target of this coverage report is to detect new classes and methods with logic but without JUnit-Tests. It is a supplement to other test-coverage tools.
Extension points
There are three extension points with the following IDs available:
org.junit.tools.generator
org.junit.tools.generator.factory.testdata
org.junit.tools.preferences
To use these extension points you need a new plug-in in which you implement the extensions.
Extension point for customized generators
With the extension point org.junit.tools.generator
you can register customized or complete new implemented generators. There are three elements in the extension point:
- testclass-generator
- testsuites-generator
- mockclass-generator
As seen in the names you can define customized or complete new implemented generators for the testclass, testsuites and mock-classes.
To extend the available generators use as superclass the default implementation and override the corresponding methods. The default generator implementations are as follows:
- testclass-generator: TestClassGenerator
- testsuites-generator: TestSuitesGenerator
- testmock-generator: TestMockGenerator
To implement a complete new generator use the following interfaces and implement all the necessary methods:
- testclass-generator: ITestClassGenerator
- testsuites-generator: ITestSuitesGenerator
- testmock-generator: ITestMockGenerator
Register the new generator class in the corresponding extension point element to activate the new generator.
Extension point for testdata factories
With the extension point org.junit.tools.generator.factory.testdata
you can register test data factories. The factories are used in the test class generator. In every test class a method will be generated to initalize the class under test. The corresponding testdata-factory will be called if the type is connected with the testdata-factory.
The testdata-factory must implement the interface ITestDataFactory
and the method boolean createTypeCreation(IType paramType, StringBuilder classCreationChain);
.
In the parameter “paramType” the information about the class to initialize is available. You can check the name of the parameter type to decide if you handle a type with your own implementation:
"TypeToInitialize".equals(paramType.getElementName())
To add an initialization for the corresponding type the parameter classCreationChain is given. In this StringBuilder you can add the special code as String:
classCreationChain.append("SpecialTestdataFactory.createTypeToInitialize()");
You must return a Boolean to indicate if you made your own creation. Otherwise the default implementation for the initialization is used.
Extension point for customized default preferences
With this extension point you can register a class which defines the default preferences programmatically. If you don’t want to set your special preferences in every new workspace instance and for every developer, you can set your own default preferences. To do this you have to implement an extended class of AbstractPreferenceInitializer and the method initializeDefaultPreferences. The constants for the preference constants are available in the interface IJUTPreferenceConstants.
For example to set the default pre- and postfixes for the testclass you can implement following class:
public class JUTPreferenceInitializerCustom extends AbstractPreferenceInitializer implements IJUTPreferenceConstants { @Override public void initializeDefaultPreferences() { IPreferenceStore store = org.junit.tools.Activator.getDefault().getPreferenceStore(); store.setDefault(TEST_CLASS_PREFIX, "Test"); store.setDefault(TEST_CLASS_POSTFIX, ""); } }
To activate this class you have to add this class in the extension point element “initializer” of the extension point org.junit.tools.preferences.