angular-cn/public/docs/ts/latest/testing/jasmine-testing-101.jade

234 lines
8.0 KiB
Plaintext
Raw Normal View History

include ../../../../_includes/_util-fns
:markdown
Well write our tests with the [Jasmine test framework](http://jasmine.github.io/2.3/introduction.html).
Well 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).
Well 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. Its not the best venue for working with a lot of tests and it wont do at all for build automation. Well 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:
```
<html>
<head>
<title>1st Jasmine Tests</title>
<link rel="stylesheet" href="../node_modules/jasmine/lib/jasmine.css">
<script src="../node_modules/jasmine/lib/jasmine.js"></script>
<script src="../node_modules/jasmine/lib/jasmine-html.js"></script>
<script src="../node_modules/jasmine/lib/boot.js"></script>
</head>
<body>
</body>
</html>
```
In the head we have three Jasmine scripts and one Jasmine css file. Thats the foundation for running any tests.
Well write our first test with inline JavaScript inside the body tag:
```
<script>
it('true is true', function(){ expect(true).toEqual(true); });
</script>
```
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 doesnt get much simpler than that!
.l-main-section
:markdown
## First TypeScript Test
Perhaps too simple. We wont write our entire test suite inside one HTML file.
Lets **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”. Well stick with that convention.
:markdown
The test we wrote is valid TypeScript because any JavaScript is valid TypeScript. But lets 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:
```
<script src="1st.spec.js"></script>
```
Hold on! We wrote a TypeScript file but were loading a JavaScript file?
Thats 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 weve 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 dont 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.
Well be evolving these tests rapidly and it would be nice to have the browser refresh automatically as we make changes and recompile.
Lets 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 cant tell what file produced these test results. We only have one file at the moment but soon well 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).
Heres 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 heres 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
Lets 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? Lets 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 didnt know what was going on. We can debug it in the browser.
- Open the browsers “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 arent 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 … youve completed Jasmine testing 101.
.l-main-section
:markdown
## Learn more
Learn more about basic Jasmine testing here
[Resources TBD](./#)
.l-main-section
:markdown
## Whats Next?
Now that were familiar with Jasmine on its own, were ready to test an application.
What application? We introduce you to that app in the next chapter.