spinach 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -4,7 +4,6 @@
4
4
  .bundle
5
5
  .config
6
6
  .yardoc
7
- Gemfile.lock
8
7
  InstalledFiles
9
8
  _yardoc
10
9
  coverage
@@ -17,3 +16,4 @@ test/tmp
17
16
  test/version_tmp
18
17
  tmp
19
18
  capybara-*.html
19
+ Gemfile.lock
data/Gemfile CHANGED
@@ -9,7 +9,7 @@ group :test do
9
9
  gem 'guard'
10
10
  gem 'guard-minitest'
11
11
  gem 'guard-spinach'
12
- gem 'capybara'
12
+ gem 'capybara', '~> 1.1.3'
13
13
  end
14
14
 
15
15
  group :darwin do
data/README.markdown CHANGED
@@ -22,117 +22,130 @@ would be irresponsible :)
22
22
 
23
23
  Start by adding spinach to your Gemfile:
24
24
 
25
- group :test do
26
- gem 'spinach'
27
- # gem 'rspec'
28
- end
25
+ ```ruby
26
+ group :test do
27
+ gem 'spinach'
28
+ # gem 'rspec'
29
+ end
30
+ ```
29
31
 
30
32
  Spinach works out-of-the-box with your favorite test suite, but you can also
31
33
  use it with RSpec as well if you put the following in `features/support/env.rb`:
32
34
 
33
- require 'rspec'
35
+ ```ruby
36
+ require 'rspec'
37
+ ```
34
38
 
35
39
  Now create a `features` folder in your app or library and write your first
36
40
  feature:
37
41
 
38
- Feature: Test how spinach works
39
- In order to know what the heck is spinach
40
- As a developer
41
- I want it to behave in an expected way
42
-
43
- Scenario: Formal greeting
44
- Given I have an empty array
45
- And I append my first name and my last name to it
46
- When I pass it to my super-duper method
47
- Then the output should contain a formal greeting
48
-
49
- Scenario: Informal greeting
50
- Given I have an empty array
51
- And I append only my first name to it
52
- When I pass it to my super-duper method
53
- Then the output should contain a casual greeting
42
+ ```cucumber
43
+ Feature: Test how spinach works
44
+ In order to know what the heck is spinach
45
+ As a developer
46
+ I want it to behave in an expected way
47
+
48
+ Scenario: Formal greeting
49
+ Given I have an empty array
50
+ And I append my first name and my last name to it
51
+ When I pass it to my super-duper method
52
+ Then the output should contain a formal greeting
53
+
54
+ Scenario: Informal greeting
55
+ Given I have an empty array
56
+ And I append only my first name to it
57
+ When I pass it to my super-duper method
58
+ Then the output should contain a casual greeting
59
+ ```
54
60
 
55
61
  Now for the steps file. Remember that in Spinach steps are just Ruby classes,
56
62
  following a camelcase naming convention. Spinach generator will do some
57
63
  scaffolding for you:
58
64
 
59
- $ spinach --generate
65
+ ```shell
66
+ $ spinach --generate
67
+ ```
60
68
 
61
69
  Spinach will detect your features and generate the following class:
62
70
 
63
71
  ## features/steps/test_how_spinach_works.rb
64
72
 
65
- class TestHowSpinachWorks < Spinach::FeatureSteps
66
- Given 'I have an empty array' do
67
- end
73
+ ```ruby
74
+ class TestHowSpinachWorks < Spinach::FeatureSteps
75
+ Given 'I have an empty array' do
76
+ end
68
77
 
69
- And 'I append my first name and my last name to it' do
70
- end
78
+ And 'I append my first name and my last name to it' do
79
+ end
71
80
 
72
- When 'I pass it to my super-duper method' do
73
- end
81
+ When 'I pass it to my super-duper method' do
82
+ end
74
83
 
75
- Then 'the output should contain a formal greeting' do
76
- end
84
+ Then 'the output should contain a formal greeting' do
85
+ end
77
86
 
78
- And 'I append only my first name to it' do
79
- end
87
+ And 'I append only my first name to it' do
88
+ end
80
89
 
81
- Then 'the output should contain a casual greeting' do
82
- end
83
- end
90
+ Then 'the output should contain a casual greeting' do
91
+ end
92
+ end
93
+ ```
84
94
 
85
95
  Then, you can fill it in with your logic - remember, it's just a class, you can
86
96
  use private methods, mix in modules or whatever!
87
97
 
88
- class TestHowSpinachWorks < Spinach::FeatureSteps
89
- Given 'I have an empty array' do
90
- @array = Array.new
91
- end
92
-
93
- And 'I append my first name and my last name to it' do
94
- @array += ["John", "Doe"]
95
- end
96
-
97
- When 'I pass it to my super-duper method' do
98
- @output = capture_output do
99
- Greeter.greet(@array)
100
- end
101
- end
102
-
103
- Then 'the output should contain a formal greeting' do
104
- @output.must_include "Hello, mr. John Doe"
105
- end
106
-
107
- And 'I append only my first name to it' do
108
- @array += ["John"]
109
- end
110
-
111
- Then 'the output should contain a casual greeting' do
112
- @output.must_include "Yo, John! Whassup?"
113
- end
114
-
115
- private
116
-
117
- def capture_output
118
- out = StringIO.new
119
- $stdout = out
120
- $stderr = out
121
- yield
122
- $stdout = STDOUT
123
- $stderr = STDERR
124
- out.string
125
- end
98
+ ```ruby
99
+ class TestHowSpinachWorks < Spinach::FeatureSteps
100
+ Given 'I have an empty array' do
101
+ @array = Array.new
102
+ end
103
+
104
+ And 'I append my first name and my last name to it' do
105
+ @array += ["John", "Doe"]
106
+ end
107
+
108
+ When 'I pass it to my super-duper method' do
109
+ @output = capture_output do
110
+ Greeter.greet(@array)
126
111
  end
127
- module Greeter
128
- def self.greet(name)
129
- if name.length > 1
130
- puts "Hello, mr. #{name.join(' ')}"
131
- else
132
- puts "Yo, #{name.first}! Whassup?"
133
- end
134
- end
112
+ end
113
+
114
+ Then 'the output should contain a formal greeting' do
115
+ @output.must_include "Hello, mr. John Doe"
116
+ end
117
+
118
+ And 'I append only my first name to it' do
119
+ @array += ["John"]
120
+ end
121
+
122
+ Then 'the output should contain a casual greeting' do
123
+ @output.must_include "Yo, John! Whassup?"
124
+ end
125
+
126
+ private
127
+
128
+ def capture_output
129
+ out = StringIO.new
130
+ $stdout = out
131
+ $stderr = out
132
+ yield
133
+ $stdout = STDOUT
134
+ $stderr = STDERR
135
+ out.string
136
+ end
137
+ end
138
+
139
+ module Greeter
140
+ def self.greet(name)
141
+ if name.length > 1
142
+ puts "Hello, mr. #{name.join(' ')}"
143
+ else
144
+ puts "Yo, #{name.first}! Whassup?"
135
145
  end
146
+ end
147
+ end
148
+ ```
136
149
 
137
150
  Then run your feature again running `spinach` and watch it all turn green! :)
138
151
 
@@ -143,47 +156,59 @@ used for different purposes:
143
156
 
144
157
  - applying some actions using hooks (eg: `@javascript`, `@transaction`, `@vcr`)
145
158
 
146
- # When using Capybara, you can switch the driver to use another one with
147
- # javascript capabilities (Selenium, Poltergeist, capybara-webkit, ...)
148
- #
149
- # Spinach already integrates with Capybara if you add
150
- # `require spinach/capybara` in `features/support/env.rb`.
151
- #
152
- # This example is extracted from this integration.
153
- Spinach.hooks.on_tag("javascript") do
154
- ::Capybara.current_driver = ::Capybara.javascript_driver
155
- end
159
+ ```ruby
160
+ # When using Capybara, you can switch the driver to use another one with
161
+ # javascript capabilities (Selenium, Poltergeist, capybara-webkit, ...)
162
+ #
163
+ # Spinach already integrates with Capybara if you add
164
+ # `require spinach/capybara` in `features/support/env.rb`.
165
+ #
166
+ # This example is extracted from this integration.
167
+ Spinach.hooks.on_tag("javascript") do
168
+ ::Capybara.current_driver = ::Capybara.javascript_driver
169
+ end
170
+ ```
156
171
 
157
172
  - filtering (eg: `@module-a`, `@customer`, `@admin`, `@bug-12`, `@feat-1`)
158
173
 
159
- # Given a feature file with this content
174
+ ```cucumber
175
+ # Given a feature file with this content
160
176
 
161
- @feat-1
162
- Feature: So something great
177
+ @feat-1
178
+ Feature: So something great
163
179
 
164
- Scenario: Make it possible
180
+ Scenario: Make it possible
165
181
 
166
- @bug-12
167
- Scenario: Ensure no regression on this
182
+ @bug-12
183
+ Scenario: Ensure no regression on this
184
+ ```
168
185
 
169
186
  Then you can run all Scenarios in your suite related to `@feat-1` using:
170
187
 
171
- spinach --tags @feat-1
188
+ ```shell
189
+ $ spinach --tags @feat-1
190
+ ```
172
191
 
173
192
  Or only Scenarios related to `@feat-1` and `@bug-12` using:
174
193
 
175
- spinach --tags @feat-1,@bug-12
194
+ ```shell
195
+ $ spinach --tags @feat-1,@bug-12
196
+ ```
176
197
 
177
198
  Or only Scenarios related to `@feat-1` excluding `@bug-12` using:
178
199
 
179
- spinach --tags @feat-1,~@bug-12
200
+ ```shell
201
+ $ spinach --tags @feat-1,~@bug-12
202
+ ```
180
203
 
181
204
  By default Spinach will ignore Scenarios marked with the tag `@wip` or whose
182
205
  Feature is marked with the tag `@wip`. Those are meant to be work in progress,
183
206
  scenarios that are pending while you work on them. To explicitly run those, use
184
207
  the `--tags` option:
185
208
 
186
- spinach --tags @wip
209
+ ```shell
210
+ $ spinach --tags @wip
211
+ ```
187
212
 
188
213
  ## Hook architecture
189
214
 
@@ -192,22 +217,44 @@ after any feature, scenario or step execution.
192
217
 
193
218
  So, for example, you could:
194
219
 
195
- Spinach.hooks.before_scenario do |scenario|
196
- clear_database
197
- end
220
+ ```ruby
221
+ Spinach.hooks.before_scenario do |scenario|
222
+ clear_database
223
+ end
198
224
 
199
- Spinach.hooks.on_successful_step do |step, location|
200
- count_steps(step.scenario.steps)
201
- end
225
+ Spinach.hooks.on_successful_step do |step, location|
226
+ count_steps(step.scenario.steps)
227
+ end
202
228
 
203
- Spinach.hooks.after_run do |status|
204
- send_mail if status == 0
205
- end
229
+ Spinach.hooks.after_run do |status|
230
+ send_mail if status == 0
231
+ end
232
+ ```
206
233
 
207
234
  Full hook documentation is here:
208
235
 
209
236
  [Spinach's hook documentation on rubydoc](http://rubydoc.info/github/codegram/spinach/master/Spinach/Hooks)
210
237
 
238
+ ## Local Before and After Hooks
239
+
240
+ Sometimes it feels awkward to add steps into feature file just because you need to do some test setup and cleanup. And it is equally awkward to add a global hooks for this purpose. For example, if you want to add a session timeout feature, to do so, you want to set the session timeout time to 1 second just for this feature, and put the normal timeout back after this feature. It doesn't make sense to add two steps in the feature file just to change the session timeout value. In this scenario, a ```before``` and ```after``` blocks are perfect for this kind of tasks. Below is an example implementation:
241
+
242
+ ```ruby
243
+ class SessionTimeout < Spinach::FeatureSteps
244
+ attr_accessor :original_timeout_value
245
+ before do
246
+ self.original_timeout_value = session_timeout_value
247
+ change_session_timeout_to 1.second
248
+ end
249
+
250
+ after do
251
+ change_session_timeout_to original_timeout_value
252
+ end
253
+
254
+ # remaining steps
255
+ end
256
+ ```
257
+
211
258
  ## Wanna use it with Rails 3?
212
259
 
213
260
  Use [spinach-rails](http://github.com/codegram/spinach-rails)
@@ -258,4 +305,3 @@ You can easily contribute to Spinach. Its codebase is simple and
258
305
  ## License
259
306
 
260
307
  MIT License. Copyright 2011 [Codegram Technologies](http://codegram.com)
261
-
data/bin/spinach CHANGED
@@ -12,5 +12,4 @@ rescue LoadError
12
12
  end
13
13
 
14
14
  cli = Spinach::Cli.new(ARGV)
15
- cli.init_reporter
16
15
  exit cli.run
@@ -0,0 +1,10 @@
1
+ Feature: Before and after hooks
2
+ In order to setup and clean the test environment for a single feature
3
+ As a developer
4
+ I want to be able to use before and after hooks within the step class
5
+
6
+ Scenario: Happy path
7
+ Then I can verify the variable setup in the before hook
8
+
9
+ Scenario: Inter-dependency - after hook cleans up (after happy path)
10
+ Then I can verify the variable setup in the before hook
@@ -0,0 +1,12 @@
1
+ Feature: Before and after hooks inheritance
2
+ In order to maintain the super classes' before and after code
3
+ As a developer
4
+ I want to chain the before and after blocks
5
+
6
+ Scenario: Happy path
7
+ Then I can see the variable setup in the super class before hook
8
+ And I can see the variable being overridden in the subclass
9
+
10
+ Scenario: Inter-dependency - after hook cleans up (after happy path)
11
+ Then I can see the variable setup in the super class before hook
12
+ And I can see the variable being overridden in the subclass
@@ -0,0 +1,9 @@
1
+ Feature: Use customized reporter
2
+ As a developer
3
+ I want to use a different reporter
4
+ So I can have different output
5
+
6
+ Scenario: Happy path
7
+ Given I have a feature that has no error or failure
8
+ When I run it using the new reporter
9
+ Then I see the desired output
@@ -1,7 +1,7 @@
1
1
  Feature: Show step source location
2
2
  As a developer
3
3
  I want spinach to give me every step source location in output
4
- So I can easyly know where I defined a step
4
+ So I can easily know where I defined a step
5
5
 
6
6
  Scenario: Show class steps source location in output when all is ok
7
7
  Given I have a feature that has no error or failure
@@ -0,0 +1,21 @@
1
+ class BeforeAndAfterHooks < Spinach::FeatureSteps
2
+ class << self
3
+ attr_accessor :var1
4
+ end
5
+
6
+ before do
7
+ if self.class.var1.nil?
8
+ self.class.var1 = :clean
9
+ else
10
+ self.class.var1 = :dirty
11
+ end
12
+ end
13
+
14
+ after do
15
+ self.class.var1 = nil
16
+ end
17
+
18
+ Then 'I can verify the variable setup in the before hook' do
19
+ self.class.var1.must_equal :clean
20
+ end
21
+ end