At Spark Consulting, we put a great emphasis on automated testing of our code. Doing so has a bunch of benefits:
- we can ship things with confidence knowing they won’t cause any regressions or unintended side effects
- it makes it easier to review changes because I can easily see how a piece of code is intended to work by reading the test; tests essentially act as developer documentation
- allows developers to catch mistakes in their code before committing/deploying
- it keeps code quality high by ensuring we all follow the same sets of conventions
- it’s actually fun; it’s a really great and rewarding feeling to see the following whenever you run your tests after writing some code:
- stress-free deployments, knowing that the chances you unintentionally broke something are pretty low
Our tests are organized as following:
From bottom to top:
Unitcontains our unit tests; most projects actually have very few of these. We mostly use unit tests to test a few key pieces of custom functionality and relationships between Models. Unit tests don’t generally load the entire Laravel application. Almost everything else in the php codebase is tested as a Feature test.
React(sometimes also just named
jsdepending on the project) contains tests written using the
jesttest runner and in the case of React, the
Featurecontains tests that ensure that our php codebase works as expected by loading the entire Laravel application and performing full Http requests. These are primarily API tests to ensure our API endpoints work as expected, but anything that is php-driven and requires the application to test would be a Feature test in my approach.
Browsercontains end-to-end integration tests that test the web application in a browser directly, using the new Laravel Dusk testing utility. We use these to test individual pages at a pretty high level and ensure that key data and key functionality works as expected.
Having these different levels of testing allows us to ensure the application works correctly from different angles, and covers all of our bases. Think of Browser tests sort of being the super zoomed-out view, where we can ensure that the main pages and functions of the site work as expected, and then we slowly zoom in with feature tests, js tests and unit tests ensuring that each piece of our codebase works as expected.
With this setup we end up with three different testing commands:
phpunitwhich runs both our Unit and Feature tests
php artisan duskwhich runs the browser tests
jest(which we alias in our
package.jsonso we can run
npm run testor just
If you’d like to learn more about Test Driven Development with Laravel, I highly recommend Adam Wathan’s Course. Even though I already grasped the basics, Adam’s course really cemented some best practices and showed me a better way of thinking and approaching tests.
In the next blog post, I’ll go through our Continuous Integration setup and explain how we automate all of this testing so that each Pull Request/deployment gets automatically tested.