Building and Testing
It is important to include clear error messages that are printed out when the build
breaks. With unambiguous error messages in place, we should be able to identify
the root cause of the failure in a matter of seconds. There is nothing worse than
staring at a cryptic error message wondering what is going on when we should
be already going live with our project.
Different workflows, different commands
As developers we are responsible for different tasks. One day we might be busy
adding new code (with tests!), and spend time integrating newly developed
features a day after. Our build system should reflect this reality by providing
different commands for different types of workflows. In our experience a build
system should have three different build tasks:
- Fast to run and critical for asserting code correctness: In a JavaScript
project it might mean running jslint / jshint and executing unit tests.
This command should be really fast so it can be executed very frequently.
This build task is very useful for developing code using the Test Driven
Development (TDD) approach. - A command to deploy a fully functional application for testing purposes:
After executing this build task we should be able to run an application in
a browser. In order to do so, we need to do more processing here, such as
generating CSS files and so on. This build task is focused on a UI-related
development workflow. - Production-deployment build task should run all the verifications listed in
the previous step as well as prepare an application for the final deployment,
such as merge and minify files, execute integration tests, and so on.
Build scripts are code too
Build scripts are a part of project's artifacts, and we should treat them with
the same care as any other deliverables. Build scripts will have to be read,
understood and maintained - just like any other source code. Badly written
build scripts can significantly slow down your progress and guarantee some
frustrating debugging sessions.
Tools
The build-system design principles outlined in the previous section can be applied
to any project and any tool set. Our selected tool-chain is operating system (OS)
agnostic, so you should be able to run sample applications or any popular OS.