Unit Test your SharePoint Framework solution with Jest
Why unit test your SharePoint solution?
I have three main reasons to do it. First, if I can unit test all lines, branches and statements of my app then the code is well designed with less technical depth, making it more extensible and flexible to changes. Second, when the change occurs I can easily test my solution for regression in no time. Third, unit tests are a good way to backup myself and the business logic within the solution against someone willing to change the code with no business knowledge and no clue how it should work.
Why should I spend time on tests, this is time consuming?
Yes, the initial effort could be time consuming, but it pays off in time. If you do not have unit tests or any tests you'd have to manually test for regression. Manual testing involves people and time and it grows exponentially when the code base grows. Interesting read in Wikipedia says that you can actually be more productive if you do Test driven development (TDD).
A 2005 study found that using TDD meant writing more tests and, in turn, programmers who wrote more tests tended to be more productive.
My observations show that developers that have experience in writing unit tests are not slowed by adding tests to the solution at all. So, we have to re-think if "time consumig" is not a myth.
How unit tests work with the SharePoint Framework?
The SharePoint Framework is flexible enough and it allows us to decide whether we want to test your solution. Since it is JavaScript based, we have plenty of testing frameworks to test our code. The Jest testing framework is a good fit since it is easy to setup and provides all the features we might possibly need: mocking, asserts, built-in code coverage, coverage threshold for continuous deployment pipeline setups, unit test coverage and summary reports in different formats.
Jest overview and setup with a SPFx solution
Here is a 15 minutes guidance on how to setup and run unit tests with Jest. It covers configuration of Jest with the SharePoint Framework and overview of how to write unit test and debug it.
The PnP SPFx-Jest-Enzyme-Sinon unit testing sample from the demo available in Github
The sample from the video is available in the SharePoint Patterns and Practices repository. You can follow the link below to clone it.
SharePoint Framework React Jest Testing sample
Jest is easy to setup
All we have to do to use Jest is to install few npm packages in our solution, replace the gulp test with jest in the scripts section of the package.json file and then add a jest configuration to the package.json. Here is a diff of the changes I made in my package.json file.
Run Jest tests
Once we've run npm install to get the new packages and we have at least one jest test created we can execute npm test and see the output in the command window or we can use Visual Studio launch configuration for that.
Visual Studio Code Typescript debugging support for the Jest unit tests
The sample above has Visual Studio Code launch.json with all the debug configurations needed to start running and debugging the unit tests for your SPFx solution. There is a Jest All configuration that will execute all the tests on demand. There is also a Jest Watch (watcher) configuration that will let live execution or debugging only on the affected by a change unit tests (if the solution is part of hg/git repo) and will provide immediate feedback if a test passes or fails on component code change. This is good option for Test Driven Development scenarios.
Important: The dedug configurations should be placed in the .vscode -> launch.json file to make the debugging work
The sample has folder named vscode where the launch.json configuration for debugging jest is stored. The configurations should be copied to your .vscode folder -> launch.json file. Once copied into your launch.json, then they will appear in your visual studio code debugging tab.
Basic unit tests scenarios included in the sample to demonstrate how Jest, Sinon and Enzyme can be used to test the SPFx React components
I wrote several unit tests to demonstrate how all testing libraries can be used together to test a React component with business logic and external dependencies included. Examples for mocking promises, pnpjs calls, https calls and spying on methods included for a quick start in unit testing your SPFx solution.
Built-in Jest code coverage
Jest uses Istanbul under the hood to produce various code coverage reports including live VS code terminal output. Such reports can be integrated in CI tools like VSTS (Visual Studio Team Services) or Jenkins.
Jest coverage threshold for continuous deployment pipeline setups
Jest coverage thresholds are set to yield error and potentially fail a build or pre-build if there isn't 100% coverage on branches, functions, lines and statements together. The thresholds can be changed by altering the solution packages.json file where the Jest configuration is.
Unit tests support for SPFx extensions
The sample uses SPFx web part, but the same setup applies for SPFx extensions and they can simply be added to the solution and unit tested the same way.
How to mock or stub your SharePoint Framework web part?
Jest has built-in support for mocks, but I use Sinonjs that is feature rich and has more intuitive apis for spies, stubs and mocks. Examples of mocking with Sinonjs are included in the sample
Conclusion
My opinion is that one SPFx solution should be unit tested and proper CI pre-build and build should be setup to fail when a test fails. Setup of quality gates is the way to go if we want to produce bullet proofed enterprise apps. Having unit tests is trending even for the SharePoint developers now. The Office 365 CLI has more than 4 000 test and 100% coverage by this moment and it is maintained by the SharePoint PnP community. The SharePoint Framework React Controls and the sp-dev-fx-property-controls are maintained in a similar way. These are 3 good examples of where the SharePoint community is heading. Why do not you give it a try?
Reference links
SharePoint Framework unit-tests with Jest - Very good article by Elio Struyf