If you are in a hurry you can fork/download this repo which has example tests and the relevant packages already set up: https://github.com/coopdigital/quickstartjest
This should get you to the point of writing a first test. It assumes OS X with homebrew installed. (see https://brew.sh/)
On Linux you should be able to substitute apt-get, yum etc when brew is mentioned. It might help to have node and npm already installed but we will be wrapping tooling around these.
This is geared towards Node but it should be the same for front-end code with test AFAIK (feel free to correct me).
Ive used
<details> I'm rambling here... </details>
to mark stuff you can jump over if you just want to get started quickly to do a kata. This is typically stuff that you need to consider for working code. Or me rambling. Who knows?
- yarn or npm Either will work, npm has caught up with the things yarn supplied, so its probably a better default option.
- nvm We are going to use this to make sure we can run a consistent node version.
- jest We will use this as our test library.
brew update
(brew install yarn)
Note. It is not recommended to install nvm using brew. Use.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
(see https://github.com/nvm-sh/nvm#installing-and-updating)
N.B. I don't normally recommend doing this to install things since you are blindly trusting the contents of a remote script, and it could do anything. It is better practice to download the script first and inspect its contents, before running it. This assumes you can understand what it does. In this case I've looked over the script linked to make sure it is safe.
Make sure you have the latest (lts - long term support) version of node installed.
nvm install --lts
There are lots of versions you can install use nvm ls-remote --lts
to show them (omit the --lts to see all versions, not just the long term support ones. nvm ls
will show which versions
are installed locally.
In a terminal create a directory for the project with two folders inside src
& __tests__
. We will put our code in one, our tests in the other. Then cd into it. (substitute the project name for [YOURPROJECT])
mkdir -p [YOURPROJECT]/src
Hint you can type the first couple of letters and hit the tab key to autofill the name now
mkdir -p [YOURPROJECT]/__tests__
cd [YOURPROJECT]
Make sure you are using the correct node version. You will need to do this every time you start working on the project (in a new terminal window).
nvm use node
or
nvm use [VERSION]
to specify a version. (For versions up to 12 there was an alias 'stable' but this is now deprecated and points to 'node').
Now we are going to initialize the project. You only need to do this once. You will need to answer some questions. Once you are done you should see a package.json
file in the directory.
npm/yarn init
Now we can add jest
as our first dependency. We are going to make it a development dependency.
npm install --save-dev jest
or
yarn add --dev jest
Now you have done this you can run:
jest --init
to set up jest.
If you encounter probelms you might need to reference the jest binary by its path like so (from the root directory):
node_modules/.bin/jest --init
<details>
I recommend doing the same with jshint
. To run in point it at a directory jshint src
.
If you use it you should stick
/*jshint esversion: 8 */
at the top of your files (assuming you are using the latest node version) so it doesn't complain if you use new features.
*Also I picked jshint after 10 minutes of searching for 'javascript syntax checker', opening too many tabs and making it sure it worked with vim syntastic. There might be better options for you. Eslint is very popular. *
</details>
Now open up package.json
in your preferred editor and add the following in the lsit (don't forget the comma.
"scripts": {
"test": "jest"
},
<details>
It's also useful for actual projects to run node --version
and yarn --version
and add them in an engine section like this. Note >=
is specifying a minimum version.
"engines": {
"node": ">= 12.0.1",
"yarn": ">= 1.19.1"
},
</details>
<details> If this is a project that's intended to end up as working software take some time to think about how you are going to structure it and where you will put things. You don't have to get everyting nailed down, but its harder to change things later. Look for best practices and existing guidelines. If you are working in a team at the very least you should talk to your team mates and get a common agreement so you are all on the same page, even if you just invent a convention. That's totally ok. Your future selves will thank you for this. </details>
You should know that Node looks for a file called index.js
as a default in side a directory. This means that you can refer to ./mymodule/index.js
as just ./mymodule
For the purposes of this cheat sheet, to keep things simple, we are going to refer/put code in a single index.js
file in a single directory called thing
. In real life this is a terrible idea. Don't do this.
<rambling> I get kind of annoyed when people do this in tutorials etc and don't call it out, and then you struggle when trying to actually implement it. </rambling>
By default Jest considers anything under __tests___
or files named this this mything.tests.js
as tests. I go for the belt and braces approach and do both.
<details>
You can replicate your carefully thought out directory structure under __tests__
. You can refer to this by including the whole directory path. I like to use e.g. ___tests__/path/to/module.tests.js
for testing src/path/to/module
. You can always add the last directory later to split things up.
Jest really doesn't like it if a file its thinks is a test file doesn't contain at leat one test. This can be annoying if you want to include shared code that belongs with tests but isn't tests. You can configure Jest to ignore these in package.json
"jest": {
"testPathIgnorePatterns": [
"/node_modules/",
"__tests__/constants/*",
"__tests__/mocks/*"
]
}
"/node_modules/"
is the default if its not configured.
</details>
Add a blank file in your directory (under src)
touch src/thing/index.js
Now create a file for your tests:
touch __tests__/thing.tests.js
Open up that file in your editor and add the following at the top:
const thing = require('../src/thing')
Note This needs to be an actual path. As we have used index.js
we don't need to use the file name. If we have other files we can refer to them by using const otherThing = require('../src/thing/otherthing')
you don't need to use the file extension as long as its sensible e.g. js
and some other things you will have to look up.
Now add the first test. Jest tests look like this:
test('A descriptive string that describes your test`, {} => {
expect(func(arg)).toBe(expectedResult);
});
Note it goes expect().toEqual()
its easy to misplace a bracket. toBe
is like === i.e. it tests identity. toEqual
is more like == but it can do things js can't, like compare arrays. There are others the docs are here: https://jestjs.io/en/ specifically: https://jestjs.io/docs/en/using-matchers and https://jestjs.io/docs/en/expect
Here's a sample first test:
test('True is truthy', () => {
expect(thing.isTruthy(true)).toBeTruthy();
});
Now run:
yarn test
or
npm test
You should see it fail because thing.isTrue
doesn't exist. Don't skip over this part and start with the function straight away. Its important to make sure you haven't messed up the test. Which I never do, ever.
Next we can create that function in thing.index.js
function isTruthy() {
return false
}
<details>
Javascript functions will take as many arguments as you give them, just ignoring any not listed. ¯\_(ツ)_/¯
that's why I haven't defined an arg you can do that on the next iteration.
<\details>
We will need to export it to make it available. At the end of index.js add:
module.exports = {
'isTruthy': isTruthy,
};
<details> Since the exported name is the same as the function name you could do: module.exports = {isTruthy};
. </details>
Now run
yarn test
Your tests should still fail unless you skipped ahead and made it pass. In which case:
Bad Monkey! No donuts for you! go back and try again.
That's all folks! go ahead and make the test pass. The rest is up to you. Just remember:
Feedback and corrected spelling misteaks welcome: [email protected]