Using JUnit to automate unit testing regression of Adapter Module
Sometime ago, I blogged about Standalone testing of Adapter Module in NWDS to introduce an approach that enables developers to perform basic unit testing on custom adapter module developments. This allows a developer to avoid the pain of deployment and end-to-end testing for even minor changes to a custom adapter module logic.
Due to the higher overhead involved in adapter module development, as a general practice, I would only go for such development when there is a possibility of reuse of such a module in different interfaces. As such, the module will be designed in a generic manner such that it is capable of catering to various scenarios. With this design principle in mind, it is possible that the adapter module will be continually enhanced to cater for new scenarios or to enhance its functionality. In order to ensure that any changes introduced do not affect existing functionality, it is important to perform rigorous regression testing with both existing as well as new scenarios.
Even with the capability to perform standalone testing in NWDS, it might require tedious effort to perform unit testing individually for all the scenarios involved. The benefit of working in an Eclipse-based environment is the rich toolset that is made available to the developer, and in the area of testing, JUnit is a popular choice. JUnit provides a simple framework to write tests for developments, and allows for automatic execution of test cases and test suites. This enables a developer to quickly and efficiently run a regression suite of unit test cases to verify that existing scenarios are not impacted.
In this article, I will share how JUnit can be used to assist in regression of unit testing for adapter module developments.
Overview of Approach
The approach described here is in part based on the standalone testing approach described in my previous blog. It utilizes a testing class that acts as a wrapper to invoke execution of the adapter module.
The diagram below shows the different components required for implementation of this automated testing approach.
1. Adapter Module
This will be the class that implements the adapter module logic. It is considered the class under test. For this example, the module is the same example module described in the previous blog.
Note: Ideally the adapter module should be situated in a separate Java EJB project to decouple the testing logic from the implementation logic. However, for the sake of simplicity for this example, it resides in the same project.
2. Testing Class
The testing class used in the standalone testing approach has been refactored to enable for this JUnit testing approach. Additionally, there are helper classes to handle the content from input files (item 4 below) which will be used as parameter inputs to the module as well as storing the expected result of the test.
3. JUnit Test Case
This class represents the test script involved in a particular test case. Scenarios are written together with the expected behavior of each test. This will be elaborated further in this article.
4. Input Files
These are input files to each test case. They represent the input payload and parameters to the adapter module, and the expected output payload.
Creating JUnit Test Case
With the project structure and testing class in place, we will focus on the creation of the JUnit Test Case.
Click File > New > Other, and select JUnit Test Case.
Select JUnit 4 test, and provide a name for the test case class, the common naming convention would be to add a Test suffix to the class under test, i.e. CustomModuleBeanTest in this case.
If it is the first time a JUnit test case is created in the project, the following prompt will be displayed to enable adding the libraries required for JUnit testing. Click OK.
Once the skeleton test case is created, we can add the logic below to complete the JUnit test case.
Following are the explanation of the key parts of the JUnit test case.
1. Each method that will be considered a test scenario and executed by the JUnit framework should be annotated with @Test.
2. The first few declarations determines the input files for this particular scenario. These files are resource files within the project as mentioned above.
3. A new instance of the ModuleTester class is created passing in the fully qualified name of the class under test.
4. The JUnit assertEquals() statement is executed to compare the runtime output of the module (returned from mt.execute()) against the expected output (from TestData/output.txt file). Note that JUnit provides many other assert conditions for test different cases. For this example, it will be a straightforward String comparison between the two values.
Running the JUnit Test Case
Once the test case has been fully written, it can be executed by right-clicking the JUnit Test Case, select Run As > JUnit Test.
For this example, the following will be the input files. The input parameter file is a tab-delimited file consisting of the parameter name and value pairs. Based on the module logic, the module should replace the MT_Calculator_Input name with New_Root for the root element of the XML payload.
Once running the JUnit test, the results will be presented in a the JUnit view, which displays the number of test scenarios executed and their results.
If the comparison is unsuccessful, it will be flagged as a failure as shown below.
In the below simulated failure, the output deviated from the expected results, and we can view the comparison by clicking on the button at the right hand corner (Compare Actual With Expected Test Result).
JUnit Test Suite
In addition to test cases, it is possible to bundle them into a JUnit Test Suite. This allows for the execution of multiple Test Cases in one go. The following is an example of a JUnit 4 Test suite that will execute numerous JUnit 4 Test Cases.
Note: Unfortunately, due to a bug in Eclipse Galileo (which NWDS 7.31 is based on), the built in Wizard does not allow for automatic creation of a JUnit 4 Test Suite based on JUnit 4 Test Cases. As such, the above was manually created as a normal Java class, with the logic manually added following JUnit 4 framework.
Execution of a JUnit Test Suite is similar to that of a Test Case.
The full source code for all the objects related to this article (module under test, testing class, test case and input files) are provided in the following GitHub repository.
As shown in this article, the standalone NWDS testing approach can be extended with JUnit to incorporate automated regression testing. With such testing, it provides confidence whenever changes are introduced to an existing adapter module. The testing can also be executed very fast once all the Test Cases are written. As an example shown in the screenshot below, 30 test scenarios were executed in just over 2 seconds, and it is possible to quickly identify any failures for further analysis and troubleshooting. This would have taken a much longer time and effort if it were performed manually either via standalone NWDS testing or end-to-end testing on the server.