Azure / Office 365 / SharePoint Development / Search

Extend Karma to get better code coverage and test reports for your SharePoint Framework solutions

September 26, 2017

In one of the previous posts I showed that since SharePoint Framework version 1.2.0, code coverage reports were added. When you run the gulp test task, it will execute the tests, and generate a code coverage report which you can find under the temp/coverage/js project folder.

Read more about this in the following article: SharePoint Framework code coverage reports for unit-tests

In a code coverage report, you can check if your unit-tests covered all your code. If you already checked out these reports, you might have noticed that they can almost never be 100% covered. In some cases, you still have to write a couple of tests, but for SharePoint Framework (and any other TypeScript) project, this is in many cases related to something else. In SharePoint Framework, we write everything in TypeScript, once we start the tests, it will transpile all the TypeScript to JavaScript files and does the tests and code coverage reports based on the JS code.

Is that wrong? No, it is not, but when you open the code coverage report, you will see code that will never get covered. Like for example this:

__extends TypeScript helper function

__extends TypeScript helper function

In this example, you see the __extends function which is not completely covered. This is not a function you wrote yourself. It is a function TypeScript automatically adds to your JS file when you are extending classes in your TS. Basically, it is a helper function to support extending in ES5 code.

But how can you get full coverage for this? Luckily there are some plugins for Karma and Istanbul that can give you better reports based on the original TypeScript code. In order to get these reports, you have to extend the default SharePoint Framework Karma configuration.

Extend the Karma configuration in SPFx

Important: Credits go where credit's due. Vincent Biret already shared this in one of his talks and spfx-devops-vsts GitHub repository. I would like to thank him for sharing the configuration.

In order to extend the Karma configuration in your SPFx solution, you first have to create a new karma.config.js file. The basic configuration looks as follows:

To allow the Karma process to pick up your configuration file, you will have to update the gulpfile.js content to this:

Important: Check the path to your Karma config file in the last line. In my example I added it to the config folder.

Add better code coverage reports

Now that the basic configuration part is done, you can start to do additions to the configuration. For example, in order to get better code coverage reports, you can make use of a Karma plugin called: karma-remap-coverage.

First, you will have to install this to your project with the following command: npm install karma-remap-coverage --save-dev --save-exact

Once installed, open your karma.config.js file, and include this plugin to the file:

The next step is to add the configuration for this plugin. After the existingKarmaConfig(config); line, add the following code:

Now run your gulp test task again, and you should get a new HTML folder in the temp/coverage directory. If you check the generated index.html file. You will notice that the outcome will be different to the first generated coverage report. Here is the outcome of my JS coverage:

Default code coverage report

Default code coverage report

Here is the new report:

Code coverage report after extending the Karma configuration

Code coverage report after extending the Karma configuration

The placeholder coverage went from 90.63% to 100%. All had to do with the __extends helper function. In the newly generated report, you can see that the coverage is based on the original code.

React TSX component file

React TSX component file

What can you do more?

There is a lot you can do once you have this in place. If you go to the npm site, you can search for Karma plugins which can further extend your unit-tests. One other useful plugin which I like to use is the HTML reporter. This generates an HTML file of the unit-test outcomes. Which is a lot easier to check that the console output.

In order to get the Karma HTML reporter, you first have to install it via: npm install karma-html-reporter --save-dev --save-exact

Add the following to the karma.config.js file:

This is the required configuration:

When you now run your unit-tests, you should see a new karma-html-report folder in the temp directory. If everything went good, it should contain an HTML file with the following output:

HTML test report

HTML test report

You can check the following project to see the complete configuration: https://github.com/sharepoint/sp-dev-fx-controls-react

Happy testing!

Comments

  • Pingback: Big Announcements from Ignite; SharePoint and OneDrive Sync Issue; AI and Hybrid Cloud at Ignite()

  • Pingback: How to debug your SharePoint Framework unit-tests - @eliostruyf()

  • StefanSchoof

    I added the karma-remap-coverage to my karma.config.js in my SPFx 1.4 test project. It does generate a html report, but when I click in the report on any file, I get a file not found. In the gulp test output, I have a `(node:10060) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: ENOENT: no such file or directory, open ‘C:UserssschoofSourceReposSD-SPFxlibwebpartshelloWorldcomponentsHelloWorld.module.scss.ts’
    The file HelloWorld.module.scss.ts does only exists in the src folder and not in the lib folder. Any Idea how I get the remap part working with the sass typescript?

    • The TS file for your SASS styling should be created when you built your solution. During a test run, it will also built it. If it does not built a TS file, check the SCSS file instead. It needs to contain a class with a CSS attribute defined. If it is empty or it contains a class without attributes, nothing will be created and you get that error.

      • StefanSchoof

        Thanks for the quick answer.
        The file is not empty (is a simple SPFx WebPart Project with React and the generated HelloWorld WebPart)

        I have the ts file, but in the srcwebpartshelloWorldcomponents folder. The error message comes from the libwebpartshelloWorldcomponents folder. And there ist only a a HelloWorld.scss.d.ts (with d in between)

        • And what happens if you run gulp or gulp bundle? It should give the same error, as gulp test will first execute these tasks.

        • StefanSchoof

          No I this error is only printed in the test part. With more context:

          Start:

          √ Should do something
          √ should render something

          Finished in 0.059 secs / 0.006 secs

          SUMMARY:
          √ 2 tests completed
          08 01 2018 13:45:56.868:DEBUG [karma]: Run complete, exiting.
          08 01 2018 13:45:56.870:DEBUG [launcher]: Disconnecting all browsers

          =============================== Coverage summary ===============================
          Statements : 100% ( 11/11 )
          Branches : 100% ( 0/0 )
          Functions : 100% ( 3/3 )
          Lines : 100% ( 10/10 )
          ================================================================================
          (node:1444) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: ENOENT: no such file or directory, open ‘C:UserssschoofDocumentsGitHubSPFx-remaplibwebpartshelloWorldcomponentsHelloWorld.module.scss.ts’
          08 01 2018 13:45:57.025:DEBUG [launcher]: Process PhantomJS exited with code 0
          08 01 2018 13:45:57.026:DEBUG [temp-dir]: Cleaning temp dir C:UserssschoofAppDataLocalTempkarma-92355521
          08 01 2018 13:45:57.042:DEBUG [launcher]: Finished all browsers

        • So there is an incorrect mapping somewhere in the component or test. As the lib folder should only contain the .js and .d.ts file.

          What did you define in your tests?

        • StefanSchoof

          I simply import the webpart with ‘import HelloWorld from “../components/HelloWorld”;’. The full test is in my github under:
          https://github.com/StefanSchoof/SPFx-remap/blob/master/src/webparts/helloWorld/tests/HelloWorld.test.tsx

        • Tested out your sample and it seems something goes wrong with the source mappings in v1.4.0. Because the error occurs for every file you use.

        • Seems to be an issue with the karma-remap-coverage module in combination with SPFx version 1.4.0.

          I tried out another module to remap, and that one seems to be working fine. The one I have tested is: karma-remap-istanbul

          Configuration is:

        • StefanSchoof

          Thanks, this works for me.