Skip to content

Commit edb09fe

Browse files
simonihmigbenwalder
authored andcommitted
Update docs (#71)
1 parent 23618e0 commit edb09fe

File tree

2 files changed

+363
-86
lines changed

2 files changed

+363
-86
lines changed

README.md

Lines changed: 142 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,22 @@
22
[![Ember Observer Score](http://emberobserver.com/badges/ember-cli-yadda.svg)](http://emberobserver.com/addons/ember-cli-yadda)
33
# Ember-cli-yadda
44

5-
This ember-cli addon facilitates writing acceptance and unit tests in the Gherkin language and executing them against your Ember app.
5+
This Ember CLI addon facilitates writing BDD tests in the Gherkin language and executing them against your Ember app.
66

77
[@mschinis (Micheal Schinis)](https://github.com/mschinis) Did a great talk at @emberlondon [BDD approach with ember using `ember-cli-yadda`](https://vimeo.com/146828818).
88

9+
It uses the [yadda](https://github.com/acuminous/yadda) library to parse and run your feature files, and integrates into
10+
your Ember test setup using either [ember-qunit](https://github.com/emberjs/ember-qunit) or
11+
[ember-mocha](https://github.com/emberjs/ember-mocha).
12+
13+
The following describes the use of ember-cli-yadda >= v0.4.0 which works only with the latest modern
14+
Ember testing APIs, as laid out in the RFCs
15+
[232](https://github.com/emberjs/rfcs/blob/master/text/0232-simplify-qunit-testing-api.md)
16+
and
17+
[268](https://github.com/emberjs/rfcs/blob/master/text/0268-acceptance-testing-refactor.md).
18+
19+
For the older APIs use v0.3.x and have a look at our [Legacy Guide](docs/legacy.md).
20+
921
## Installation
1022

1123
Installing ember-cli-yadda is a breeze. All you need to do is run the following command in your project directory.
@@ -14,50 +26,53 @@ Installing ember-cli-yadda is a breeze. All you need to do is run the following
1426
ember install ember-cli-yadda
1527
```
1628

17-
##### Versions >= 0.2.0
18-
1929
This adds the latest version of yadda to your node modules, along with [ember-browserify](https://www.npmjs.com/package/ember-browserify) (to allow yadda to run in the browser). It also adds the following files:
2030

2131
```
2232
/tests/acceptance/steps/steps.js
33+
/tests/integration/steps/steps.js
2334
/tests/unit/steps/steps.js
35+
/tests/helpers/yadda.js
36+
/tests/helpers/yadda-annotations.js
2437
```
2538

2639
You may specify the version of yadda by changing it in package.json and running `npm install`.
2740

28-
##### Versions <= 0.1.0
41+
## Upgrading
2942

30-
ember-browserify is not used. Instead, yadda is also added to your bower dependencies. The files listed above are also added.
43+
To upgrade to the latest version of this addon from a previous release < 0.4.0, including refactoring your existing
44+
tests to Ember's new testing APIs, follow these steps:
3145

32-
After installation the addon will have added the most recent yadda version to your bower dependencies. As it comes with all yadda releases in its dist folder, you can specify which yadda version to include in your ember-cli build:
46+
- Install the latest version of ember-cli-yadda.
47+
- Run `ember g ember-cli-yadda` to add the most recent files from the blueprint to your project.
48+
- Add the appropriate [setup annotation](#setup-tests) to each Feature or Scenario.
49+
- Refactor your step files to use the new testing APIs:
50+
- for application tests, skip using Ember's global test helpers and use those provided by [@ember/test-helpers](https://github.com/emberjs/ember-test-helpers).
51+
- use `async`/`await` for all asynchronous operations, including `andThen()`
52+
- [ember-test-helpers-codemod](https://github.com/simonihmig/ember-test-helpers-codemod) will be able to do most of
53+
these changes automatically
54+
- For further details have a look at the [Migration Guide for QUnit](https://github.com/emberjs/ember-qunit/blob/master/docs/migration.md)
55+
or the [Migration Guide for Mocha](https://github.com/emberjs/ember-mocha/blob/master/docs/migration.md#upgrading-to-the-new-testing-apis)
56+
- *Optional*: customize `tests/helpers/yadda-annotations.js` with any additional setup logic that is needed, see
57+
[here](#customization)
3358

34-
```js
35-
// ember-cli-build.js
59+
## Usage
3660

37-
var app = new EmberApp({
38-
'ember-cli-yadda': {
39-
'yaddaVersion': '0.17.6'
40-
}
41-
});
61+
The following describes the specific features and Ember integration points of ember-cli-yadda. For general documentation
62+
on how to write yadda-based tests please consult the [Yadda User Guide](https://acuminous.gitbooks.io/yadda-user-guide/en/).
4263

43-
```
64+
### Creating feature files
4465

45-
Running `ember serve` will make the test results available at `http://localhost:4200/tests`.
66+
This ember-cli addon provides you with a blueprint with which you can create feature files:
4667

47-
##### Upgrading from <= 0.1.0 to >= 0.2.0
48-
1. Un-install yadda from your bower dependencies: `bower uninstall yadda --save`.
49-
2. Install ember-cli-yadda: `ember install ember-cli-yadda`.
50-
3. If a specific version of yadda is being used:
51-
* Remove the code from ember-cli-build.js that specifies the version.
52-
* Un-install the latest version of yadda from npm: `npm uninstall yadda --save-dev`.
53-
* Install the desired version of yadda: `npm install yadda@<desired version> --save-dev`.
68+
```sh
69+
ember g feature [feature title] --type=[acceptance|integration|unit]
70+
```
5471

72+
#### Acceptance tests
5573

56-
## Usage
57-
This ember-cli addon provides you with two blueprints with which you can create feature files.
58-
59-
##### Acceptance tests
60-
If you want to create acceptance tests, you can use ``ember g feature [feature title]`` which generates a feature file for your acceptance tests and a step definition.
74+
For acceptance tests you can omit the `--type` option. So you can use `ember g feature [feature title]` which generates
75+
a feature file for your acceptance tests and a step definition.
6176

6277
For example:
6378

@@ -72,28 +87,16 @@ This will generate the following files in your project directory:
7287
/tests/acceptance/make-a-feature.feature
7388
```
7489

75-
When using Mocha as your test framework, you have the option to run each scenario's step as a separate test, with all steps grouped within a Mocha `describe` block. If a step is failing, all following steps of that scenario will then be marked as pending. This way you get a much clearer picture on where (which step) a possible failure is happening. To opt in into that mode, use the `separateSteps` config option.
76-
77-
```js
78-
// ember-cli-build.js
79-
80-
var app = new EmberApp({
81-
'ember-cli-yadda': {
82-
'separateSteps': true
83-
}
84-
});
85-
86-
```
87-
88-
*Note that this mode is currently not available when you are using QUnit as your test framework!*
89-
90-
##### Unit tests
91-
To create a unit test, you can use ``ember g feature-unit [feature title]`` which generates a feature and step definition file where you can write your unit tests.
90+
#### Integration or unit tests
91+
92+
To create an integration or unit test, you can use `ember g feature [feature title] --type=integration` for an
93+
integration test, or `--type=unit` for a unit test. This generates a feature and step definition file where you can
94+
write your tests.
9295

9396
For example:
9497

9598
```sh
96-
ember g feature-unit make-a-feature
99+
ember g feature make-a-feature --type=unit
97100
```
98101

99102
This will generate the following files in your project directory:
@@ -103,11 +106,12 @@ This will generate the following files in your project directory:
103106
/tests/unit/make-a-feature.feature
104107
```
105108

106-
## Writing tests
109+
### Writing tests
107110

108-
All tests are asynchronous so when writing steps you should always call `next`. For example:
111+
Let's take this example of an acceptance test feature:
109112

110113
```gherkin
114+
@setupApplicationTest
111115
Feature: bananas rot
112116
113117
Scenario: bananas rot faster when next to apples
@@ -117,21 +121,29 @@ Feature: bananas rot
117121
Then the banana rots
118122
```
119123

120-
Because we probably have more features about bananas. We add the `Given I have bananas` to the global steps file: `/tests/acceptance/steps.js`
124+
The `@setupApplicationTest` annotation will setup all scenarios of this feature as application tests, using the
125+
`setupApplicationTest()` function provided by either `ember-qunit` or `ember-mocha`. See the [Annotations](#annotations)
126+
section below for more information on how to setup your tests.
127+
128+
Because we probably have more features about bananas, we add the `Given I have bananas` to the global steps file:
129+
`/tests/acceptance/steps.js`
121130

122131
```js
123132
import yadda from '../../helpers/yadda';
133+
import { visit } from '@ember/test-helpers';
124134

125135
export default function(assert) {
126136
return yadda.localisation.English.library()
127-
.given("I have bananas", function(next) {
128-
visit("/bananas")
129-
andThen(() => next());
137+
.given("I have bananas", async function() {
138+
await visit("/bananas");
130139
});
131140
}
132141
```
133142

134-
Notice how I wrapped the call to next in an `andThen` this tells the yadda to continue to the next step when the application routed to the `/bananas` route. Then fact that it's next to apples is probably unique to this Feature so we'll add it to the feature specific step definitions in `/tests/acceptance/steps/bananas-rot-feature-steps.js`. That will look like this:
143+
*Notice that the preferable way to handle asynchronous steps like the one above is to use `async`/ `await`. But you can
144+
also explicitly return a promise or use a `next()` [callback](https://acuminous.gitbooks.io/yadda-user-guide/en/usage/step-libraries.html).*
145+
146+
The fact that "it's next to apples" is probably unique to this Feature so we'll add it to the feature specific step definitions in `/tests/acceptance/steps/bananas-rot-feature-steps.js`. That will look like this:
135147

136148
```js
137149
import steps from './steps';
@@ -141,35 +153,31 @@ import steps from './steps';
141153

142154
export default function(assert) {
143155
return steps(assert)
144-
.given('it\'s next to apples', function(next) {
145-
const apples = find('.apple');
156+
.given('it\'s next to apples', function() {
157+
let apples = this.element.querySelectorAll('.apple');
146158
assert.ok(apples.length > 0)
147159
})
148-
.when('left toghether for a while', function(next) {
160+
.when('left together for a while', function(next) {
149161
// bananas rot really quickly next to apples.
150-
setTimeout(function() {
151-
assert.ok(true);
152-
next();
153-
}, 1000);
162+
setTimeout(next, 1000);
154163
})
155-
.then('the banana rots', function (next) {
156-
const banana = find('.banana');
157-
assert.ok(banana.hasClass('rotten'));
158-
next();
164+
.then('the banana rots', function () {
165+
let banana = this.element.querySelector('.banana');
166+
assert.ok(banana.classList.contains('rotten'));
159167
});
160168
}
161169
```
162-
**NOTE:** If you are creating a unit test, you need to use `<unit type>/<file name>` when using the generator. This allows ember-cli-yadda to automatically find and import the component, where it will run the tests against.
163-
164-
For example, creating a feature file for a component named `form-select`, you would use `ember g feature-unit components/form-select`
165170

166-
You can skip tests by adding the `@ignore` annotation above the Scenario or Feature.
171+
#### Important information
167172

168-
## Important information
169173
##### Scope and helpers
170-
ember-cli-yadda passes the original scope down to each step definition. This means that you have access to the same Ember helpers, like `andThen()` and `find()`, as you did when writing a normal acceptance/unit test in mocha/qunit.
174+
175+
ember-cli-yadda passes the original scope down to each step definition. This means that you have access to the same
176+
context (like `this.element` or `this.owner`) and helpers from `@ember/test-helpers` (like `click()`), as you did when
177+
writing a normal test in QUnit/Mocha.
171178

172179
##### Sharing variables between steps
180+
173181
You can easily share variables between your steps, by either creating a new variable outside your step chain, or by storing the values in `this.ctx` in each step.
174182

175183
For Example:
@@ -181,43 +189,91 @@ For Example:
181189

182190
export default function(assert) {
183191
return steps(assert)
184-
.given('I add something to the context', function(next) {
192+
.given('I add something to the context', function() {
185193
// Assign 'hello' to the variable outside the step chain
186194
something = 'hello';
187195
// Assign 'there' to a new variable in `this.ctx`
188196
this.ctx.something = 'there';
189197
assert.ok(true, this.step);
190-
next();
191198
})
192-
.then('it should be there in the next step', function(next) {
199+
.then('it should be there in the next step', function() {
193200
// Do an assertion to check that 'there' has been passed correctly
194201
// to the next step
195202
assert.equal(this.ctx.something, 'there', this.step);
196-
next();
197203
})
198-
.then('external variable should be there in the next step', function(next){
204+
.then('external variable should be there in the next step', function(){
199205
// Assert that the external variable still holds the information
200206
// we set in the first step
201207
assert.equal(something,'hello',this.step);
202208
});
203209
}
204210
```
205-
##### Testing components that depend on other components
206-
If you need to test a component, that depends on other components, you can use the `@needs` gherkin decorator to specify what this component depends on.
207211

208-
For example:
209-
```gherkin
210-
@needs=component:ember-selectize
211-
Feature: Component form-select
212+
### Annotations
212213

213-
Scenario: Check if component renders
214-
Given I initialize the component
215-
When I render it
216-
Then it should be rendered
214+
You already saw the use of the `@setupApplicationTest` annotation in the example feature file above.
215+
Yadda's [support for annotations](https://acuminous.gitbooks.io/yadda-user-guide/en/feature-specs/annotations.html`) can
216+
be used to customize the way tests are run.
217+
218+
The implementation for the way certain annotations affect your tests lives in the `tests/yadda-annotations.js` file.
219+
The addon installs this file with a default implementation as described below, but you can freely customize it at your
220+
will.
221+
222+
#### Skipping tests
223+
224+
You can skip tests by adding the `@ignore` annotation above the Scenario or Feature.
225+
226+
#### Test suites
227+
228+
You can set `ENV.annotations` to an array of annotations (either statically or e.g. by assigning them from an
229+
environment variable like `process.env.ANNOTATIONS`). This will then run only those Features or Scenarios that have one
230+
of these annotations assigned.
231+
232+
#### Setup tests
233+
234+
For each of the setup functions already known from `ember-qunit` or `ember-mocha`, there exists a corresponding
235+
annotation to setup your Feature/Scenario accordingly:
236+
237+
- `@setupTest` for (unit) tests requiring the DI container of Ember to be set up
238+
- `@setupRenderingTest` for (integration) tests allowing you to call `render`, e.g. for component tests
239+
- `@setupApplicationTest` for (acceptance) tests requiring the whole application to be booted
240+
241+
#### Customization
242+
243+
You can customize how annotations are handled in your app's `tests/yadda-annotations.js` file, e.g. to add support for
244+
additional annotations, or extend the existing ones. This module has to export these hooks, that are called by this
245+
addon's test runner:
246+
247+
- `runFeature`: called for each feature. If you return a function, this will be called to run the feature, instead of
248+
the default implementation.
249+
- `runScenario`: similar to `runFeature`, but called for each scenario.
250+
- `setupFeature`: called for each feature to setup the test environment. You can call QUnit's or Mocha's `beforeEach`
251+
and `afterEach` functions here to add custom setup/teardown work.
252+
- `setupScenario`: similar to `setupFeature`, but called for each scenario.
253+
254+
Have a look at the existing implementation and the comments present in your `tests/yadda-annotations.js` file!
255+
256+
Here is an example to extend the defaul implementation of the `@setupApplicationTest` annotation to also call the
257+
`setupMirage()` function provided by `ember-cli-mirage` to setup the Mirage server:
258+
259+
```js
260+
import setupMirage from 'ember-cli-mirage/test-support/setup-mirage';
261+
262+
// your existing tests/yadda-annotations.js file...
263+
264+
function setupYaddaTest(annotations) {
265+
if (annotations.setupapplicationtest) { // lower case!
266+
return function(hooks) {
267+
setupApplicationTest(hooks);
268+
setupMirage(hooks);
269+
}
270+
}
271+
// ...
272+
}
217273
```
218274

219275
## Inner workings
220276

221-
This ember addon registers a preprocessor that parses `.feature` / `.spec` / `.specification` files using [yadda](https://github.com/acuminous/yadda) and generates a `-test.js` file in the acceptance test folder. It also adds a little loader helper ``/tests/helpers/yadda.js`` because yadda does not define an amd module.
277+
This ember addon registers a preprocessor that parses `.feature` / `.spec` / `.specification` files using [yadda](https://github.com/acuminous/yadda) and generates a `-test.js` file in the apropriate test folder. It also adds a little loader helper ``/tests/helpers/yadda.js`` because yadda does not define an amd module.
222278

223-
The addon also adds two ES6 modules `/tests/acceptance/steps/steps`, `/tests/unit/steps/steps` you can extend in feature specific step definitions. Any shared step definitions should be moved to these file or included there, depending on the type of test you are running. Feature specific step definitions reside in ``/tests/acceptance/steps/`` and ``/tests/unit/steps``. The generated feature test js files import a ``/tests/[type]/steps/[feature title]-steps`` module, where type can either be `acceptance` or `unit`.
279+
The addon also adds ES6 modules `/tests/[type]/steps/steps` you can extend in feature specific step definitions. Any shared step definitions should be moved to these file or included there, depending on the type of test you are running. Feature specific step definitions reside in ``/tests/[type]/steps/``. The generated feature test js files import a ``/tests/[type]/steps/[feature title]-steps`` module, where type can either be `acceptance`, `integration` or `unit`.

0 commit comments

Comments
 (0)