How we do testing in PnP JS Core
Recently we added support for testing the library directly against SharePoint. While the effort is ongoing to get complete test coverage I wanted to share how we set things up and perhaps this will also help with testing your applications.
Mocha and Chai
The foundation of our testing begins with Mocha and Chai. These two open source packages are a testing framework and assertion library respectively. Put simply, Mocha runs the tests we write using Chai. All of our tests are written in TypeScript and our testing pipeline looks like this:
First we require the libraries we need, these are gulp, mocha, instanbul (which is discussed below) and the gulp typescript transpiler. We then create two tasks, the first "build-tests" builds all the tests (as you might have guessed from the name) and is utilized by the second as a dependent task. The task "test" runs the actual tests, which are now JavaScript files in the output folder generated by build-tests. It does this by gathering the files using gulp.src then piping them to mocha which executes the tests. The results are then piped to the instanbul plug-in. Fundamentally what mocha does it run the files it is given and provide a nice report of the results. A sample test looks like this:
Mocha provides us the functions "describe" and "it" which provides a very clear way to define each test. These described statements can also be nested. The above example is saying "The thing PnP it should have a property util that is expected to not be null." The way we check for null is where Chai comes in. The body of the function supplied as the second parameter to "it", which is the test to execute, uses chai's expect function. This then allows us to chain off in a fluent way a description of what we expect to happen. This is a relatively simple example but there are many types of tests you can do with Chai.
Instanbul
As mentioned above another plug-in we use is called Istanbul, which is a code coverage tool. This generates a report of how much of our code is covered by tests - as well as letting us know lines which are currently missed by tests. Once the tests are run the report is shown via the second pipe to instanbul.writeReports(). Istanbul is configured in another dependent task "instanbul:hook" which looks like this:
This task grabs the compiled js output files, pipes them to Instanbul, and then executes the hookRequire method activating the plug-in and preparing it to measure the test coverage.
Chai as Promised
What we have covered so far only support synchronous tests - so how do we support the asynchronous nature of the library? Enter Chai as Promised. This library extends Chai to support promises and the idea that they will be fulfilled. This is done by adding in the "eventually" property to your Chai fluent chain. You can also control various settings, notable the timeout for each function. See the example below:
The above example, from the web tests, uses eventually along with the "fulfilled" property to indicate that we expect this request to eventually be fulfilled. In this case we aren't checking the result, just that the request successfully completes. Any http error responses would cause this test to fail. We could also check the results of a series of calls, provided they can be chained as promises - let's take a look at a more complicated test:
Here we have created a list using ensure and verified we can get it's title and that the title equals what we think it should. There are many other options and browsing through the tests is a good place to start. As said above we don't yet have 100% coverage for these web tests, but we are improving steadily and always welcome help. Just comment in the related issue to grab a file.
Node Fetch Client
Enabling this testing against SharePoint is the addition of the NodeFetchClient which makes requests using the same API surface as the browser fetch - allowing us to accurately test the usage of the library. This was added in the 1.0.3 release and you can read more on the release blog post around the node client support.
Typings
A quick note, we also installed the typings for these libraries which are: chai, mocha, chai-as-promised, and promises-a-plus - doing so in your projects will add intellisense and help you to construct your Chai chains.
What is the JS Core Component?
The Patterns and Practices JavaScript Core Library was created to help developers by simplifying common operations within SharePoint. This is aligned with helping folks transitioning into client side development in support of the upcoming SharePoint Framework. Currently it contains a fluent API for working with the full SharePoint REST API as well as utility and helper functions. This takes the guess work out of creating REST requests, letting developers focus on the what and less on the how.
“Sharing is Caring”