Check out a free preview of the full Testing and Modular Front-End course

The "Tape Modules" Lesson is part of the full, Testing and Modular Front-End course featured in this preview video. Here's what you'd learn in this lesson:

For testing in node and in the browser, James introduces how to use the tape node module that is built on TAP.


Transcript from the "Tape Modules" Lesson

>> So we're gonna use some modules now to generate tap for us, we could do this our self with like console.log, but why write your own tap system when there's perfectly capable modules that can do it for us. So if you wanna write tests that are only gonna run in node js, you can use the module called tap.

If you wanna write tests that are gonna run in both node in the browser, then you can use tape which I wrote. But they implement pretty much the same API. So, if you decide to change your mind later about, like if you have a tap test suite and you want to run it in the browser, you can just swap out required tap that tests for required tape and it will all work.

So, I'm gonna make a directory. I'm gonna use tape for a couple of these and then I'll swap that out for tap and you can see kind of the difference. So, the first thing that we're gonna do is require tape like this. Some people like to call their test function tape but I like to call it test, up to you.

However you like to do it is fine. So how this works is you call the test function which is exported by this module. You can give your test a name if you like, this test has a name, and that'll appear in the output in the tap format. It's optional, though.

And then you can provide a function. This function is gonna receive this argument. I like to call it t, but you can call it whatever you like. Like test, for example. And that argument has an api that's quite similar to the assert api. So you can do things like t.equal.

You might also wanna call it assert cuz it's like the assert object. But the things that the tape and tap give you that are different or you get this thing called plan. So you can plan out a number of assertions. And see, so I can show you how that will fail if I don't have the correct number of assertions.

So here I have two tests, but I plan to have four tests. If I run my test suite now I see that it fails because the plan didn't match the number of tests. Another way to do it is to cal t.end instead of t.plan, this is kind of handy sometimes if all that you have is a list of assertions that you wanna run through and you don't have any call backs or anything like that, so you don't have to worry about branching.

So if I run the test suite now, it passes, if you try to do something after you've ended the test suite, it'll also fail. And then I can show you that even though the first assertion is gonna fail now it's gonna also run the second one which is useful in a lot of cases.

Right, so the first one fails. But unlike with the assert module that throws an exception and kind of like bails out of program execution. Our test suite is gonna keep running in here it ran the second assertion as well. So the other thing about tests with libraries like tap and tape, is that you can very easily support asynchronous operations, because we either have to plan out the number of assertions with t.plan, or we have to call t.end.

So, if I don't do that this test is going to fail because I never ended the test and I never planned out a number of assertions. There we go. So what this implicitly gives us is if I had a callback that never fired, like this never fires where I was gonna end the test or have more assertions or something.

And then I never call cb, then this test will fail. So, it's gonna deal with one of those cases that was a problem with the assert module. So that's what that looks like. It looks like the same as if we hadn't planned or ended any test. So a more practical example, you might have some asynchronous function, I'm just gonna use set timeout to make it real simple.

So we'll plan out a couple of things to do. And then 100 milliseconds later, we'll do the final assertion. Also with any of this assertions you can always provide a final description as a string, so true is okay, I don't know, something like that. This examples are all still a bit contrived but, there we go.

So, our first test still fails cuz I haven't updated it but the other two succeed. And the number of assertions is what we would expect it's 3. Another thing to mention about the tape and tap api is that you can specify as many of these tests as you like.

Including in other files, and they'll execute serially. This is because if you have too much parallelism in your tests, if you're dealing things that have to do with IO, it can be quite difficult to kind of reason your way through them. So, the trade off that tape and tap make in this case is that it's probably better most of the time to execute things serially.

That's not true of all test suites. I think some of them will run things in parallel. But that's just the behavior that you get from these libraries. I think that's better than having one monster library that you have to configure in the way that you like. And everyone does it differently.

So just pick the opinions that you like in terms of which libraries you use. I like this one. Okay, so if we have a second test, this is a second test. Then the assertions that we put in here. Are going to happen after this first test is complete.

So even though there's a set timeout here, the second test won't happen until after it's finished. Six, sure. Give you any idea what that looks like? There we go. So I fixed that first assertion, and we get a little successful tests. There we go. So the first three happened, even though one happens inside of a set timeout, then the second test happens.

And if the first test never finished, so suppose that we'd planned to four assertions but we only have three, then the test suite is going to run the three tests and then it's just going to sit there. In this particular case something a bit special is happening because node has a way of tracking the number of handles that are registered on the event loop.

And there's also a hook to the programs like this. Test suite can hook on to where the testing library is gonna know right before your test suite finishes. So it can say, well, I was waiting on that first test to finish but I guess now if we're exiting node then that never happened.

So I'm gonna print something about it right now. So that's how that works. Okay, so I'm gonna add, well, I'm gonna do one last thing. So if you wanna use tap instead, you can do var test = require('tap').test after you npm install it. So if I run it, it works pretty much just the same.

Tap will format things a little bit differently. It adds some things that you don't get with tape. Although it doesn't run in the browser. So, just two ways that you can do it.

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