You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
6
6
7
7
[@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).
8
8
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
For the older APIs use v0.3.x and have a look at our [Legacy Guide](docs/legacy.md).
20
+
9
21
## Installation
10
22
11
23
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
14
26
ember install ember-cli-yadda
15
27
```
16
28
17
-
##### Versions >= 0.2.0
18
-
19
29
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:
20
30
21
31
```
22
32
/tests/acceptance/steps/steps.js
33
+
/tests/integration/steps/steps.js
23
34
/tests/unit/steps/steps.js
35
+
/tests/helpers/yadda.js
36
+
/tests/helpers/yadda-annotations.js
24
37
```
25
38
26
39
You may specify the version of yadda by changing it in package.json and running `npm install`.
27
40
28
-
##### Versions <= 0.1.0
41
+
##Upgrading
29
42
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:
31
45
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)
33
58
34
-
```js
35
-
// ember-cli-build.js
59
+
## Usage
36
60
37
-
var app =newEmberApp({
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/).
42
63
43
-
```
64
+
### Creating feature files
44
65
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:
46
67
47
-
##### Upgrading from <= 0.1.0 to >= 0.2.0
48
-
1. Un-install yadda from your bower dependencies: `bower uninstall yadda --save`.
* 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
+
```
54
71
72
+
#### Acceptance tests
55
73
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.
61
76
62
77
For example:
63
78
@@ -72,28 +87,16 @@ This will generate the following files in your project directory:
72
87
/tests/acceptance/make-a-feature.feature
73
88
```
74
89
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 =newEmberApp({
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.
92
95
93
96
For example:
94
97
95
98
```sh
96
-
ember g feature-unit make-a-feature
99
+
ember g feature make-a-feature --type=unit
97
100
```
98
101
99
102
This will generate the following files in your project directory:
@@ -103,11 +106,12 @@ This will generate the following files in your project directory:
103
106
/tests/unit/make-a-feature.feature
104
107
```
105
108
106
-
## Writing tests
109
+
###Writing tests
107
110
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:
109
112
110
113
```gherkin
114
+
@setupApplicationTest
111
115
Feature: bananas rot
112
116
113
117
Scenario: bananas rot faster when next to apples
@@ -117,21 +121,29 @@ Feature: bananas rot
117
121
Then the banana rots
118
122
```
119
123
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`
121
130
122
131
```js
123
132
importyaddafrom'../../helpers/yadda';
133
+
import { visit } from'@ember/test-helpers';
124
134
125
135
exportdefaultfunction(assert) {
126
136
returnyadda.localisation.English.library()
127
-
.given("I have bananas", function(next) {
128
-
visit("/bananas")
129
-
andThen(() =>next());
137
+
.given("I have bananas", asyncfunction() {
138
+
awaitvisit("/bananas");
130
139
});
131
140
}
132
141
```
133
142
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:
135
147
136
148
```js
137
149
importstepsfrom'./steps';
@@ -141,35 +153,31 @@ import steps from './steps';
141
153
142
154
exportdefaultfunction(assert) {
143
155
returnsteps(assert)
144
-
.given('it\'s next to apples', function(next) {
145
-
constapples=find('.apple');
156
+
.given('it\'s next to apples', function() {
157
+
let apples =this.element.querySelectorAll('.apple');
146
158
assert.ok(apples.length>0)
147
159
})
148
-
.when('left toghether for a while', function(next) {
160
+
.when('left together for a while', function(next) {
149
161
// bananas rot really quickly next to apples.
150
-
setTimeout(function() {
151
-
assert.ok(true);
152
-
next();
153
-
}, 1000);
162
+
setTimeout(next, 1000);
154
163
})
155
-
.then('the banana rots', function (next) {
156
-
constbanana=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'));
159
167
});
160
168
}
161
169
```
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`
165
170
166
-
You can skip tests by adding the `@ignore` annotation above the Scenario or Feature.
171
+
#### Important information
167
172
168
-
## Important information
169
173
##### 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.
171
178
172
179
##### Sharing variables between steps
180
+
173
181
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.
174
182
175
183
For Example:
@@ -181,43 +189,91 @@ For Example:
181
189
182
190
exportdefaultfunction(assert) {
183
191
returnsteps(assert)
184
-
.given('I add something to the context', function(next) {
192
+
.given('I add something to the context', function() {
185
193
// Assign 'hello' to the variable outside the step chain
186
194
something ='hello';
187
195
// Assign 'there' to a new variable in `this.ctx`
188
196
this.ctx.something='there';
189
197
assert.ok(true, this.step);
190
-
next();
191
198
})
192
-
.then('it should be there in the next step', function(next) {
199
+
.then('it should be there in the next step', function() {
193
200
// Do an assertion to check that 'there' has been passed correctly
.then('external variable should be there in the next step', function(next){
204
+
.then('external variable should be there in the next step', function(){
199
205
// Assert that the external variable still holds the information
200
206
// we set in the first step
201
207
assert.equal(something,'hello',this.step);
202
208
});
203
209
}
204
210
```
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.
207
211
208
-
For example:
209
-
```gherkin
210
-
@needs=component:ember-selectize
211
-
Feature: Component form-select
212
+
### Annotations
212
213
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:
// your existing tests/yadda-annotations.js file...
263
+
264
+
functionsetupYaddaTest(annotations) {
265
+
if (annotations.setupapplicationtest) { // lower case!
266
+
returnfunction(hooks) {
267
+
setupApplicationTest(hooks);
268
+
setupMirage(hooks);
269
+
}
270
+
}
271
+
// ...
272
+
}
217
273
```
218
274
219
275
## Inner workings
220
276
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.
222
278
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