Automation
Why test things yourself when a computer can do it for you.
Once you're happy and familiar with manual testing, and you're making great websites that work when you spend time making sure everything is correct it's time to raise your game. Automation seems like a daunting prospect at the beginning - the tools are incredibly unfriendly and hard to work with, the concepts can be alien, and figuring out what's wrong when things aren't working is frustrating.
All those things being true, it's hard to see where the benefit lies.
The primary advantage of automated testing is that it bring problems to the surface quicker. Automated tests can be running all the time, so every time you check in a commit your tests can figure out if there's anything wrong. That frees you up to be working on the creative and exciting stuff happy in the knowledge that should anything fail you'll be information immediately. There are further benefits too. If you work in a team you can be sure that the code your colleagues are checking in won't break your features. You can change someone else's code with confidence that you're not going to make a change that stops it working properly. You can know that deploying code to a server is going to work and not lead to an outage.
In short, automated testing is really cool.
The first thing to know is that there are several different sorts of automated tests that you can use. Which ones you pick is a matter of preference and opinion. The internet is full of people who strongly believe that there are right ways and wrong ways of testing, so you may find that some types of tests are labelled as critical or useless. Sometimes you'll find that they're labelled both critical and useless the same time, especially in the case of Unit Testing. Don't let this put you off though. There isn't really a "wrong way" to test. Some testing is better than no testing, even if the testing methods aren't perfect.
The tests that this book covers are;
- Unit testing
- End-to-end testing (aka Functional testing)
- Regression testing
- Performance testing
Unit testing is the process of testing small blocks of code (units) in isolation to make sure they're able to do what they're supposed to do without relying on side-effects from other parts of the code. End-to-end testing is automation of interactions with the code in order to test how the website would be used in real life. Regression testing is making sure your code is correct after a bug has been discovered, and that changes to the code don't break things that already work. Lastly, performance testing is testing that makes sure the code is usable and not frustratingly slow.
One very important thing to understand is that automated testing has a big impact on the code you write. Some code is very hard, perhaps impossible, to test using any of the methods discussed here. Consequently, if you're writing code without tests now, there's a good chance that you're going to need to change the way you work.
That sounds a bit scary. It shouldn't be though. Testable code is better code. If something can be tested then it has a sane, understandable API. That means it's not just easier to work with in tests, it's easier to work with in everything. Your code will be smaller, better defined, with nice-to-use interfaces. That's a really good thing.
There are other aspects of writing tests for your code that you need to be aware of if you've never unit tested things before. The first is mocks. A mock is essentially a 'pretend' version of a module. It has the same API as the proper module but it doesn't actually do any of the work. The reason we use mocks is two-fold. The first is that they enable you to test without using things like internet services or a database. Your mock makes the module you're testing believe the work has been done without actually doing it, so you can test repeatedly and quickly without waiting for a request to complete or a database record to update. The second advantage of mocks is that you can write tests for code that relies on a service before you've even written the service. That keeps everything moving forwards.
The next piece of the testing puzzle is where your tests should run. There are a few different approaches, each with their own advantages and disadvantages.
-
Running tests locally.
A local test environment is a good bet for a small project, or if you're just starting out with testing and you want to try things out. Testing locally is the easiest way to get your tests running, but you're relying on the development machine so the tests won't reflect the environment where the code actually runs, which could be misleading.
-
Running tests on a VM
A virtual machine represents the middle ground for testing - it's not as simple to set up as local testing, but not as hard as a test server, and it can be much closer match to the real world environment that your code runs in (especially for server side scripts). There are a number of great tools to help set up a VM too, which is really helpful.
-
Using a testing server, continuous integration, or continuous deployment service
The last option is going all out and setting up a server to run your tests, or paying for a service that provides a testing server (and more). These are brilliant for larger projects and bigger teams, but they come with a world of complexities around scripting how things are run and keeping things nice and secure. Continuous integration services test your code every time you commit something. Continuous deployment tests your code and deploys it if it passes all the tests. These are covered in the Continuous Development chapter.
One important thing to be consider is that you'll want to run your tests in different browsers. This means you'll need to access different operating systems (Windows, OSX, Android, etc). If you use a cloud based approach that's generally taken care of for you, but if you decide to run tests locally you may need to be clever. One annoyance about this is that there isn't an operating system that runs everything - Edge is only available on Windows and Safari is only available on OSX. This means you'll need to either run two test machines, one for each platform, or you'll need to dabble in virtualisation. We'll get to that later.
source control and tests