2015-10-09 13:33:12 -04:00
include ../../../../_includes/_util-fns
2015-11-10 13:31:46 -05:00
:marked
2015-10-14 23:25:19 -04:00
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.
2015-10-09 13:33:12 -04:00
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
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## Install npm packages locally
2015-10-14 23:25:19 -04:00
Next follow all of the steps prescribed in “Install npm packages locally” of the
[QuickStart](../quickstart.html).
2015-10-09 13:33:12 -04:00
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
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
Be sure to install `jasmine-core` , not `jasmine`!
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
**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
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
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.
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
Create a new file called`unit-tests.html` and enter the following:
```
<html>
2015-10-14 23:25:19 -04:00
<head>
2015-10-09 13:33:12 -04:00
<title>1st Jasmine Tests</title>
2015-10-18 15:20:52 -04:00
<link rel="stylesheet" href="../node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
2015-10-09 13:33:12 -04:00
2015-10-18 15:20:52 -04:00
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
2016-01-28 19:15:26 -05:00
<script src="../node_modules/jasmine-core/lib/jasmine-core/main.js"></script>
2015-10-09 13:33:12 -04:00
</head>
<body>
</body>
</html>
```
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:
2015-10-14 23:25:19 -04:00
```
<script>
it('true is true', function(){ expect(true).toEqual(true); });
</script>
```
2015-10-09 13:33:12 -04:00
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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
It doesn’ t get much simpler than that!
2015-11-10 13:31:46 -05:00
2015-10-16 04:06:56 -04:00
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## First TypeScript Test
2015-10-14 23:25:19 -04:00
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` ** .
2015-10-09 13:33:12 -04:00
.l-sub-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
Among Jasmine developers, a test is known as a “spec” and test filenames include the word “spec”. We’ ll stick with that convention.
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
The test we wrote is valid TypeScript because any JavaScript is valid TypeScript. But let’ s make it more modern with an arrow function:
2015-10-14 23:25:19 -04:00
```
it('true is true', () => expect(true).toEqual(true));
```
2015-10-09 13:33:12 -04:00
Now modify `unit-tests.html` to load the script:
2015-10-14 23:25:19 -04:00
```
<script src="1st.spec.js"></script>
```
2015-10-09 13:33:12 -04:00
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.
2015-10-16 04:06:56 -04:00
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## Prepare for TypeScript
2015-10-14 23:25:19 -04:00
As we’ ve seen before, we first have to tell the compiler how to compile our TypeScript files with
a ** `tsconfig.json` **.
2015-10-09 13:33:12 -04:00
2015-10-14 23:25:19 -04:00
We can copy one from an application we wrote previously and paste it into our src sub-folder.
It should look something like this:
2015-10-09 13:33:12 -04:00
```
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
2016-01-19 04:15:26 -05:00
},
"exclude": [
"node_modules"
]
2015-10-09 13:33:12 -04:00
}
```
## Compile and Run
Compile in the terminal window using the npm script command
pre.prettyprint.lang-bash
code npm run tsc
2015-10-14 23:25:19 -04:00
.alert.is-helpful
2015-11-10 13:31:46 -05:00
:marked
2015-10-14 23:25:19 -04:00
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.
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
If we reload the browser, we should see the same Jasmine test-runner output as before.
2015-10-14 23:25:19 -04:00
We’ ll be evolving these tests rapidly and it would be nice to have the browser refresh automatically as we make changes and recompile.
2015-10-09 13:33:12 -04:00
Let’ s launch with **live-server** in a second terminal window:
pre.prettyprint.lang-bash
code npm start
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
Now navigate to `1st-tests.html`
We should get the same Jasmine test-runner output as before.
2015-10-16 04:06:56 -04:00
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## 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.
2015-11-21 12:59:03 -05:00
We should wrap this test into 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).
2015-10-09 13:33:12 -04:00
2015-10-14 23:25:19 -04:00
Here’ s what our revised `1st.spec.ts` looks like when wrapped in a `describe`:
```
describe('1st tests', () => {
2015-10-09 13:33:12 -04:00
2015-10-14 23:25:19 -04:00
it('true is true', () => expect(true).toEqual(true));
2015-10-09 13:33:12 -04:00
2015-10-14 23:25:19 -04:00
});
```
2015-10-09 13:33:12 -04:00
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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
Let’ s add another Jasmine test to `1st.spec.ts`
2015-10-14 23:25:19 -04:00
```
it('null is not the same thing as undefined',
() => expect(null).not.toEqual(undefined)
);
```
2015-10-09 13:33:12 -04:00
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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
We can re-run just the failing test by double-clicking it. Try it!
2015-10-16 04:06:56 -04:00
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## 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")
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
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.
2015-10-17 13:01:41 -04:00
<!-- TODO
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-17 13:01:41 -04:00
## Learn more
Learn more about basic Jasmine testing here
[Resources TBD](./#)
-->
2015-11-10 13:31:46 -05:00
2015-10-16 04:06:56 -04:00
.l-main-section
2015-11-10 13:31:46 -05:00
:marked
2015-10-09 13:33:12 -04:00
## What’ s Next?
Now that we’ re familiar with Jasmine on its own, we’ re ready to test an application.
2015-11-21 12:59:03 -05:00
What application? We introduce you to it in the [next chapter](application-under-test.html).