include ../../../../_includes/_util-fns
:markdown
We’ll write our tests with the [Jasmine test framework](http://jasmine.github.io/2.3/introduction.html).
We’ll start by getting *some* tests to work - *any* tests at all.
We will learn
- basic Jasmine testing skills
- to run our tests in the browser
- to write simple Jasmine tests in TypeScript
- to debug a test in the browser
**Create a new project folder** perhaps called `angular2-unit-testing`.
.l-main-section
:markdown
## Install npm packages locally
Next follow all of the steps prescribed in “Install npm packages locally” of the
[QuickStart](../quickstart.html).
We’ll also add the Jasmine package via `npm`:
pre.prettyprint.lang-bash
code npm install jasmine-core --save-dev --save-exact
.alert.is-important
:markdown
Be sure to install `jasmine-core` , not `jasmine`!
:markdown
**Create a sub-folder `src` ** for our tests and then **cd into it**.
We are going to **display and control our tests in the browser**.
.l-sub-section
:markdown
The browser is nice during development of a few tests. It’s not the best venue for working with a lot of tests and it won’t do at all for build automation. We’ll switch to the karma test-runner when the time comes. But the browser will do for now.
:markdown
Create a new file called`unit-tests.html` and enter the following:
```
1st Jasmine Tests
```
In the head we have three Jasmine scripts and one Jasmine css file. That’s the foundation for running any tests.
We’ll write our first test with inline JavaScript inside the body tag:
```
```
Now open `unit-tests.html` in a browser and see the Jasmine HTML test output:
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/jasmine-1-spec-0-failures.png' style="height:170px;" alt="Jasmine HTML test output")
:markdown
It doesn’t get much simpler than that!
.l-main-section
:markdown
## First TypeScript Test
Perhaps too simple. We won’t write our entire test suite inside one HTML file.
Let’s **extract** that line of test code to a **new file in `src` called `1st.spec.ts` ** .
.l-sub-section
:markdown
Among Jasmine developers, a test is known as a “spec” and test filenames include the word “spec”. We’ll stick with that convention.
:markdown
The test we wrote is valid TypeScript because any JavaScript is valid TypeScript. But let’s make it more modern with an arrow function:
```
it('true is true', () => expect(true).toEqual(true));
```
Now modify `unit-tests.html` to load the script:
```
```
Hold on! We wrote a TypeScript file but we’re loading a JavaScript file?
That’s a reminder that we need to compile our TypeScript test files as we do our TypeScript application files. Do that next.
.l-main-section
:markdown
## Prepare for TypeScript
As we’ve seen before, we first have to tell the compiler how to compile our TypeScript files with
a ** `tsconfig.json` **.
We can copy one from an application we wrote previously and paste it into our src sub-folder.
It should look something like this:
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
```
## Compile and Run
Compile in the terminal window using the npm script command
pre.prettyprint.lang-bash
code npm run tsc
.alert.is-helpful
:markdown
Our editor and the compiler may complain that they don’t know
what `it` and `expect` are because they lack the typing files that describe Jasmine.
We can ignore those annoying complaints for now as they are harmless.
:markdown
If we reload the browser, we should see the same Jasmine test-runner output as before.
We’ll be evolving these tests rapidly and it would be nice to have the browser refresh automatically as we make changes and recompile.
Let’s launch with **live-server** in a second terminal window:
pre.prettyprint.lang-bash
code npm start
:markdown
Now navigate to `1st-tests.html`
We should get the same Jasmine test-runner output as before.
.l-main-section
:markdown
## Add a describe and another test
We can’t tell what file produced these test results. We only have one file at the moment but soon we’ll write more.
We should wrap this test something that identifies the file. In Jasmine that “something” is a `describe` function. Every test file should have at least one `describe` that identifies the file holding the test(s).
Here’s what our revised `1st.spec.ts` looks like when wrapped in a `describe`:
```
describe('1st tests', () => {
it('true is true', () => expect(true).toEqual(true));
});
```
And here’s how the test report displays it.
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/test-report-1-spec-0-failures.png' style="height:100px;" alt="1 spec, 0 failures")
:markdown
Let’s add another Jasmine test to `1st.spec.ts`
```
it('null is not the same thing as undefined',
() => expect(null).not.toEqual(undefined)
);
```
You knew that right? Let’s prove it with this test. The browser should refresh after you paste that test, and show:
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/test-report-2-specs-0-failures.png' style="height:100px;" alt="refreshed 2 specs, 0 failures")
:markdown
What does a failing test look like? Remove the `.not`. The browser refreshes and shows:
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/test-report-2-specs-1-failure.png' style="height:190px;" alt="failing test 2 specs, 1 failure")
:markdown
Click the `Spec List` link just below “2 specs, 1 failure” to see the summary again:
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/spec-list-2-specs-1-failure.png' style="height:140px;" alt="2 specs, 1 failure")
:markdown
We can re-run just the failing test by double-clicking it. Try it!
.l-main-section
:markdown
## Debug the test
Suppose we didn’t know what was going on. We can debug it in the browser.
- Open the browser’s “Developer Tools” (F12 or Ctrl-Shift-I).
- Pick the “sources” section
- Open the `1st.spec.ts` test file (Ctrl-P, then start typing the name of the file).
- Set a breakpoint on the second line of the failing test
- Refresh the browser … and it stops at our breakpoint.
- Open the console window at the bottom (press Esc)
- Type `null === undefined` … … and we should see this:
figure.image-display
img(src='/resources/images/devguide/jasmine-testing-101/null-to-equal-undefined.png' style="height:500px;" alt="null === undefined")
:markdown
How about that! They really aren’t equal.
- remove the breakpoint (right-click in the “Breakpoints” section and chose “Remove breakpoint”)
- Click the “play” icon to resume the test (or F8)
And the test finishes. Close the browser tools (click the close box or press F12 or Ctrl-Shift-I)
Fix the test (restore the `.not`); the browser should refresh automatically and all tests pass.
Congratulations … you’ve completed Jasmine testing 101.
.l-main-section
:markdown
## What’s Next?
Now that we’re familiar with Jasmine on its own, we’re ready to test an application.
What application? We introduce you to it in the next chapter.