Check out a free preview of the full JavaScript Testing Practices and Principles course

The "Automated Testing" Lesson is part of the full, JavaScript Testing Practices and Principles course featured in this preview video. Here's what you'd learn in this lesson:

Kent introduces some common bugs, what is generally done about these bugs, and gives an introduction to tests, with examples on what static, unit, integration, and a look of E2E tests.


Transcript from the "Automated Testing" Lesson

>> Kent C. Dodds: Who knows what this is?
>> Kent C. Dodds: Yeah?
>> Speaker 2: It's the first actual case of a bug being found in a computer at a mainframe at a naval laboratory, I think.
>> Kent C. Dodds: Yeah, yeah. So this is Relay # 70, Panel F, a moth in relay. So this is not where the term bug came from.

That's a pretty common misconception. This is just the first actual case of a bug being found. So at least the first recorded case of a bug being found. And the term bug was used I think by Thomas Edison used it in a letter to somebody else, and even before that.

And but the term bug is used to describe a problem in a system. And we write a lot of systems now in code with software. And we find bugs in our systems all the time. It's one of the fun things about software is it's so fluid. And that fluidity is a great opportunity for bugs to sneak into things.

So we're finding bugs a lot more than they used to find moths in relays. But yeah, this is what a bug is and we don't want bugs in our software. So what kind of bugs are there? What kind of bugs do you find in software? I'll give you just one hint.

There are security bugs. What other kind of bugs can you find in software? What's the bug that you found yesterday cuz you find them all the time? What kind of bugs?
>> Speaker 2: Memory leaks.
>> Kent C. Dodds: Memory leaks, yes, great.
>> Speaker 2: Logic errors.
>> Kent C. Dodds: Logic, yep, logic bugs.
>> Speaker 2: Integration.

>> Kent C. Dodds: What? Integration bugs, yep. Yeah, you're talking to Twitter's API or something. There's a bug in that integration or even your own APIs. Any other kinds of bugs?
>> Speaker 2: Off by one.
>> Kent C. Dodds: Off by one errors, yeah.
>> Speaker 2: Race conditions.
>> Kent C. Dodds: Uh-huh, yeah, race conditions.
>> Speaker 2: No pointer exception.

>> Kent C. Dodds: No pointer exception. Man. I prefer undefined is not a function. [LAUGH] But yeah, so they're regression bugs that used to work, doesn't work anymore, business logic, accessibility. There are lots and lots of different kinds of bugs. And this isn't a comprehensive list or anything, but bugs can surface in all areas of our software.

So what do we do about these bugs? How do we prevent these bugs from happening? So there's sonic typing is a great way to do that. So how many people here are using a type checker in their JavaScript? Is it TypeScript, TypeScript? Flow, anybody using Flow? All right, yeah.

So I prefer Flow because I like Babel. I guess Babel you'd be able to do TypeScript sort of. But yeah, so I highly recommend that you leverage static typing in your Javascript. It will just take away a whole category of bugs that could appear in your software. It will also take you a lot longer to write JavaScript because it sometimes adding types to Javascript is really frustrating.

But in general, it makes your software better and so I definitely recommend static typing. This is also a form of static analysis. Linting, ESLint is a fantastic tool. If you're not using ESLint, I recommend you do. If you're using ESLint to check style, code style, please stop. We don't need that.

We have prettier formatted all. ESLint's job should be to catch common bugs that static type checkers can't catch. And lots of that involves domain specific things like in our code base, we can't do this because of this other thing or whatever. So you can write a custom ESLint rule for that.

So and ESLint also has a bunch of rules that are useful that static types don't generally catch, type checkers don't catch. So linting is another form of testing, and these two things are generally pretty easy to set up. And so I definitely recommend using these things. And we're not gonna be talking about or using these things directly at all today.

But I just mention them because it's really, really valuable. So then testing is the next thing, the next layer of defense. ESLint can't catch logic errors. Type checking can't catch logic errors, anything like that. And so there's still a big category of bugs that we need to catch with testing.

So what kinds of test are available to us, these automated tests? I'll give you a hint, there's unit tests, what other kinds?
>> Speaker 2: Integration test.
>> Kent C. Dodds: Integration tests, yep.
>> Speaker 2: And end tests.
>> Kent C. Dodds: And end tests, there's still more. What other-
>> Speaker 2: Acceptance tests.
>> Kent C. Dodds: Acceptance tests. I'm not sure what order they are anymore, so I'm gonna.

>> Speaker 2: Regression test.
>> Kent C. Dodds: Regression test, yep.
>> Kent C. Dodds: Any other forms of tests?
>> Speaker 2: Performance.
>> Kent C. Dodds: Yep, performance, yep.
>> Speaker 2: Stress test, load test.
>> Kent C. Dodds: Yep, yep, stress tests.
>> Kent C. Dodds: I think we covered every single formula, no, I'm just kidding. There are many more. So penetration tests is security, performance, regression, yeah, all three of the ones you mentioned.

Accessibility, that's a11y, accessibility. Very, very important, we should be testing that. Internationalization, how many times have you had a localization bug? All the time. I cannot ship internationalized software without having some bug within my internationalization. Most of the time it has to do with right to left conversion and things look funny.

Or yeah, or the text is way longer in language x than English or something. So yeah, there's some things you can do to automate that, and then a whole bunch of other things. We're not gonna cover all of these. It would take weeks to cover all of these with any amount of depth.

So yeah, we're gonna focus on just a couple of these. So this is an example of static code analysis. 'three' is not defined. ESLink can save us from that. And then Flow can tell us, hey, well, three is defined, but it's a string. It should be a number.

And so it can tell us that these types are incompatible with each other. Unit tests, this is a basic unit test. We've got a little function here and we call it and we did a value back. That's the simplest form of a code automated test that I can think of.

And we're gonna be seeing what that test function and what that expect function are supposed to do. We'll be writing it ourselves. But that's, yeah, that's basic unit test. Integration test are generally a little bit more complicated. You have to start up the server, and then you have to hit an endpoint or something like that.

Maybe you have to have a database up and running. And so often these integration tests can be more complicated. This is for bank and stuff. You could also have integration tests on the UI that is mocking out all server requests and stuff, but is integrating how your UI is interacting with itself.

And so yeah, there's more of a layer above unit test where it's testing several units together. The line between unit and integration test is a little bit fuzzy. But then we also have end-to-end tests. We're not gonna cover these today. But the general idea is you pull up the entire application and try to use it as close to as the user as possible.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now