CI / CD Pipeline Patterns For JavaScript (Part 3)

More pretending to actually work

Part one and part two of this series covered the basic building blocks for implementing CI and CD pipelines in a JavaScript world. This final short piece will talk about some further stages you could use to extend the levels of assurance on your application, the need for which will vary depending on your application.

Component / E2E tests

While unit testing is a great way to provide assurance that your application is going to behave in the way that you expect, it is not without its limitations. Metrics like unit test coverage are fairly easy to game if a developer so desires, and even the best developer can’t conceive of every possible use case. Additionally, each individual function you write may do what you expect, but when combined produce unexpected results. This is where an extra layer of testing, focused on the rendered user interface (UI) rather than the code implementation itself, can be useful. Quality Assurance (QA) tests, or component tests, can test your individual elements as if a user was interacting with them, while the End to End (E2E) tests can cover a whole journey through your app, ensuring the overall experience is as expected, and consistent.

But where to put these in the pipelines? These jobs will generally take longer to execute, and if your app gets large they can really slow down your time to deployment, which can be frustrating particularly if you’re only deploying to a test environment. One solution can be to only run these tests on a commit to master, or release branch, to ensure everything is green before deploying to production. This solves the deployment problem, but running the tests less frequently means the advantages gained from CI can be reduced, as problems will now only be detected further down the line. A potential middle ground is to run the tests on a commit to master as well as periodically run them against your deployed website develop branch, to pick up problems there as well, and still enable rapid deployments to the test environment.

Performance, Security, Accessibility

Beyond the scope of testing your code’s functionality and user experience, there are a number of other types of testing which often get overlooked. While all of these may not be necessary for a large amount of applications, larger scale projects should definitely look to implement these early on as the idea of CI shows that catching problems early is much better and easier to fix than catching them just before you go live, or even after, which can be catastrophic.

Similar to component and E2E tests, performance and security tests can take longer to run, and so probably should not be part of your primary pipeline. They should be run periodically, perhaps overnight or first thing in the morning, to ensure problems are called out as close to when they occur as is possible.

Performance testing is a huge discipline, the scope of which is outside this article, but it’s important to note that even basic performance tests on your Node applications can let you understand how much you need to scale your system, and at how many users you are likely to encounter problems. Benchmarking your app early also means you know when performance is starting to degrade and can react accordingly. Many tools exist to help you do this. Front end frameworks such as React also come with tools to enable performance testing of your website.

Similar to performance testing, security is a rabbit hole which could go on forever if you so desired. Without being a dedicated security specialist you probably won’t be able to secure an application against every single attack known to man, but the same concept of being vigilant early on means you’re less likely to be caught out by a security team at release time, and even better if you can get security involved from the start themselves! It’s fairly straightforward to get set up with tools to protect yourself against the most common vulnerabilities, which is a better starting point than the majority of applications at the moment.

Finally, if you know you’re going to be building an app for a large amount of accessibility users, automating this testing can be a huge time saver. The WCAG guidelines are monstrous and no one can be expected to be compliant with that manually. Additionally, accessibility considerations really go all the way back to the design of your application rather than just the implementation, so the need to catch these early before the cost of change becomes massive is even greater. Many developers probably aren’t even aware that their applications aren’t compliant either — check your most recent project with something like WAVE and see how much you’ve covered.

Conclusion

So there you have it, a series of building blocks and patterns to bring CI and CD to your JavaScript applications! If you’ve not worked with these practices before I highly encourage you to give them a go — you won’t be able to imagine working without them once you do. It is important to note however, that CI and CD isn’t everything. It doesn’t stop malicious or inexperienced developers writing bad code but it does mean you can catch more problems earlier and more frequently. Things like manual peer reviews of code, pair programming and other extreme programming techniques should also be used to really ramp up your team and code quality. The techniques described here don’t immediately make your team or organisation “Agile” or mean you’ve implemented “DevOps”, but they do enable you to begin that larger transformation.