Current section: Test Structure 6 exercises

Modular Tests and Global Helpers


00:00 So the first thing I would do is take our existing tests, creating a file called read.test.yes, and paste them there. Once I do, there's a bunch of errors going on, so let's address them one by one. First, we need to have our actual code available in these tests. To do that, let's go back to read.yes and export these functions publicly.

00:20 With this, we can now import them in the test file from the source module. Great, now the problem is with test and expect. Those don't really exist, but we don't wanna import them explicitly because we will be using them a lot in all of our tests. So how about we make them global?

00:39 Let's start by creating a file called setup.yes. And first, before we do anything else, let's approach this type first. So let's describe this global functions by writing declare, global, then var, expect, and var, test. Let's provide the type annotations for them.

00:59 So we know that expect accepts actual, which is a known, and returns an assertion object. And test accepts a title, which is a string, and a callback, which is a function. Now, assertion is missing, so let's describe it too. I'll create an interface for assertion

01:17 that has just one property called to be, which is expected, and it doesn't return anything. So with this types in place, we can see that our greet.test.yes module is fine. But if we try to run it, we'll still get an error, because test is not defined. Here's the thing.

01:35 What we did just now is told TypeScript how to treat this globals, but the actual runtime implementation is still missing. Node.js doesn't know how those functions work, because they're not defined. So how about we define them? I will go to the greet.yes and copy their functionality.

01:50 So there's expect function, and also the test function. To expose these functions globally, I will assign them on the global this object, using the key of this object as the function name. So global this.expect will be the global expect function,

02:09 and the same way global this.test will be the global test function. Because we described those global functions here, we can leverage the type inference in TypeScript and drop this explicit type annotations, because types will be inferred from our global definitions. And the same for the test function.

02:26 Now, if we run tests, we will see them both passing. So let's recap a little what we did here. We moved the test from our source code into a separate module called greetTest.yes. We exported the function that we test publicly,

02:45 so we can use them in tests. But functions like test and expect, we introduced on a global test. And test and expect, we introduced on a global level. First, by describing them on a type level and letting TypeScript know how to treat them, but then providing the actual implementation for these functions by assigning them on the global this object,

03:04 so Node.js would know how they behave on runtime. And with this, we use the import flag in Node.js and provided the setup.ts module before running tests. This means that this whole file will be imported before the greetTest.ts file is even run. provided the test to run, which printed us the test result just gracefully.