cukable 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.yardopts +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +47 -0
- data/README.md +368 -0
- data/Rakefile +41 -0
- data/bin/cuke2fit +25 -0
- data/cukable.gemspec +26 -0
- data/features/conversion.feature +54 -0
- data/features/cuke_fixture.feature +147 -0
- data/features/slim_json_formatter.feature +153 -0
- data/features/step_definitions/cukable_steps.rb +115 -0
- data/features/support/env.rb +183 -0
- data/lib/cukable.rb +2 -0
- data/lib/cukable/conversion.rb +314 -0
- data/lib/cukable/cuke.rb +305 -0
- data/lib/cukable/helper.rb +221 -0
- data/lib/cukable/slim_json_formatter.rb +366 -0
- data/spec/conversion_spec.rb +275 -0
- data/spec/cuke_spec.rb +134 -0
- data/spec/helper_spec.rb +203 -0
- data/spec/spec_helper.rb +10 -0
- data/vendor/cache/rubyslim-0.1.1.gem +0 -0
- metadata +188 -0
data/.yardopts
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cukable (0.1.1)
|
5
|
+
cucumber
|
6
|
+
diff-lcs
|
7
|
+
json
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
bluecloth (2.0.11)
|
13
|
+
builder (2.1.2)
|
14
|
+
cucumber (0.8.5)
|
15
|
+
builder (~> 2.1.2)
|
16
|
+
diff-lcs (~> 1.1.2)
|
17
|
+
gherkin (~> 2.1.4)
|
18
|
+
json_pure (~> 1.4.3)
|
19
|
+
term-ansicolor (~> 1.0.4)
|
20
|
+
diff-lcs (1.1.2)
|
21
|
+
gherkin (2.1.5)
|
22
|
+
trollop (~> 1.16.2)
|
23
|
+
json (1.5.1)
|
24
|
+
json_pure (1.4.6)
|
25
|
+
rcov (0.9.9)
|
26
|
+
rspec (2.5.0)
|
27
|
+
rspec-core (~> 2.5.0)
|
28
|
+
rspec-expectations (~> 2.5.0)
|
29
|
+
rspec-mocks (~> 2.5.0)
|
30
|
+
rspec-core (2.5.1)
|
31
|
+
rspec-expectations (2.5.0)
|
32
|
+
diff-lcs (~> 1.1.2)
|
33
|
+
rspec-mocks (2.5.0)
|
34
|
+
term-ansicolor (1.0.5)
|
35
|
+
trollop (1.16.2)
|
36
|
+
yard (0.6.4)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
bluecloth
|
43
|
+
bundler (~> 1.0)
|
44
|
+
cukable!
|
45
|
+
rcov
|
46
|
+
rspec (>= 2.2.0)
|
47
|
+
yard
|
data/README.md
ADDED
@@ -0,0 +1,368 @@
|
|
1
|
+
Cukable
|
2
|
+
=======
|
3
|
+
|
4
|
+
Cukable allows you to write and execute [Cucumber](http://cukes.info) tests
|
5
|
+
from [FitNesse](http://fitnesse.org).
|
6
|
+
|
7
|
+
It consists of a [rubyslim](http://github.com/unclebob/rubyslim) fixture that
|
8
|
+
invokes Cucumber, and a custom Cucumber output formatter that returns
|
9
|
+
SliM-formatted test results to FitNesse.
|
10
|
+
|
11
|
+
|
12
|
+
Supported syntax
|
13
|
+
----------------
|
14
|
+
|
15
|
+
Most of the standard Cucumber/Gherkin syntax is supported by Cukable, including:
|
16
|
+
|
17
|
+
- Background sections
|
18
|
+
- Scenarios and Scenario Outlines with Examples
|
19
|
+
- Multiple scenarios per feature
|
20
|
+
- Multi-line table arguments and table diffing
|
21
|
+
- Multi-line strings
|
22
|
+
- Tags for running/skipping scenarios and defining drivers (such as `@selenium`)
|
23
|
+
|
24
|
+
|
25
|
+
Installation
|
26
|
+
------------
|
27
|
+
|
28
|
+
To install Cukable, do:
|
29
|
+
|
30
|
+
$ gem install cukable
|
31
|
+
|
32
|
+
Cukable requires [rubyslim](http://github.com/unclebob/rubyslim) in order to
|
33
|
+
work; as of this writing, rubyslim is not officially packaged as a gem, making
|
34
|
+
it slightly more difficult to get Cukable working. For this reason, a makeshift
|
35
|
+
rubyslim gem is provided in the `vendor/cache` directory of Cukable. Install
|
36
|
+
this into whatever environment you plan to run Cukable under, like so:
|
37
|
+
|
38
|
+
$ gem install /path/to/cukable/vendor/cache/rubyslim-0.1.1.gem
|
39
|
+
|
40
|
+
Please note that this is an unofficial gem, created without the sanction of the
|
41
|
+
rubyslim author. Until such time as rubyslim gets an official gem distribution,
|
42
|
+
please report any issues with it to the
|
43
|
+
[Cukable issue tracker](http://github.com/wapcaplet/cukable/issues).
|
44
|
+
|
45
|
+
|
46
|
+
Converting existing features
|
47
|
+
----------------------------
|
48
|
+
|
49
|
+
Cukable comes with an executable script to convert existing Cucumber features
|
50
|
+
to FitNesse wiki format. You must have an existing FitNesse page; features will
|
51
|
+
be imported under that page.
|
52
|
+
|
53
|
+
Usage:
|
54
|
+
|
55
|
+
cuke2fit <features_path> <fitnesse_path>
|
56
|
+
|
57
|
+
For example, if your existing features are in `features/`, and the FitNesse
|
58
|
+
wiki page you want to import them to is in `FitNesseRoot/MyTests`, do:
|
59
|
+
|
60
|
+
$ cuke2fit features FitNesseRoot/MyTests
|
61
|
+
|
62
|
+
The hierarchy of your `features/` folder will be preserved as a hierarchy of
|
63
|
+
FitNesse wiki pages. Each `.feature` file becomes a separate wiki page.
|
64
|
+
|
65
|
+
|
66
|
+
Writing new features
|
67
|
+
--------------------
|
68
|
+
|
69
|
+
You can write new Cucumber features from scratch, directly in FitNesse, and run
|
70
|
+
them from FitNesse with only minimal configuration.
|
71
|
+
|
72
|
+
Here's what a simple hierarchy might look like:
|
73
|
+
|
74
|
+
- FitNesseRoot
|
75
|
+
- CukableTests (suite)
|
76
|
+
- SetUp
|
77
|
+
- FeedKitty (test)
|
78
|
+
- CleanLitterbox (test)
|
79
|
+
|
80
|
+
Put these variable definitions in `CukableTests`:
|
81
|
+
|
82
|
+
!define TEST_SYSTEM {slim}
|
83
|
+
!define TEST_RUNNER {rubyslim}
|
84
|
+
!define COMMAND_PATTERN {rubyslim}
|
85
|
+
|
86
|
+
This is the essential configuration to tell FitNesse how to invoke `rubyslim`
|
87
|
+
for tests in the suite. Then put this in `CukableTests.SetUp`:
|
88
|
+
|
89
|
+
!| import |
|
90
|
+
| Cukable |
|
91
|
+
|
92
|
+
This tells `rubyslim` to load the `Cukable` module, so it'll know how to run
|
93
|
+
tests in `Cuke` tables. Now create a `Cuke` table in `CukableTests.FeedKitty`:
|
94
|
+
|
95
|
+
!| Table: Cuke |
|
96
|
+
| Feature: Feed kitty |
|
97
|
+
| Scenario: Canned food |
|
98
|
+
| Given I have a can of cat food |
|
99
|
+
| When I feed it to my cat |
|
100
|
+
| Then the cat should purr |
|
101
|
+
|
102
|
+
The `!` that precedes the table ensures that all text within will be treated
|
103
|
+
literally, and will not be marked up as FitNesse wiki-text. This is especially
|
104
|
+
important if you have CamelCase words, email addresses, or URLs in your table.
|
105
|
+
|
106
|
+
Also, note that all your steps must be defined in the usual way, such as `.rb`
|
107
|
+
files in `features/step_definitions`. That's outside Cukable's scope.
|
108
|
+
|
109
|
+
Finally, you can run the `FeedKitty` test by itself, or run the entire
|
110
|
+
`CukableTests` suite.
|
111
|
+
|
112
|
+
|
113
|
+
Test syntax
|
114
|
+
-----------
|
115
|
+
|
116
|
+
FitNesse uses wikitext tables delimited with a pipe `|` to format the
|
117
|
+
executable statements of a test scenario; these are rendered as HTML tables in
|
118
|
+
a FitNesse wiki page. When a test is run from FitNesse, the results of the test
|
119
|
+
are rendered into the same table, with green- or red-highlighted cells indicating
|
120
|
+
pass/fail status.
|
121
|
+
|
122
|
+
Cucumber tests written in a FitNesse wiki page closely resemble the
|
123
|
+
[Gherkin](http://github.com/aslakhellesoy/cucumber/wiki/gherkin) syntax that
|
124
|
+
Cucumber understands, with some changes in formatting to accommodate FitNesse.
|
125
|
+
|
126
|
+
If this is your `.feature` file:
|
127
|
+
|
128
|
+
Feature: Hello
|
129
|
+
Scenario: Hello world
|
130
|
+
Given I am on the hello page
|
131
|
+
Then I should see "Hello world"
|
132
|
+
|
133
|
+
Then here is what your FitNesse wikitext would be:
|
134
|
+
|
135
|
+
!| Table: Cuke |
|
136
|
+
| Feature: Hello |
|
137
|
+
| Scenario: Hello world |
|
138
|
+
| Given I am on the hello page |
|
139
|
+
| Then I should see "Hello world" |
|
140
|
+
|
141
|
+
Each row of the FitNesse table contains one step or other directive. Whitespace
|
142
|
+
before and/or after steps is not significant, so you can use it to aid
|
143
|
+
readability if you're into that sort of thing.
|
144
|
+
|
145
|
+
Your table must contain exactly one row with `Feature: ...`, and you must have
|
146
|
+
at least one `Scenario: ...` or `Scenario Outline: ...`.
|
147
|
+
|
148
|
+
|
149
|
+
Tables
|
150
|
+
------
|
151
|
+
|
152
|
+
Cucumber supports multiline step arguments in the form of tables; in a
|
153
|
+
`.feature` file, these might look like:
|
154
|
+
|
155
|
+
Feature: Tables
|
156
|
+
Scenario: Fill in fields
|
157
|
+
Given I am on the contact page
|
158
|
+
When I fill in the following:
|
159
|
+
| Name | Email | Message |
|
160
|
+
| Eric | wapcaplet88@gmail.com | Howdy |
|
161
|
+
|
162
|
+
In a FitNesse wiki page, this would translate to:
|
163
|
+
|
164
|
+
!| Table: Cuke |
|
165
|
+
| Feature: Tables |
|
166
|
+
| Scenario: Fill in fields |
|
167
|
+
| Given I am on the contact page |
|
168
|
+
| When I fill in the following: |
|
169
|
+
| | Name | Email | Message |
|
170
|
+
| | Eric | wapcaplet88@gmail.com | Howdy |
|
171
|
+
|
172
|
+
That is, each row in an embedded table begins with an empty cell. The same
|
173
|
+
applies to the "Examples" portion of a
|
174
|
+
[Scenario Outline](https://github.com/aslakhellesoy/cucumber/wiki/scenario-outlines):
|
175
|
+
|
176
|
+
| When I look at paint samples |
|
177
|
+
| Then I should see "<color>" |
|
178
|
+
| Examples: |
|
179
|
+
| | color |
|
180
|
+
| | Taupe |
|
181
|
+
| | Vermilion |
|
182
|
+
| | Fuscia |
|
183
|
+
|
184
|
+
|
185
|
+
Multi-line strings
|
186
|
+
------------------
|
187
|
+
|
188
|
+
To pass a multi-line string to one of your steps, just enter it as you normally
|
189
|
+
would in a .feature file, with triple-double-quotes delimiting the string:
|
190
|
+
|
191
|
+
| When I fill in "Message" with: |
|
192
|
+
| """ |
|
193
|
+
| So long, and |
|
194
|
+
| thanks for all the fish! |
|
195
|
+
| """ |
|
196
|
+
|
197
|
+
|
198
|
+
Tags
|
199
|
+
----
|
200
|
+
|
201
|
+
You can include Cucumber tags, as long as you only include one tag per row in
|
202
|
+
the table:
|
203
|
+
|
204
|
+
| @tag_a |
|
205
|
+
| @tag_b |
|
206
|
+
| Feature: Tagged feature |
|
207
|
+
| @tag_c |
|
208
|
+
| @tag_d |
|
209
|
+
| Scenario: Tagged scenario |
|
210
|
+
| When I have some tags |
|
211
|
+
|
212
|
+
The inclusion of tags is useful for defining which driver to use (for example
|
213
|
+
the `@selenium` tag supported by Capybara), as well as for controlling which
|
214
|
+
tests are run via cucumber command-line arguments, described below.
|
215
|
+
|
216
|
+
|
217
|
+
Acceleration
|
218
|
+
------------
|
219
|
+
|
220
|
+
Normally, FitNesse runs tests one-by-one. That is, under normal circumstances,
|
221
|
+
each `Cuke` table will result in its own standalone execution of `cucumber`.
|
222
|
+
This means that when you run a suite of tests, Cucumber will be running
|
223
|
+
multiple times (once per feature) when it should really be running all features
|
224
|
+
at once.
|
225
|
+
|
226
|
+
This may be fine if your test environment is simple, and Cucumber runs quickly.
|
227
|
+
But if your application has a lot of dependencies to load, there may be too much
|
228
|
+
overhead to run a suite of tests in this way.
|
229
|
+
|
230
|
+
Cukable provides a workaround to this in the form of something called `AaaAccelerator`.
|
231
|
+
If you have a suite of three features:
|
232
|
+
|
233
|
+
- MyFeatures (suite)
|
234
|
+
- FirstFeature (test)
|
235
|
+
- SecondFeature (test)
|
236
|
+
- ThirdFeature (test)
|
237
|
+
|
238
|
+
and you want to be able to run the entire suite without invoking a separate
|
239
|
+
Cucumber instance each time, simply create a new child page of `MyFeatures` called
|
240
|
+
`AaaAccelerator` (named this way so it will be executed first in the suite):
|
241
|
+
|
242
|
+
- MyFeatures (suite)
|
243
|
+
- AaaAccelerator (test)
|
244
|
+
- FirstFeature (test)
|
245
|
+
- SecondFeature (test)
|
246
|
+
- ThirdFeature (test)
|
247
|
+
|
248
|
+
The `AaaAccelerator` page does not need to have any content; you can leave it
|
249
|
+
empty if you like. Its existence alone will cause acceleration to take effect
|
250
|
+
for the suite that it's in. To make this magic happen, you must add this to your
|
251
|
+
`SetUp` page for the suite:
|
252
|
+
|
253
|
+
| script | Cuke |
|
254
|
+
| accelerate; | ${PAGE_PATH}.${PAGE_NAME} | ${CUCUMBER_ARGS} |
|
255
|
+
|
256
|
+
Include this exactly as it appears; the variables will be expanded to the
|
257
|
+
name of your `AaaAccelerator` page when the suite runs. The `CUCUMBER_ARGS`
|
258
|
+
piece is an optional argument that passes any defined command-line arguments
|
259
|
+
to Cucumber (see below).
|
260
|
+
|
261
|
+
You can nest suites inside each other, and each suite can have its own
|
262
|
+
`AaaAccelerator` page. Whenever you execute a suite, the highest-level
|
263
|
+
accelerator will be executed (thus running as many features as possible
|
264
|
+
together).
|
265
|
+
|
266
|
+
|
267
|
+
Cucumber args
|
268
|
+
-------------
|
269
|
+
|
270
|
+
There are two ways to pass command-line arguments to Cucumber when running
|
271
|
+
features. The first is by passing an argument directly to the `Cuke`
|
272
|
+
constructor in a feature table; just include an extra cell in the first row:
|
273
|
+
|
274
|
+
!| Table: Cuke | --tags @run_me |
|
275
|
+
| Feature: Arguments |
|
276
|
+
| @run_me |
|
277
|
+
| Scenario: This will be run |
|
278
|
+
| @dont_run_me |
|
279
|
+
| Scenario: This will be skipped |
|
280
|
+
|
281
|
+
This is the approach you'd use if you wanted to run a single test with
|
282
|
+
specific command-line arguments. If you want to run an entire suite using
|
283
|
+
the `AaaAccelerator` technique described above, you can define command-line
|
284
|
+
arguments as a FitNesse variable, like this:
|
285
|
+
|
286
|
+
!define CUCUMBER_ARGS {--tags @run_me}
|
287
|
+
|
288
|
+
Put this at the top of any suite page, and any `AaaAccelerator` in that suite
|
289
|
+
will pass those additional arguments to Cucumber. Note that these will override
|
290
|
+
any arguments passed to individual tables, because Cucumber is only executed
|
291
|
+
once for the entire suite.
|
292
|
+
|
293
|
+
|
294
|
+
Support
|
295
|
+
-------
|
296
|
+
|
297
|
+
This README, along with API documentation on Cukable, are available on
|
298
|
+
[rdoc.info](http://rdoc.info/github/wapcaplet/cukable/master/frames).
|
299
|
+
|
300
|
+
Please report any bugs, complaints, and feature requests to the
|
301
|
+
[issue tracker](http://github.com/wapcaplet/cukable/issues).
|
302
|
+
|
303
|
+
|
304
|
+
Development
|
305
|
+
-----------
|
306
|
+
|
307
|
+
To hack on Cukable's code, first fork the
|
308
|
+
[repository](http://github.com/wapcaplet/cukable),
|
309
|
+
then clone your fork locally:
|
310
|
+
|
311
|
+
$ git clone git://github.com/your_username/cukable.git
|
312
|
+
|
313
|
+
Install [bundler](http://gembundler.com/):
|
314
|
+
|
315
|
+
$ gem install bundler
|
316
|
+
|
317
|
+
Then install Cukable's dependencies:
|
318
|
+
|
319
|
+
$ cd /path/to/cukable
|
320
|
+
$ bundle install
|
321
|
+
|
322
|
+
It's a good idea to use [RVM](http://rvm.beginrescueend.com/)
|
323
|
+
with a new gemset to keep things tidy.
|
324
|
+
|
325
|
+
If you make changes that you'd like to share, push them into your fork,
|
326
|
+
then [submit a pull request](http://github.com/wapcaplet/cukable/pulls).
|
327
|
+
|
328
|
+
|
329
|
+
Testing
|
330
|
+
-------
|
331
|
+
|
332
|
+
Cukable includes a suite of self-tests, executed using RSpec and Cucumber.
|
333
|
+
These are in the `spec` and `features` directories, respectively. To run the
|
334
|
+
full suite of tests, simply run:
|
335
|
+
|
336
|
+
$ rake
|
337
|
+
|
338
|
+
This will generate output showing the status of each test, and will also use
|
339
|
+
[rcov](http://eigenclass.org/hiki.rb?rcov) to write a code coverage report to
|
340
|
+
`coverage/index.html`.
|
341
|
+
|
342
|
+
|
343
|
+
Copyright
|
344
|
+
---------
|
345
|
+
|
346
|
+
The MIT License
|
347
|
+
|
348
|
+
Copyright (c) 2011 Automation Excellence
|
349
|
+
|
350
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
351
|
+
a copy of this software and associated documentation files (the
|
352
|
+
"Software"), to deal in the Software without restriction, including
|
353
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
354
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
355
|
+
permit persons to whom the Software is furnished to do so, subject to
|
356
|
+
the following conditions:
|
357
|
+
|
358
|
+
The above copyright notice and this permission notice shall be
|
359
|
+
included in all copies or substantial portions of the Software.
|
360
|
+
|
361
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
362
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
363
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
364
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
365
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
366
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
367
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
368
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
|
5
|
+
namespace :rcov do
|
6
|
+
desc "Run RSpec tests with coverage analysis"
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.pattern = 'spec/**/*_spec.rb'
|
9
|
+
t.rspec_opts = ['--color', '--format doc']
|
10
|
+
t.rcov = true
|
11
|
+
t.rcov_opts = [
|
12
|
+
'--exclude /.gem/,/gems/,spec,features',
|
13
|
+
'--include lib/**/*.rb',
|
14
|
+
'--aggregate coverage.data',
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Run Cucumber tests with coverage analysis"
|
19
|
+
Cucumber::Rake::Task.new(:cucumber) do |t|
|
20
|
+
t.cucumber_opts = [
|
21
|
+
"--format pretty",
|
22
|
+
"--tags ~@wip",
|
23
|
+
]
|
24
|
+
t.rcov = true
|
25
|
+
t.rcov_opts = [
|
26
|
+
'--exclude /.gem/,/gems/,spec,features',
|
27
|
+
'--include lib/**/*.rb',
|
28
|
+
'--aggregate coverage.data',
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Run RSpec and Cucumber tests with coverage analysis"
|
33
|
+
task :all do |t|
|
34
|
+
rm 'coverage.data' if File.exist?('coverage.data')
|
35
|
+
Rake::Task['rcov:spec'].invoke
|
36
|
+
Rake::Task['rcov:cucumber'].invoke
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => ['rcov:all']
|
41
|
+
|