The Unit Tests and Code Coverage can seem complicated to be implemented into your SharePoint Framework components; the time of implementation of this kind of automation can seem excessive compared to the obtained result. Adding unit tests can take some time especially if the developer does not have the habit to do it.

The aim of this post is to bring out the prerequisites, the environment, the use cases, and the benefits. In fact, some blog posts about that already exist, but I did not find any of them enough complete and some of them were deprecated (SPFx 1.7.0 for some of them).

Based on my experience, every time I tried some tutorials and samples, it did not work as expected and I spent a lot of time searching for solutions. Now, I created a standard setup that I am using for all of my components as much as possible.


It is important to note that it is very difficult to perform unit tests on the controller (ex: ...WebPart.ts) due to the complexity of the object class. The best way to do it is to split your custom code into other files and consume them from the controller.

Prerequisites

  • SharePoint Framework : 1.11.0
  • NodeJS: 10.x

Setup

The minimal setup to use Jest to perform the tests on the models and basic TypeScript files.

  • Create a new Web Part component based on the React Framework
  • For this example, you can create a model folder located into src/webpart/yourWebpart/
  • Create a SharePoint.ts file with the following content:
    enum EnvType {
        'Online',
        'On-Premise'
    }
    
    export default class SharePoint {
    
        private _env: EnvType;
    
        private _version: string;
    
        constructor() {
            this._env = EnvType.Online;
        }
    
        public get env(): EnvType {
            return this._env;
        }
    
        public set env(value: EnvType) {
            if (undefined == EnvType[value]) {
                throw TypeError('EnvType is out of range.');
            }
            this._env = value;
        }
    
        public get version(): string {
            return this._version;
        }
    
        public set version(value: string) {
            this._version = value;
        }
    }
    
  • Rather than create a folder named test, I suggest that you create a test file in the same location; create a file SharePoint.test.ts with this content:
    /// <reference types="jest" />
    
    import SharePoint from './SharePoint';
    
    describe('SharePoint model', () => {
        it('should create a SharePoint instance', () => {
            let s = new SharePoint();
            expect(s).toEqual({
                _env: 0
            });
        });
    
        it('should set SharePoint._env to the passed argument \'1\'', () => {
            let s = new SharePoint();
            s.env = 1
            expect(s).toEqual({
                _env: 1
            });
        });
    
        it('should throw an error when EnvType is out of range', () => {
            let s = new SharePoint();
            expect(() => { s.env = 3 }).toThrow(TypeError);
        });
    
        it('should return the \'env\' value when the getter \'env\' called', () => {
            let s = new SharePoint();
            expect(s.env).toEqual(0);
        });
    
        it('should set SharePoint._version to the passed argument \'15.0.4693.1000\'', () => {
            let s = new SharePoint();
            s.version = '15.0.4693.1000';
            expect(s).toEqual({
                _env: 0,
                _version: '15.0.4693.1000'
            });
        });
    
        it('should return the \'version\' value when the getter \'version\' called', () => {
            let s = new SharePoint();
            s.version = '15.0.4693.1000';
            expect(s.version).toEqual('15.0.4693.1000');
        });
    });
    

NPM Packages

Before configuring and executing the unit tests, it is necessary to install several packages:

  • The Jest testing Framework packages, that allow running the unit tests:
    npm i jest @types/jest ts-jest jest-junit --save-dev
    

Jest Configuration

Some changes must be performed on several files to launch tests

  1. Edit the package.json file by editing the scripts part like this:

    "scripts": {
       "build": "gulp bundle",
       "clean": "gulp clean",
    -  "test": "gulp test"
    +  "test": "jest"
    },
    
  2. Without a specific configuration for Jest, the unit tests will not work. It is necessary to specify the configuration as illustrated in the Jest documentation. In our case, I will choose to use the package.json file to implement the configuration by adding these lines at the top of the file:

    {
      "name": "yourwebpart",
      "jest": {
        "verbose": true,
        "moduleFileExtensions": [
          "ts",
          "tsx",
          "js"
        ],
        "transform": {
          "^.+\\.(js|ts|tsx)$": "ts-jest"
        },
        "testMatch": [
          "**/src/**/*.(test|spec).+(ts|tsx|js)"
        ],
        "testResultsProcessor": "jest-junit"
      },
      ...
    }
    
  3. Launch your tests:

    npm run test
    
  4. Collect the coverage information by adding the following configuration in the jest node of package.json:

    {
      "name": "yourwebpart",
      "jest": {
        ...,
        "collectCoverage": true,
        "coverageReporters": [
          "text-summary"
        ]
      }
      ...
    }
    
    LsOnline-SPFx-UnitTest02

[success]Tips

Update .gitignore file by adding junit.xml to exclude this file from the commits

[note]Note

Jest uses the same reports as Istanbul. You can find the list on the Istanbul repository



Hoping this post will help you πŸ˜‰

You may also be interested in