Skip to Content
Technical Articles
Author's profile photo Jakob Marius Kjær

Code coverage for your automated testing in SAPUI5 using ui5-tooling middleware

HI all.


This is a bit of an announcement blog as I finally got around to update my outdated ui5-middleware-code-coverage plugin to be able to handle es6. The old plugin used istanbul-middleware as the main package to instantiate an express server. The problem was that the repository wasn’t maintained anymore and couldn’t handle es6 code like arrow functions and async/await.

With the new release “currently” 2.0.3 this plugin now supports everything as I written a new NYC-middleware package instead

Be aware that currently it works by adding the necessary .nyc_output folder to your repository and running NYC report from that. When you generate the coverage you will get a coverage folder in your repository which will automatically delete itself when you choose to download.

Let me show you by an example:

First generate a new SAPUI5 project. I’m using the Easy-UI5 by Marius Obert to get started

Run command after doing the installation as explained on the github page

yo easy-ui5

For this example I just stick with all the proposals and let the NPM install run.

Afterwards enter the repository and install the middleware component

npm install ui5-middleware-code-coverage --save-dev

Now add the config to the package.json file and ui5.yaml(Bear in mind that i’m using the easy-ui5 package as it comes and the webapp folder is in a uimodule subfolder. If you are adding to an existing project, you might have the webapp folder in the root and therefore don’t need the uimodule prefix)



I’ll add a button to my mainview and a controller to display a dialog. Code is mostly just copied from the SAPUI5 documentation samples.

 <mvc:View controllerName="com.myorg.myUI5App.controller.MainView"
  <App id="idAppControl" >
      <Page title="{i18n>title}">
          <Button id="btnPress" text="Press me" press="onPress" />
], function(Controller, Dialog, Button, Text) {
  "use strict";

  return Controller.extend("com.myorg.myUI5App.controller.MainView", {

     * Event handler for the button on the mainview using async/await
     * @returns {void}
    onPress: async function(){
      const text = await this.delayedResponse();
      if (!this.oDefaultMessageDialog) {
				this.oDefaultMessageDialog = new Dialog("myDialog", {
					type: "Message",
					title: text,
					content: new Text({ text: "Test" }),
					beginButton: new Button({
						type: "Emphasized",
						text: "OK",
						press: function () {

     * Promise to return back a text after 3 seconds
     * @returns {Promise} Promise with a timeout to send hello world
    delayedResponse: function(){
      return new Promise((resolve, reject) => 
      setTimeout(() => {
        resolve("Hello world");
      }, 3000));


Now let’s use UIveri5 as the testing tool. Follow the instructions on how to get it installed from the github page.

I want to show a nice little plugin created by Adrian Marten  that I discovered recently called UI5-test-recorder. It has a fair bit of functionality and is open source.

You can also check it out here from UI5con 2019.

Let’s add our first test.

I created a folder in my webapp called test and in there a conf.js file containing the following:

exports.config = {
    profile: 'integration',
    baseUrl: 'https://localhost:8080/index.html',


Now I’ll use the test recorder to press my button and assert my text.



Then i can export the code


I copy this to a file called test.spec.js in the same test folder. I will then change the code slightly to handle my delay and the exact text match.

describe('test' , function () {
    it('Test 0', function () {
        var button = element(by.control({ id: /idAppControl--btnPress$/}));;
        var title = element(by.control({ id: /myDialog-title$/}));
        expect(title.getText()).toBe("Hello world");


Now when we run uiveri5 in the test folder i should hopefully come back positive. (make sure to run the serve:uimodule script as well from the package.json file.


So far so good. Now let’s add the coverage to the output.

Add the following function to your test.spec.js file. This function will execute after each test run.

    afterAll(() => {
            type: "POST",
            url: 'http://localhost:3000/coverage/client',
            data: JSON.stringify(window.__coverage__),
            headers: {
              'Accept': 'application/json',
              'Content-Type': 'application/json'


Change the test script in the package.json folder to

"test": "cd uimodule/webapp/test && uiveri5 && nyc report",


And finally enable the code coverage in the yaml file

by setting the enabled to “true”

Make sure to restart your server and then run the npm test command.

We will now get a nice little summary of the code coverage.


A folder has been added to your root called .nyc_output. This is the coverage file. You can also run command

nyc report --reporter=html
nyc report --reporter=lcov

To get a html report or lcov formatted report.


If you run your testing manually. Then you can submit the code coverage to the middleware by pasting the following into your chrome debugger

  type: "POST",
  url: 'http://localhost:3000/coverage/client',
  data: JSON.stringify(window.__coverage__),
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'


Then visit http://localhost:3000/coverage to see the HTML report as well.

Happy testing!

Assigned Tags

      You must be Logged on to comment or reply to a post.
      Author's profile photo Gijs Pruijmboom
      Gijs Pruijmboom

      Hi Jacob,

      Thanks for your blog. As i understand the ui5 app is started by the "UI5 serve" command. This command uses the configuration provided by ui5.yaml.

      When i run "ui5 serve" i can see that the coverage service is started and made avalable at port 3000.

      However, in our project we start the webserver by launching "approuter.js". when we run our app using approuter, the coverage service is not being launched. What is the approach to achieve this?

      Author's profile photo Jakob Marius Kjær
      Jakob Marius Kjær
      Blog Post Author

      Hi Gris,

      I haven't tested out the middleware with the approuter. Does other extensions work with this setup?

      Author's profile photo Cynthia He
      Cynthia He

      Hi Jacob,

      Could you please provide one example for me to use it ,Acutally for my real project ,the coverage is always zero, I did not know which point is wrong from my side ,hope you could guide me a lot .

      Author's profile photo Jakob Marius Kjær
      Jakob Marius Kjær
      Blog Post Author

      Hi Cynthia,


      Sorry I didn't see your reply before. Are you sending the resting call to submit the coverage to the collector?


        type: "POST",
        url: 'http://localhost:3000/coverage/client',
        data: JSON.stringify(window.__coverage__),
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'