(train whistle)
- Hello, welcome to a special Coding Train episode.
This episode is the first in a series
of some number of videos that I don't know
right now because I haven't made them yet,
all about unit testing and continuous integration.
This really fits into my playlists
and topics about open-source development.
So, if you've never used Git or GitHub before you're here,
I might suggest going and watching
my Direction to GitHub videos.
If you've never used Node,
you might even watch my What is Node video.
I'll link to both of those in the description.
But other than that, this is for the total beginner
who has never done any unit testing
or continuous integration.
You know why I know that this video is for that person?
(dinging)
I am that person! (laughs)
Before last week, I barely, I mean,
I've done a little bit of unit testing,
and I've dabbled, I've read, I've seen other people do it.
Mostly I'm afraid of it, I think oh,
they're just going to make it so I can
never get anything done anymore.
And people say, "No, it's going to make it
so you can get everything done anymore."
So, I'm here to investigate that.
I should have mentioned this at the outright.
This video series is sponsored by CircleCI,
which is a company that provides
as a service, continuous integration.
Now, what that is, I will get to eventually.
Unfortunately, you're going to have to watch
me continuing to talk to get to that.
So, let's start.
I'm going to come over to the whiteboard
for really no reason other than to write
the word here, unit testing.
So, continuous integration can be used
for a variety of different things,
but probably one of the more common things it's used for,
from what I understand is TDD,
or test driven development.
So, let's think about this.
I was saying, another video series you could watch
which is very useful about unit testing
and with CircleCI is from MPJ, Fun Fun Function.
I will link to those videos in the description as well.
And MPJ says that you can think of software,
a software project, a P5 sketch,
you can think of my snakes and ladders game
from last week as a big project
divided into lots of little parts.
There's the player part, there's the snake part,
the ladder part, all of these are units.
What if I change something about the player
to fix a bug, but don't realize
it's also going to break whatever
the ladder functionality or the snake functionality is?
In this case, if I have tests that run
for each unit to say, this little test code runs
and says the ladder is working,
this little test code runs
and says the snake is working,
this little test code runs
and says the player is working.
If I change just one, I can run
all the tests and know that my code is fine.
The benefit of this is not just for
your own personal sanity, but for collaboration
and open source projects because this can be automated.
You can have, whenever somebody submits
a pull request to your project, that tests are run.
And it doesn't just give you confidence
about merging, it gives the contributor
a good feeling and confidence that the tests have run,
and if they haven't run, then you can
help them figure out how to fix it
so that they do run, so all of this is good,
good, good, good, good.
I'm going to learn how to do it and try
to adopt it more in my own work.
Where have I encountered this before?
The place I have encountered this before
is with the open source project P5.js.
P5.js, you might be aware of, is a library,
is a JavaScript library that I use
for a lot of my tutorials, learning about
the basics of coding and graphics
and creative coding and data stuff
and all this sort of stuff.
All of the source code for P5.js as a project is here.
You may have encountered P5.js
as just this file, and here I have
my snakes and ladders game in which
you can see like, that's the P5.js library.
If I click on it, it's like oh my god,
this is all the P5.js code,
but if you're working on developing the library,
scroll, scroll, scroll, scroll.
If you're working on developing the library,
it's likely that you don't want to work
with that file, so it's divided into
lots of little units and those units
you can find in the GitHub repository,
in this folder called source.
In source you can see there's all the code
for all the color stuff, core stuff
is like the core drawing functionality,
data, events, and then there's a build process.
Once you finish doing your little change
or whatever, then the build process runs
and finishes off with this smooshed together
P5.js file that is all of the bits,
all of the units together in one file
so it can be used more easily.
During that build process, tests run.
These are the source folders.
For example, I'm going to go here,
one of the aspects that I worked on
a while ago was the random functionality.
There's a file called random.js,
and if I click on that, we can kind of
look down and see like oh, look,
this is the actual random number generator code
that's inside the P5.js library.
This is what actually runs and it's kind of
really interesting, I should do a video
about this linear congruental generator stuff
and how random seeding works, but that's another topic.
So we can see this is the code.
Now, where was that?
We have to remember that was in
P5.js source math random.
Now let's take a look and say,
hmm, there is also test.
There's a folder called test,
folder called source, folder called test.
I'm going to go into test and look at this.
Then I'm going to go into unit. (laughs)
All of a sudden look at this.
Don't these directories look very familiar to you?
For every single unit, piece of a puzzle
of the P5.js library, there is a corresponding test.
Let's go right into math and let's go right into random.
This is not the source code for the library, remember.
You could cut back and forth between the video
and it'll look the same, but if I go here,
you're going to see ah, this is a test.
You might be wondering like ooh, what does suite mean
and what is test, and assert, and type of?
What is all of this code?
This is where you most likely want to
involve yourself with, that's a weird way
to say it, but might want to select and use
a testing framework or a testing library.
If I'm right about this, P5 uses
a testing framework called Mocha,
which is a very popular one.
I'm going to, as I get a little further
into this tutorial, use something called Jest,
and I'll talk about the differences
or what that is and I'll get to that in a little bit,
but even without knowing anything about it,
we can see some code here because look at this.
This is how we test the function random.
The first thing we do is we set the random seed
and then we pick five random numbers.
Then we set the random seed again
and pick five more random numbers.
What should that do that makes it correct?
If we set a random seed, if you get
the same sequence of random numbers.
First of all though, before we even do that,
does random even produce a number?
We should check to make sure all 10
of those things are numbers and that's what
this assert type of blah blah blah is a number is checking.
Then we should check to make sure,
well random is supposed to give us a number
between zero and one, so we should check
to make sure all of those numbers are between that range.
Then we should test to make sure random seed worked.
Is it the same sequence of random numbers?
A way you can also test is when you
pass in the argument five, if you get
a number between zero and five.
When you pass in the arguments one and 10,
do you get a random number between one and ten?
This is what testing is, that way
if I'm contributing to P5 and I change something
somewhere else, what if I don't realize
that something I'm doing somewhere else
in the library actually breaks the way
random works, this will tell me that.
This is why unit testing can be valuable
in a large or even a small software project
that is a collaborative project,
or even one that you're just doing it
to test yourself as you go.
Okay, so that's the basic idea of testing.
Now let's think about what are all the pieces you need?
Number one is, there's so many possibilities.
We can do testing in Python or
whatever language you're doing, there's so many.
I'm going to zero down and live in the JavaScript world.
You could be doing a server side web app,
just like the client side JavaScript thing,
some open source library that's meant
to be used, there's so many complicated scenarios,
but let's pick a simple one.
I just have a single JavaScript file
called sketch.js and this is my
P5 creative assignment, blah blah blah.
What I want to do is I want to run a test
on the code that's in that file.
I need some mechanism to do that.
The tools that I'm going to use to do that,
so this is just for the testing,
is I'm going to use Node, and I'm not using Node.js
because I'm creating a web server,
although I might be doing that
at some point in another project.
I'm using Node just essentially as like
a command line utility to run the test
because there are Node packages,
collections of code and libraries
to allow you to do testing through Node
and the one that I want to use is something called Jest.
I'll be perfectly honest, the reason why
I'm using Jest is because I asked
a whole bunch of people who seemed
to know about this stuff what should
I use and they said Jest.
I believe P5 uses Mocha, type in the comments
your favorite testing framework, go nuts,
but Jest is an open source project
from Facebook, open source that I believe
is generally paired with React.
Again, I'm not doing React, I know less
about React than I know about continuous integration
but I'm going to use Jest because
it's pretty simple and I liked it,
I looked at it, it's fine.
That's what I need, so what I'm going to need to do
is somehow configure my Node project
so that I can write NPM test.
I want to run this command,
it's going to do a whole bunch of stuff,
and it's either going to say something like
success or failure and hopefully
if it's failure it's going to give me a report.
This is the idea of testing.
While I'm here in the kind of overall landscape of this,
let me make a little map here.
I've got to erase this.
Let's think about where everything lives,
because how does GitHub play a role in this
and how does CircleCI or
continuous integration play a role in this?
Number one, I have on my laptop,
which is my local client computer
where I'm doing the development, I have sketch.js.
I also have my whole Node project,
which is really just by the way
a package.json file and some other stuff.
What I could do is I could
push this repository, I'll use the idea
of a cloud even though it's really just
an underground bunker of course as we know.
I could push this repository to GitHub,
so I can have it saved on GitHub
and the nice thing about that is
lots of other people could start to
pull it and then make changes or
propose changes through pull requests.
Where do I run the tests?
On the one hand, these are lots of
other little client computers.
On one hand, I could change my code
and run my test locally and I know ah,
my tests run, great, I'm going to push to GitHub.
Other people could clone the repository,
make changes, run the tests themselves,
and feel confident and push to the repository,
but wouldn't it be nice if GitHub
could run the tests for me?
Any time that I try to push code there,
it's going to say let me test that first,
I'll tell you if it's okay.
It can't, GitHub does not have that a service.
You can't execute code on GitHub.
You can host your projects there,
you can even web host client side
JavaScript programs there, but you need something else.
You need a continuous integration service
and that is where something like CircleCI comes in.
I don't know what I'm drawing here,
but CircleCI is another thing
that lives in the cloud shaped underground bunker
and what CircleCI does is it can be a service,
it can be linked as a service to
your particular GitHub account.
You sign up for a CircleCI account
in the same way you sign up for a GitHub account.
CircleCI has a good, free tier
which you could do just about everything
that I'll show you in this video
for small projects and small teams,
you can absolutely use it.
So what you can do is you can say hey,
any time I push or any time I commit
or do a pull request, please go
and run, open a little instance of a server
on CircleCI to run a bunch of Node stuff
to check the test and report back.
This is the process, and so what
I'm going to show you in the next video,
I'm going to actually just make an entirely
simple, basic example of one little JavaScript program
with one test and continuous integration,
I'm going to make it so that if you, the viewer
watching right now, you can submit
a pull request, but I as the administrator
of the repository will not be allowed to merge it
unless the tests that I have written for the project pass.
That's the basic gist of it.
I'm sure there are going to be some questions
and things and I will return in a moment
in the next video to start writing
what I need in package.json,
what I need in sketch.js,
what did I need in a test file
and all the other things that
I'm forgetting to mention right now.
(upbeat music)