In this lecture.
Let's talk about testing and why it's important.
Testing can make or break your development career.
There are a lot of successful developers who can create applications without ever writing a single test.
Unfortunately, not being able to write tests can stagnate your skills as a developer.
Writing tests can improve your ability to write code.
Recruiters are likely to hire developers who have experience with testing.
Beginner developers may be tempted to skip testing.
After all, it can seem trivial.
In the past, this statement was true.
Where do you start?
What tests should you write?
What do you use for testing?
Over the years, the frontend testing community has blossomed with tools and guides.
In this section of the course, I want to guide you through the process of testing your code.
We'll create a suite of automated tests to verify that our angular application is functioning as expected.
Your goal as a developer is to ship a bug free application.
Applications with bugs lead to a bad user experience.
A bad user experience leads to users leaving your app.
Testing can prevent this scenario from happening.
Let's take a step back for a moment.
What is testing?
Testing is the process of checking that an application is functioning as expected.
For example, if a user clicks the login button, the authentication component should open on the page.
The interactions users have with our application will change its behavior.
Testing will help us verify that the correct behavior always occurs.
There are different techniques for testing an application.
Primarily, they will fall into two categories manual testing and automated testing.
From the beginning of the course, we've been manually testing the application.
After writing code, we proceeded to test if it worked in the browser.
Sometimes we even checked other parts of the app to make sure they worked.
We would never write code and then claim it worked.
We always tested new features manually.
Testing an app is perfect for small applications.
If it takes less than 3 minutes to test, you don't need to write tests.
However, as your app scales, you may find the process cumbersome.
Manual testing isn't efficient.
We're human.
We can easily become bored if we have to perform the same tasks repetitively as humans.
When we're bored, we tend to lose focus that can lead to bugs bleeding through into production.
Manual testing doesn't scale.
This is where automated testing saves the day.
Automated testing is when a program performs tests on your application.
It's completely automated.
It'll go through a list of tasks to execute.
You can test functions, components, events and screenshots.
If all tests pass, you can go ahead with pushing the app into production.
Otherwise, it'll tell you where things went wrong, thus saving you the time of having to find where
the bug is present.
Best of all, machines can perform tests much faster than humans can.
The advantages are clear.
Automated tests are the way to go.
In this section, we're going to focus solely on automated testing.
Testing is a very broad term for what the testing world has to offer.
If you do your own research, you'll come across dozens of definitions and tutorials for different types
of testing.
You may also come across libraries that perform tests differently.
To make things easier, we can generally categorize tests into three groups unit tests, snapshot tests,
and end to end tests.
Let's discuss each of them.
The first type of test you'll become familiar with are end to end tests and end to end.
Test is performed by a program within the browser.
This program will load the app in the browser, navigate the app and fill in fields.
Tests are completely visualised.
The purpose is to make sure things look like they're working from the user's perspective.
At first glance, it may seem like end to end testing is the only type of test you will ever need to
write.
Unfortunately, that's not the case.
End to end testing can cause a lot of issues trying to automate user behavior in a browser.
It can be time consuming.
Tests can take up to an hour if you write a lot of them.
On top of that, if a test does fail, you may not know the reason why.
You may know which test failed, but you don't know why it failed.
You will have to retrace the steps of the test to understand why it failed.
Sometimes it may not even be because of the code you've written.
Your app could be working fine, but one of the APIs you're using could be down during a test.
This downtime can cause a test to fail.
One day a test will work and the next day it may not.
Generally end to end tests are not the most reliable way to test an application.
Most developers don't rely on this type of testing for their applications.
This leads us to the next type of testing unit testing, instead of testing an entire page in the browser.
You can run tests against small sections in your application, hence the word unit.
Unit tests are reliable because they're fast and can tell you where a problem is.
Unit tests can be defined for classes, components, services and pipes.
Unit tests are much smaller.
Basically, a unit test is a way to check bits and pieces of your code in isolation.
The main advantage of writing unit tests is that they're fast.
After making changes to your source code.
You can immediately run a test to get feedback on your changes.
Another benefit is helping developers better understand the code base.
Let's say you're hired to work on an existing project.
The first thing you want to do is to become familiar with the existing code base.
A great way to learn about a project is by viewing the tests.
Tests are meant to be descriptive and provide documentation.
This is because the test checks the behavior of a class in a way that can help you figure out what a
class is supposed to do.
You can study a test to quickly learn what components do in the application.
It'll help you get up to speed with things.
Overall, unit testing is usually the type of testing most developers like to use.
On the other hand, unit testing isn't perfect.
There are two major issues you'll face with them.
Firstly, code refactoring can become a nightmare if you want to restructure your application.
You will also need to update your tests.
Even something as simple as outsourcing logic into a service can be time consuming.
Unfortunately, there isn't a way around this besides better planning and structuring your code.
The second issue is testing small pieces of an application.
It's like testing out the parts of a machine.
The parts of a machine can work.
But what if they can't work together?
This can render our tests useless.
There is a way to get around this, but I'll explain in a moment.
Let's talk about the last type of testing called snapshot testing.
You're probably familiar with the game spot.
The difference, it's a game where you're presented with two nearly identical images.
The objective is to spot the differences.
That's what snapshot testing is.
It's a program that will take two snapshots of your application and compare them if it spots any differences.
It'll consider the test a failure snapshot.
Testing, similar to the other types of tests comes with a set of challenges.
The biggest challenge is being able to test on different browsers and operating systems.
The smallest differences can cause a test to fail.
There are ways around this which I'll discuss later in the section.
We've identified the most common types of tests you'll encounter.
The question is which do you use?
The answer is all of them.
If you were to search for the phrase pyramid of tests, you'll come across an image similar to what
I'm showing you.
Tests are not a concept exclusive to Angular or the front end.
It's a concept that's used across all software, languages and platforms.
The main consensus is the following A majority of your tests should be unit tests.
About 60% is the recommended proportion for unit tests, 30% for snapshot tests, and lastly, 10% for
end to end tests.
Unit tests make up the majority because they're quick and straightforward.
In contrast, end to end tests are slow and sometimes unreliable.
Keep in mind that this is merely your recommendation.
You may not always have a suite of tests that fit this proportion.
There's one important question I want to answer before we move on.
When should we test an application?
The goal of testing your application is to make development faster.
Bugs can impact how long it may take to build an app.
If you carelessly write tests, you may end up crippling yourself by spending too much time on tests
that aren't completely necessary.
You don't have to test every single line of code with experience.
You'll understand what you should and shouldn't test.
There is one general rule of thumb I recommend for determining when you should write a test.
The rule is if it doesn't save you time, don't bother writing it.
At the very beginning of this video.
I talked about how manual testing can take a while to execute.
The larger your app is, the longer it'll take to test.
The purpose of writing tests is to automate the process and help you catch errors in your application.
If a test doesn't help you reduce your testing process, it likely isn't worth writing.
There's one last.
Question I often hear, which is What do we test?
I talked about how the purpose of unit testing is to test bits and pieces of code.
And you also mentioned how tests shouldn't focus on single lines of code.
The question then becomes, what should we be testing?
The best place to start is with components.
Specifically, you should test the output of a component.
If you think about it, that's generally what most of the code we write does.
Every class or component will have an input and output.
We're going to be writing tests where we'll pass in data to a component.
The test will check the output of the component.
If it outputs the desired results, it'll pass the test.
The idea of input and output is an important concept to understand for tests.
Testing is about input and output.
In a test, you supply an input, receive an output and assert that the output is correct.
You should write tests from the perspective of a developer who's using the component but is unaware
of how the component functionality is implemented.
That was a bit of an introduction.
This lecture was a general overview of things from here on out.
We'll start writing tests when you're ready.
I'll see you in the next lecture.