Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .pullapprove.yml
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,14 @@ groups:
contains_any_globs(files.exclude('packages/compiler-cli/**'), [
'**/testing/**',
'aio/content/guide/testing.md',
'aio/content/guide/test-debugging.md',
'aio/content/guide/testing-attribute-directives.md',
'aio/content/guide/testing-code-coverage.md',
'aio/content/guide/testing-components-basics.md',
'aio/content/guide/testing-components-scenarios.md',
'aio/content/guide/testing-pipes.md',
'aio/content/guide/testing-services.md',
'aio/content/guide/testing-utility-apis.md',
'aio/content/examples/testing/**',
'aio/content/images/guide/testing/**'
])
Expand Down
28 changes: 28 additions & 0 deletions aio/content/guide/test-debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Debugging tests

If your tests aren't working as you expect them to, you can inspect and debug them in the browser.

<div class="alert is-helpful">

For the sample app that the testing guides describe, see the <live-example embedded-style noDownload>sample app</live-example>.

For the tests features in the testing guides, see <live-example stackblitz="specs" noDownload>tests</live-example>.

</div>


Debug specs in the browser in the same way that you debug an application.

1. Reveal the Karma browser window. See [Set up testing](guide/testing#set-up-testing) if you need help with this step.
1. Click the **DEBUG** button; it opens a new browser tab and re-runs the tests.
1. Open the browser's “Developer Tools” (`Ctrl-Shift-I` on Windows; `Command-Option-I` in macOS).
1. Pick the "sources" section.
1. Open the `1st.spec.ts` test file (Control/Command-P, then start typing the name of the file).
1. Set a breakpoint in the test.
1. Refresh the browser, and it stops at the breakpoint.

<div class="lightbox">
<img src='generated/images/guide/testing/karma-1st-spec-debug.png' alt="Karma debugging">
</div>

<hr>
78 changes: 78 additions & 0 deletions aio/content/guide/testing-attribute-directives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

{@a attribute-directive}

# Testing Attribute Directives

An _attribute directive_ modifies the behavior of an element, component or another directive.
Its name reflects the way the directive is applied: as an attribute on a host element.

<div class="alert is-helpful">

For the sample app that the testing guides describe, see the <live-example embedded-style noDownload>sample app</live-example>.

For the tests features in the testing guides, see <live-example stackblitz="specs" noDownload>tests</live-example>.

</div>

## Testing the `HighlightDirective`

The sample application's `HighlightDirective` sets the background color of an element
based on either a data bound color or a default color (lightgray).
It also sets a custom property of the element (`customProperty`) to `true`
for no reason other than to show that it can.

<code-example path="testing/src/app/shared/highlight.directive.ts" header="app/shared/highlight.directive.ts"></code-example>

It's used throughout the application, perhaps most simply in the `AboutComponent`:

<code-example path="testing/src/app/about/about.component.ts" header="app/about/about.component.ts"></code-example>

Testing the specific use of the `HighlightDirective` within the `AboutComponent` requires only the techniques explored in the ["Nested component tests"](guide/testing-components-scenarios#nested-component-tests) section of [Component testing scenarios](guide/testing-components-scenarios).

<code-example path="testing/src/app/about/about.component.spec.ts" region="tests" header="app/about/about.component.spec.ts"></code-example>

However, testing a single use case is unlikely to explore the full range of a directive's capabilities.
Finding and testing all components that use the directive is tedious, brittle, and almost as unlikely to afford full coverage.

_Class-only tests_ might be helpful,
but attribute directives like this one tend to manipulate the DOM.
Isolated unit tests don't touch the DOM and, therefore,
do not inspire confidence in the directive's efficacy.

A better solution is to create an artificial test component that demonstrates all ways to apply the directive.

<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="test-component" header="app/shared/highlight.directive.spec.ts (TestComponent)"></code-example>

<div class="lightbox">
<img src='generated/images/guide/testing/highlight-directive-spec.png' alt="HighlightDirective spec in action">
</div>

<div class="alert is-helpful">

The `<input>` case binds the `HighlightDirective` to the name of a color value in the input box.
The initial value is the word "cyan" which should be the background color of the input box.

</div>

Here are some tests of this component:

<code-example path="testing/src/app/shared/highlight.directive.spec.ts" region="selected-tests" header="app/shared/highlight.directive.spec.ts (selected tests)"></code-example>

A few techniques are noteworthy:

- The `By.directive` predicate is a great way to get the elements that have this directive _when their element types are unknown_.

- The <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:not">`:not` pseudo-class</a>
in `By.css('h2:not([highlight])')` helps find `<h2>` elements that _do not_ have the directive.
`By.css('*:not([highlight])')` finds _any_ element that does not have the directive.

- `DebugElement.styles` affords access to element styles even in the absence of a real browser, thanks to the `DebugElement` abstraction.
But feel free to exploit the `nativeElement` when that seems easier or more clear than the abstraction.

- Angular adds a directive to the injector of the element to which it is applied.
The test for the default color uses the injector of the second `<h2>` to get its `HighlightDirective` instance
and its `defaultColor`.

- `DebugElement.properties` affords access to the artificial custom property that is set by the directive.

<hr>
57 changes: 57 additions & 0 deletions aio/content/guide/testing-code-coverage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{@a code-coverage}

# Find out how much code you're testing

The CLI can run unit tests and create code coverage reports.
Code coverage reports show you any parts of your code base that may not be properly tested by your unit tests.

<div class="alert is-helpful">

For the sample app that the testing guides describe, see the <live-example embedded-style noDownload>sample app</live-example>.

For the tests features in the testing guides, see <live-example stackblitz="specs" noDownload>tests</live-example>.

</div>


To generate a coverage report run the following command in the root of your project.

<code-example language="sh" class="code-shell">
ng test --no-watch --code-coverage
</code-example>

When the tests are complete, the command creates a new `/coverage` folder in the project. Open the `index.html` file to see a report with your source code and code coverage values.

If you want to create code-coverage reports every time you test, you can set the following option in the CLI configuration file, `angular.json`:

```
"test": {
"options": {
"codeCoverage": true
}
}
```

## Code coverage enforcement

The code coverage percentages let you estimate how much of your code is tested.
If your team decides on a set minimum amount to be unit tested, you can enforce this minimum with the Angular CLI.

For example, suppose you want the code base to have a minimum of 80% code coverage.
To enable this, open the [Karma](https://karma-runner.github.io) test platform configuration file, `karma.conf.js`, and add the following in the `coverageIstanbulReporter:` key.

```
coverageIstanbulReporter: {
reports: [ 'html', 'lcovonly' ],
fixWebpackSourcePaths: true,
thresholds: {
statements: 80,
lines: 80,
branches: 80,
functions: 80
}
}
```

The `thresholds` property causes the tool to enforce a minimum of 80% code coverage when the unit tests are run in the project.

Loading