Diffrent types of testing
End-to-end tests
End-to-end tests are the most intuitive type of test to understand. In frontend applications, end-to-end tests automate a browser to check that an application works correctly from the user’s perspective.
Example
Imagine you’re writing a calculator app and you want to test that it sums two numbers correctly.
You could write an end-to-end test that opens a browser, loads the calculator app, clicks the 1 button, clicks the plus (+) button, clicks the 1 button again, clicks equals (=), and checks that the screen displays the correct result (2).
You can see an example of what that might look like as code in the next listing.
function testCalculator(browser) {
browser
.url('http://localhost:8080')
.click('#button-1')
.click('#button-plus')
.click('#button-1')
.click('#button-equal')
.assert.containsText("#result", "2")
.end();
}
End-to-end tests are powerful time-savers. After you’ve written an end-to-end test, you can run it as often as you want. Imagine how much time a suite of hundreds of these tests could save!
At first, end-to-end tests seem like the only testing tool you need. But they have a few problems. First, end-to-end tests are slow. Launching a browser can take several seconds, and websites can be slow to respond. It’s common for a suite of end-to-end tests to take 30 minutes to run, and if you relied purely on end-to-end tests, your test suite would take hours to run.
Another problem with end-to-end tests is that debugging them can be difficult. To debug an end-to-end test, you need to open a browser and step through the user journey to reproduce the bug yourself. This is bad enough when you’re running end-to-end tests locally, but if your tests fail on your CI server and not on your local machine, you’re going to have a bad time.
Unit testing
Unit testing is the process of running tests against the smallest parts of an application (units). Normally the units you test are functions, but in Vue apps, components are also units to test (more on those later).
Remember the calculator application? In the code, the application uses a sum function to calculate the sum of two numbers.
If you edited the function to make it easier to read, you would want to test that the function still works correctly. You could run an end-to-end test, but if the end-to-end test failed, you wouldn’t know whether the problem was with the sum function or with a different part of the source code. The only way you could know for sure that it was the sum function that was broken would be to run the function in isolation. You can do this with unit tests.
Unit tests are functions that call functions in your source code in isolation and assert that they behave correctly. Take a look at the next listing. It’s a simple program that imports a sum function, runs it, and throws an error if sum does not return 2.
// sum.js
export default function sum(a, b) {
return a + b
}
// sum.spec.js
import sum from '../sum'
function testSum() {
if (sum(1,1) !== 2) {
throw new Error('sum(1,1) did not return 2')
}
}
testSum()
Because unit tests run against an isolated unit, when a well-written unit test fails, it acts as a flashing neon sign pointing you toward the problem code.
Unlike end-to-end tests, unit tests are fast. They run in a few seconds, so you can run unit tests each time you make a code change to get quick feedback on whether the change broke existing functionality.
A happy side effect of unit tests is that they provide documentation. If a new developer starts on a project and needs to know how a unit of code behaves, they can look at the tests to see exactly how a unit behaves.
Snapshot testing
Have you played Spot the Difference? Spot the Difference is a game where you have two pictures of the same thing with small differences between them. The aim of the game is to identify the differences.
Snapshot tests are similar to Spot the Difference. A snapshot test takes "a picture" of your running application and compares it against previously saved pictures. If the pictures are different, the test fails. This test method is a useful way to make sure an application continues to render correctly after code changes.
Traditional snapshot tests launch an application in a browser and take a screenshot of the rendered page. They compare the newly taken screenshot to a saved screenshot and display an error if differences exist. These types of snapshot tests have problems when differences between operating systems or browser versions cause tests to fail even though the snapshot hasn’t changed.
However usually we dont compare screenshots of the app, but rather compare the code structure of the output of the component with a previous version we had stored. It won’t actually render and take a picture of the component, but it would save its internal data.