Skip to Content
Technical Articles

SAPUI5 Opa5/QUnit Enabling Tests’ Local Code Coverage

Recently, I found out that there was no public given way using only QUnit to show code coverage on both Opa5 and QUnit. I decided to make an article to make the process easier for those people who want to see the code coverage of their tests.

This article assumes that you have your project set up with jQuery, QUnit and OPA5. It also assumes that you already have an html page set up to see the results of your OPA5 tests and QUnit tests.

All you need to do is add this line on the top of the file handling all of your QUnit/OPA5 tests (for me: AllJourneys.js), right after the QUnit “requires”:

jQuery.sap.require(“sap.ui.qunit.qunit-coverage”);

There should be these right before:

jQuery.sap.require(“sap.ui.qunit.qunit-css”);
jQuery.sap.require(“sap.ui.thirdparty.qunit”);
jQuery.sap.require(“sap.ui.qunit.qunit-junit”);

So that QUnit is defined.

You need to place this code wherever your qunit is integrated in your project structure. This could be in some .qunit.html extension file or some Javascript file handling all tests.

This will show a new checkbox, called “Enable coverage”, when running the file that runs all of your OPA tests. You have to select that checkbox to show the code coverage of your tests. This checkbox is located on the top left of your screen along with the other QUnit checkboxes.

If you want to check it automatically, find the word “coverage” in your URL, and set it to true: on my URL, there was only the word “coverage”. Replace “coverage” by “coverage=true” in the URL.

When your tests finish running, a list with the header “Blanket.js results” will appear. Any file below can be clicked on to get further information about what parts of the file you did cover/not cover. There is also percentage information on the right hand side of each file name.

Filtering Output Files

Also, if the files that end up appearing on the code coverage are not the ones that you want, you will have to put some lines of code instead on your html files for QUnit ( .qunit.html extension files).

It is covered here: https://openui5.hana.ondemand.com/#/topic/7ef32428dc7c4c048a8d7e8de0a556fb

Note: There might be a different amount of “../” in their example to reach the resources file.

Here is one way to do it:

Right after the ‘jQuery.sap.require(“sap.ui.qunit.qunit-coverage”);’ line, place your code:

if(window.blanket){
window.blanket.options(…);
}

If SAP Web IDE is used, use the keyword window in front of blanket because SAP Web IDE marks it as an error otherwise.

You can place anything you want where the three dots are. This could be, for example:

"sap-ui-cover-only", "[sap/ui/core/Popup.js, sap/ui/core/EventProvide]"

To cover only the files Popup.js and EventProvide. From this example, you can understand that to cover multiple files you can add the square brackets [ ] .

Look at further examples on the link given above.

This gives an idea what your code should look like after following the above steps. Everything added is delimited with dashed lines:

jQuery.sap.require("sap.ui.qunit.qunit-css");
jQuery.sap.require("sap.ui.thirdparty.qunit");
jQuery.sap.require("sap.ui.qunit.qunit-junit");
//-8<-------------------------------------------------------------------------
jQuery.sap.require("sap.ui.qunit.qunit-coverage"); //added

//this is the filter. This covers only the Opa5.js file. See the importance of covering at least
//one file below.
if(window.blanket){
     window.blanket.options("sap-ui-cover-only", "sap/ui/test/Opa5.js");
}
//-8<-------------------------------------------------------------------------
//below provided for context...
QUnit.config.autostart = false;

sap.ui.require([

The code below was shown to give context: those jQuery.sap.require calls must be before any line of code from sap.ui.require that handles the tests.

Particularity Using an IFrame in OPA

It seems that the IFrame (“the second screen”) generated for OPA testing does not capture the files that are used inside of the IFrame. There is a way to make it work.

This code should get added to the file running in the IFrame (for me, flpSandboxMockServer.html). The code to be added is delimited with dashed lines:

<script type="text/javascript">
                sap.ui.getCore().attachInit(function() {
// -8<------------------------------------------------------------------------------------------------------------------
                      window.QUnit = Object.create(window.parent.QUnit || {
                           urlParams: {coverage: false}
                      }); // Might not exist
                      if (QUnit && QUnit.urlParams.coverage) {
                           function noop () {}
                           QUnit.begin = noop;
                           QUnit.done = noop;
                           QUnit.moduleStart = noop;
                           QUnit.testStart = noop;
                           QUnit.testDone = noop;
                           var _$blanketCache = window.parent._$blanketCache;
                           if (!_$blanketCache) {
                                 _$blanketCache = {
                                      getItem: function (key) {
                                            return _$blanketCache[key];
                                      },
                                      setItem: function (key, data) {
                                            _$blanketCache[key] = data;
                                      }
                                 };
                                 window.parent._$blanketCache = _$blanketCache;
                           }
                           window._$blanketCache = _$blanketCache;
                           var _eval = window.eval;
                           window.eval = function (sScript) {
                                 if (sScript.indexOf("sessionStorage&&sessionStorage.getItem") > -1) {
                                      sScript = sScript.replace(/\bsessionStorage\b/g, "_$blanketCache");
                                      window.eval = _eval; // disconnect
                                 }
                                 _eval(sScript);
                           };
                           jQuery.sap.require("sap.ui.qunit.qunit-coverage");
                           blanket.noConflict().setupCoverage();
                           blanket.noConflict().options({
                                 instrumentCache: true // force cache since the app will be restarted
                           });
                           window._$blanket = window.parent._$blanket; // Connect to parent
                      }
// -8<------------------------------------------------------------------------------------------------------------------
                      sap.ui.require([
                           "sap/ui/fl/FakeLrepConnector",
                           "hpa/cei/setupapp/test/mockserver",
                           "hpa/cei/mkt/lib/opa/i18nCheck",
 
                      ], function (FakeLrepConnector, server) {
                           FakeLrepConnector.enableFakeConnector("fakeLRep.json");
                           server.init();
                           sap.ushell.Container.createRenderer().placeAt("content");
                      });
                });
           </script>

Thank you Arnold Buchholz for providing a solution to this problem.

This code above will take into account all the files that are used in the IFrame, which include all of your controllers (e.g. the files you probably want to get their test coverage percentage, located in the controller folder of your project).

Filtering Output Files with the Code Above

This new code will change the way the filter works. In the original file where the filter was applied (for me, AllJourneys.js), if the filter excludes all files outside of the IFrame, there will be no output files shown in the code coverage section. In other words, at least one file should be covered in the filter that you have applied after the QUnit require functions (see the first code snippet). This is why I was covering the file Opa5.js in my first code snippet.

What needs to be done to limit the amount of output files:

  • Apply a filter in the location where you are taking in all tests/journeys (for me, AllJourneys.js) that returns at least one file.
  • Apply another filter right after this line in the second code snippet to cover only the files you want to be covered by the test coverage tool Blanket: jQuery.sap.require(“sap.ui.qunit.qunit-coverage”);

 

Note: This second filter concerns the files present in the IFrame, while the first filter concerns the files present outside the IFrame.

Note: I do not know if it works across all browsers. I used Google Chrome to see my tests’ code coverage.

 

All of this can be done by simply using QUnit. The process could not be made any easier. I hope this information will facilitate the addition of code coverage to an already existing project.

-Alexandre Therrien

1 Comment
You must be Logged on to comment or reply to a post.
  • Hey Alexandre!

    Thanks for this nice post, it helped me find the need configuration for my case.

    From what I was able to find here https://github.com/alex/seville/blanket/blob/master/docs/options.md

    You can have something like this

    if(window.blanket){
      window.blanket.options("sap-ui-cover-only", "[myComponentID/]");
      window.blanket.options("sap-ui-cover-never", "[myComponentID/test,myComponentID/localService]");
    }

    To cover all the files in your project but not tests itself or mockserver configuration.

    Hope this helps somebody else as well.

    Regards, Alex