ABAP Unit-Testing via Azure DevOps Pipelines
Motivation and Functionality
In this blog we want to show how ABAP Unit-Tests can be run from a CI/CD pipeline. This is relevant for all applications where automated deployment shall be achieved. We run the respective ABAP Unit-Tests through automatically triggered Azure DevOps pipelines. Graphically displayed test results are also desired to be obtained. In the following, I will start by explaining the rough procedure and architecture. A graphical delineation can be viewed in figure 1.
Meanwhile, the respective Node.js-App is pushed into another GitHub repository. This Node.js-App repository is then cloned in our pipeline, so that we are able to run the Node.js-App through running our triggered Azure DevOps pipeline. In doing so we use a different repository than the one in which we store the ABAP package. Otherwise it would be necessary that all the GitHub repositories of all the ABAP packages that shall be tested, and upon which we place Azure DevOps pipelines, contain our Node.js-App. This would be inconvenient and could eventually cause additional maintenance efforts. By cloning a particular Node.js-App repository, we avoid these issues and potential referencing complications.
Altogether, if an ABAP class to be tested is changed and committed into its ABAP package’s GitHub repository, a connected Azure DevOps pipeline will be triggered to run, which starts a Node.js-App that calls Unit-Tests on the ABAP class and delivers JUnit-formatted test results.
Finally, a ready-to-use task in our pipeline enables us to display test results in a JUnit format as expressive graphics in Azure DevOps.
Tutorial and Guidance
Initially, we tried to take advantage of the abap_test_runner_cli, which promised to run Unit-Tests through command line inputs. This nevertheless failed to be integrated in our Azure DevOps pipeline. For further information regarding the abap_test_runner_cli, see Jakob Marius Kjær’s blog article.
We then switched to Mattias Johansson’s Node.js-App, to which we aligned when implementing our Unit-Test-running Node.js-App. Detailed explanations of the code and of the functionality of the Node.js-App can be found in Mattias Johansson’s respective blog article.
Essentially, our Node.js-App first calls an HTTP GET-request to fetch a CSRF-Token needed to run ABAP Unit-Tests. This CSRF-Token is then included in the HTTP POST-request to run the ABAP Unit-Tests. Thereby, a XML-file that contains a call to run ABAP Unit-Tests is used as body. The ABAP Unit-Testing results are then transformed from AUnit to JUnit format by using a XSL-file.
When starting the Node.js-App, SAP-username, SAP-password, the ABAP-Package containing the ABAP classes to be tested, and the path of the file for test-results have to be specified by the user – for example as follows:
npm start — –username=<SAP-User> –password=<SAP-Password> –package=<Z2607_AZURE_UNIT_TEST> –file=<result/abapResultFile.xml>
The target file is optional. If not specified, a default file will be chosen. This target file contains the XML-formatted test results of our ABAP Unit-Tests.
Now, the Unit-Testing Node.js-App and the ABAP package which contains the ABAP classes to be tested should be integrated into an Azure DevOps pipeline. Therefore, we first push the respective ABAP package in a GitHub repository. This GitHub repository is then used to build an Azure DevOps pipeline, so that a commit in this ABAP package repository can be used as pipeline trigger.
Figure 2 shows in line 6 that our pipeline is triggered by commits of the underlying GitHub repository’s main branch. Further on, Node.js has to be installed.
As seen in figure 3, we then clone a second GitHub repository, which consists of our Node.js-App.
The cloned GitHub repository is stored in a working dictionary which has the same name as the GitHub repository. In this working directory, we then execute the npm install command, and later on the npm start command with specified variables as shown in figure 4.
As explained before, our Node.js-App stores a file with JUnit formatted test results in a dictionary which can be specified by the user. Figure 5 shows that we can include a ready-to-use DevOps task in the pipeline which publishes JUnit formatted test results as graphics.
In figure 6 and figure 7 you can see samples of these expressive test result graphics.
Summed up, we can conclude that automating ABAP Unit-Testing successfully works by applying the mentioned Node.js-App and integrating the App into a pipeline build on the ABAP package that contains the ABAP classes to be tested.
Continuous Integration of ABAP Unit-Testing provides the benefit of automatically triggering Unit-Testing while working on ABAP packages. This definitely saves time and effort.