Hello, YouTube.
My name is Bruno
and today, I'm very happy
to welcome you to this React.js testing
series.
During this series,
you will learn all the
tools and techniques
you need in order to create
good unit and integration
tests for your react.js applications.
There are a few tools that we will use
across all the videos in this series.
They are "Jest" "react
testing library" and "typescript".
If you know me, you know
that I will also reserve
two or three videos
at the end of the series
for "Next.js" testing
where we are going to test,
getServerSideProps, getStaticProps
and connected Next.js to a database.
In the first videos,
I will take the assumption
that you are starting
your testing journey,
so you have never done
a test in your life.
Taking that into account,
I will take this video's opportunity
to answer the four or five questions
I received the most from people
in your position.
The first of those four or five questions
is regarding this testing list
that I have over here.
What's the difference
between end2end testing,
integration testing and unit testing?
And even when to use those?
So let's start by the top one
"end2end" testing, because
it's the easiest one to explain.
And at the same time,
the one that everybody agrees
on the explanation,
let's say that in your company,
you have a manual tester
with some list of tasks
that they need to do
before you deploy to production.
So they will click in the "Login" button.
They will put some password.
They will see the Login page working.
That task is with a check
so you can test the next task.
But it is a person doing that,
and that's slow.
So an end2end test
is just automating this type of job
with tools like selenium or Cypress.
Regarding integration testing
is when we test two or more units,
which leaves us with
the question of "Bruno,
so then what's a unit?" Well,
if you are coming from object
oriented programing,
usually a unit for you in
that world is a Class!
In the case of React.js components,
we can say it's a component,
but not everybody will agree
with that distinction.
So I usually like what Kent C Dodds
once said in his blog,
and you should follow his blog.
He said that he really doesn't care
about the distinctions of
what is an integration test
or an end to end test?
What he cares is the value
that it's providing to the business,
that you can catch bugs.
And at the same time,
every time that you are doing
a breaking change, your test will fail,
because that's what
the tests are there
for, to catch the bugs
that we create in our code
and also allows us to do
refactoring of our code.
That's what Kent C Dodds wants!
That's also what I usually like to have.
But I will give you a real world example,
completely unrelated with code,
just to show you that different teams
can have completely different abstraction
levels and call something a unit test
and another team and test
and both be right.
Let's say that now
you are working for a car company
and you are in the assembly line
receiving the engine from another team
and fitting the engine into the car,
receiving the seats
from another team
and putting the seats in the car.
You receive the steering wheel
and your team sees every single
of those pieces/parts as a unit.
So after a while, you start to notice
that the engines
that you put in, the cars,
sometimes they don't work.
So you come up with the idea
of creating a unit test
to turn on the engine
and turn off the engine
before you assembled
the engine in the car.
You go to your CFO and you say, look,
we are saving like four hours
because every time that now
the engine is broken,
we don't need to remove the broken engine
and put a new good engine inside the car
that can also be broken that engine.
So with these alone,
we save, let's say, four hours
every time that happens.
Your CFO loves that idea
and tells you to go to
the engine department
and explain what you did.
You arrive at the engine department
and you say, hey, look,
I did an amazing unit test
for your engine.
I'm turning on and off the engine.
And everybody in the team
will hate you at that second
because they will ask you,
hey, do you even know
how an engine works?
It's not a unit test.
What you are doing is an end to end test.
And they will tell you, look,
we in order for an engine to work,
we need to have the pistons
that go inside the cylinders.
That alone is already
an integration test.
And then you have a thousand more pieces
in order for the engine
to turn on and off.
So what you are doing
is an end to end test.
And now you might ask me: "Bruno,
So which of those two teams is correct?"
Well, in reality, they are both correct.
They are just working
in completely different
levels of abstraction.
That's why I love that from Kent
that you just stop referring
what is the test type/name!!!
Because if you go to the engine
department and you say,
oh, I created a new test
and that test is to turn on
and off the engine
and put the engine in the car,
everybody across your company
will agree with that test.
I usually never name the type of tests.
I just care about
the value and the safety
that the test is giving me.
Like Kent C Dodds says, the confidence
the test gives you.
Now, another question that I receive
a lot is regarding what is mocking?
"I read mocking everywhere Bruno!".
Why is that even useful?
Let me give you the same example
with the car company.
Let's say that in order
for you to turn on and off the engine,
you need some kind of power
which will come from the battery.
But usually you can't fit the battery
in the cars immediately,
because if the car is in storage
for, let's say, one year, that
but battery will no longer work.
So usually what factories do is
they test it with
something that they connect directly
to a power wallet.
So that test that they are doing
doesn't rely on the battery
because the battery
can even be already dead at that moment.
So you are really just
testing your engine.
And that's what mocking means.
You remove one part of your code
and you replace that by
something that is safer
and at the same time is more reliable .
It's much more reliable for you
to connect your engine to a power outlet
than connecting it to a battery
that has different levels of quality.
Right?
So you just want to test the the engine.
You don't care about the battery
in this test.
You mock the battery by something else.
Then the third and the fourth question
are actually kind of the same thing,
which is when should you test something?
And why should you test that something?
And usually you will see people
coming up with a priority chart,
with a risk in that chart
and everything that is high
risk and high probability,
you should create tests for it.
There is no way around that.
If you are lucky enough
that your company allows you to have
100 percent code coverage
and allows you to have everything,
then you can ignore this section,
because this section is not for you.
But some companies, especially startups,
you don't have the time to test
every single component that you produce.
So usually what I will tell
you is ask yourself if this bug happens,
is this very dramatic for my company?
Can it put my company at risk?
If yes, test it.
If it's something that you say no.
If it happens, nobody really cares.
Don't test it.
I will give you an example.
Let's say that you are in Amazon,
and let's say that Amazon,
for whatever reason, allowed you
to change your profile picture.
Is that an important feature
if it stops working?
No, actually, today, Amazon,
I don't think they
even have a profile picture.
So if it fails, it's not a huge deal.
But if the credit card is not working
and that flow is not working
is very dramatic for Amazon
because it's where they make revenue.
So you should 100 percent test
that with both integration
and even end 2 end tests
for that scenario. Right???
So usually I always ask
this question, is this
something that will happen
quite a lot of times
and is annoying enough to damage
the reputation of my company.
If yes, I create a test!!!
Is this something that
even if it only has a one
in a million chances of happening,
it can destroy my company immediately?
If yes, I will do that test.
Everything that is in this
corner over here, not probable
and not too dramatic, If it happens,
I usually will say
you are quite OK to not test it.
Of course,
if you have the time, test everything
in your application,
that will be the ideal scenario.
One very common question I hear
is regarding this pyramid of testing.
And if you went to university,
your teachers were all the time
bombarding you with this one,
telling you that you should do
a lot of unit testing,
a bit less integration
and even less end 2 end testing.
And why is that?
Well, if you take, again,
the example of the car and the battery,
you know that if you have a lot of pieces
working together in your end 2 end tests,
it will be harder to not have
some variability there.
So your tests may become a bit flaky
when a third party API doesn't respond
or something like that.
That's why usually people
start to mock a lot of stuff going down
to the unit testing level.
Now, a lot of people, myself
included, I don't like that.
I prefer something more like that.
And I will give you some people online
that you probably know that agree with me
or some of them looking
at the date of the tweet
probably I agree with them
because they said it before me.
So Guilherme Roche, the CEO of Vercel
creators of Next.js, said
the following: "Do tests,
not too many mostly integration"....
And immediately after,
one of the creators of CSS
module said, "I'm
assuming anyone who disagrees with this
hasn't attempted a significant refactor
in in a code base
with too many unit tests".
In less than a minute,
I will give you one example
that happened to me,
and you will understand this much better.
But I will just read something from Dan
Abramov of the creator
or one of the creators of Redux,
and he's currently working for Facebook
in the React Core team.
And he said the following
"A suite of integration tests
written at the right
level of abstraction is chefs-kiss.
You need to find the level
that's just below
where the flakiness occurs".
So I already explained what flakiness is.
Then it's much more useful
than individual unit tests.
You have someone else, Kent C Dodds
once again saying the following.
If you have to delete your tests
after refactoring,
then what good did they do to you?
This is what tests should be like.
Now I think I am in the right mood
to explain what happened to me
in that situation.
I was building an application
with one of my best friends.
And the way we were testing our HTTP
calls was to mock Axios.
And we were doing that,
jest.mock('axios') -
I will show you in a few videos
how you do that. So don't worry too much.
But we were mocking Axios
and when we decided to move to fetch
all our unit tests
they were completely broken, because
now all our tests were expecting
Axios to have been called
and Axios was not being called
when we moved to fetch
because we were testing
an implementation detail.
In video I think
six or seven of the series,
I will explain how you can test
without having to mock Axios or fetch.
So in the future,
if there is a new browser
feature to replace fetch,
you can just use that browser feature
and your test will help you
in that refactoring.
That's what they meant, is
your tests should help you
with your refactoring.
If your users are still
seeing roughly the same thing
or exactly the same thing, in this case,
your test shouldn't break.
It's very frustrating
when you go to an application.
You change something.
The behavior for the user
is exactly the same.
And then you have 10 tests
that are failing right now
because they are mocking
something or expecting something,
which is an implementation detail.
So usually what I say,
and this is probably the best advice
of all the series, is
when you are testing, test
the public interfaces or the public
API of your components.
If your components receive four or five
props, pass those four
or five props and just test
what HTML your component is returning.
Don't test or at least avoid testing
internal components
and mocking those internal components,
because otherwise,
when you want to refactor,
it will become a very big pain for you!!!
In the second video I will show you
how you can configure your application
in order to have testing with ts-jest,
TypeScript, Next.js,
react testing library, React.js
and all the good things
that you might want
for all the videos that we will use.
So that will be the base
of all the videos.
And that video is over.
Here is number two.
If you already know how to do that
and you prefer to go to
video number three, it will be here
and over here at the top,
It will be the full playlist.
So if you click there, you'll see
all the videos that exist in the playlist
and just watch the ones
that you care about.
So I really hope you enjoyed this one.
I hope you also enjoyed the next ones.
And I see you very, very soon.
Bye bye.