specify 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -107
- data/lib/specify/rspec/example_group.rb +19 -7
- data/lib/specify/spec.rb +7 -0
- data/lib/specify/version.rb +1 -1
- data/lib/specify.rb +8 -11
- data/spec/shared_steps_spec.rb +1 -1
- data/spec/steps_spec.rb +16 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69e28c76e85f675a58da7de545f6dabbbce8d096
|
4
|
+
data.tar.gz: 18fe6a1eba5d7f22d547d1d4c7b714e0f01127f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c70699a694cc659c87a2084213da46efa23fc44c67fcd0d483a3e83a67d8053e744ccfd5865da9614cc9caef63f2438a140ad589fd3ee1bb5241bc5684a6ee8c
|
7
|
+
data.tar.gz: 5397feaf56d969fa864111c8e0bcac12b988ff7e12bcaa8a18b63d025a4ddebafbea4845e2816b4ab5982c607e60d4585837d0fc7440549339e8c560d881f316
|
data/README.md
CHANGED
@@ -9,11 +9,13 @@
|
|
9
9
|
|
10
10
|
[![Gitter chat](https://badges.gitter.im/jnyman/specify.png)](https://gitter.im/jnyman/specify)
|
11
11
|
[![endorse](https://api.coderwall.com/jnyman/endorsecount.png)](https://coderwall.com/jnyman)
|
12
|
-
[![Stories in Ready](https://badge.waffle.io/jnyman/specify.png?label=ready&title=Ready)](https://waffle.io/jnyman/specify)
|
13
12
|
|
14
|
-
|
13
|
+
> _"Simplicity is the ultimate sophistication."_
|
14
|
+
> -- <cite>Leonardo DaVinci</cite>
|
15
15
|
|
16
|
-
Specify is a
|
16
|
+
Specify is a test solution development tool that acts as a BDD-style micro-framework.
|
17
|
+
|
18
|
+
Specify provides a very thin wrapper around RSpec that provides a Gherkin-style syntax for use with test examples.
|
17
19
|
|
18
20
|
## Installation
|
19
21
|
|
@@ -33,119 +35,25 @@ Or install it yourself as:
|
|
33
35
|
|
34
36
|
## Usage
|
35
37
|
|
36
|
-
To use Specify you simply have to require it within your `spec_helper` file
|
37
|
-
|
38
|
-
While Specify does provide a Gherkin-like syntax, there is no parsing of a Gherkin feature and step definition matching. Just as in RSpec, everything is in one place: the Ruby file. The benefit here is that you don't have to change the text in two places (feature file and step definition file) every time you change something. Further, there are no more matchers to sync up with natural language. Specify uses plain Ruby helper methods coupled with various patterns.
|
39
|
-
|
40
|
-
### Integration Tests
|
41
|
-
|
42
|
-
RSpec's mode of action is that all examples should be completely independent. This is in line with its focus as primarily a unit-based testing framework. For integration purposes, this means if you want to use RSpec you have to write a sequence of examples, each of which repeats the behavior of all previous examples. Another alternative is that you could write one single large example that performs the entire set of actions. The problem in that case is that there is no independent reporting of each step.
|
43
|
-
|
44
|
-
This is why tools like Cucumber end up being used.
|
45
|
-
|
46
|
-
However the only benefit there is the ability to execute some examples in sequence and skip subsequent steps after a failure.
|
47
|
-
|
48
|
-
So that's the goal of Specify: provide just the good parts of Cucumber and skipping all the questionable parts. At minimum this means the ability to chain examples into a series of steps that run in sequence and which stop when a step fails. The idea is to assemble a series of tests that should all pass, but where completely isolating them is not sensible. Hooking this into RSpec, this would make RSpec less unit and more integration.
|
49
|
-
|
50
|
-
### Example
|
51
|
-
|
52
|
-
Consider this example of a standard RSpec example group:
|
38
|
+
To use Specify you simply have to require it within your `spec_helper` file:
|
53
39
|
|
54
40
|
```ruby
|
55
|
-
|
56
|
-
context 'when simple logic tests are applied' do
|
57
|
-
it 'will agree that true almost certainly not false' do
|
58
|
-
expect(true).to_not be false
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'will agree that true is pretty definitely true' do
|
62
|
-
expect(true).to be true
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
describe 'Simple Scenarios' do
|
68
|
-
context 'with an instance variable' do
|
69
|
-
it 'will establish a variable' do
|
70
|
-
@active = 'testing'
|
71
|
-
expect(@active).to eq 'testing'
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'will reference the instance variable' do
|
75
|
-
puts "@active = #{@active}"
|
76
|
-
expect(@active).to eq 'testing'
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
41
|
+
require 'specify'
|
80
42
|
```
|
81
43
|
|
82
|
-
|
44
|
+
Then you simply run your `rspec` command as normal against your test suite.
|
83
45
|
|
84
|
-
|
85
|
-
context 'when simple logic tests are applied' do
|
86
|
-
steps do
|
87
|
-
Given 'true is almost certainly not false' do
|
88
|
-
expect(true).to_not be false
|
89
|
-
end
|
90
|
-
|
91
|
-
Given 'true is pretty definitely true' do
|
92
|
-
expect(true).to be true
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
context 'Simple Scenarios' do
|
98
|
-
steps 'with an instance variable' do
|
99
|
-
When 'it establishes an instance variable' do
|
100
|
-
@active = 'testing'
|
101
|
-
expect(@active).to eq 'testing'
|
102
|
-
end
|
103
|
-
|
104
|
-
Then 'that instance variable can be referenced' do
|
105
|
-
puts "@active = #{@active}"
|
106
|
-
expect(@active).to eq 'testing'
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
```
|
46
|
+
## Why Specify?
|
111
47
|
|
112
|
-
|
48
|
+
Specify provides an internal DSL, similar to the [RSpec Story Runner](https://github.com/dchelimsky/rspec-stories), which was the predecessor of the [Cucumber](http://cukes.info/) external DSL provided by [Gherkin](http://cukes.info/gherkin.html).
|
113
49
|
|
114
|
-
|
50
|
+
Behavior Driven Development (or even just good Test Driven Development) practices put emphasis on communication. Tools like Cucumber focus on allowing communication via a test description language, structured by Gherkin keywords. However, while the ideas of Gherkin are nice, tools like Cucumber abstract away the nuts and bolts of your tests.
|
115
51
|
|
116
|
-
|
117
|
-
shared_steps 'login' do |email, password|
|
118
|
-
When 'I go to login page' do
|
119
|
-
puts 'Go to the login page'
|
120
|
-
end
|
121
|
-
|
122
|
-
When 'I put credentials' do
|
123
|
-
puts "Email: #{email}, Password: #{password}"
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
shared_steps 'invalid login' do
|
128
|
-
Then 'I should see login error' do
|
129
|
-
puts 'Expect a login error'
|
130
|
-
end
|
131
|
-
end
|
132
|
-
```
|
52
|
+
Abstraction can be a good thing but Cucumber gives you no choice in the matter. It hides code blocks behind a "call by regular expression" invocation mechanism instead of making those code blocks readily available in the acceptance test description.
|
133
53
|
|
134
|
-
|
54
|
+
Specify lets you write as much logic beside your specifications as you want by leveraging the RSpec ecosystem with the addition of a Gherkin-like syntax.
|
135
55
|
|
136
|
-
|
137
|
-
context 'action' do
|
138
|
-
steps 'User provides wrong email' do
|
139
|
-
include_steps 'login', 'jeff', 'invalid'
|
140
|
-
include_steps 'invalid login'
|
141
|
-
end
|
142
|
-
|
143
|
-
steps 'User provides wrong password' do
|
144
|
-
include_steps 'login', 'jeff@example.com', 'testing'
|
145
|
-
include_steps 'invalid login'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
```
|
56
|
+
The [wiki](https://github.com/jnyman/specify/wiki) contains more information about Specify.
|
149
57
|
|
150
58
|
## Contributing
|
151
59
|
|
@@ -157,7 +65,7 @@ To work on Specify:
|
|
157
65
|
4. Push the branch. (`git push origin my-new-feature`)
|
158
66
|
5. Create a new [pull request](https://help.github.com/articles/using-pull-requests).
|
159
67
|
|
160
|
-
##
|
68
|
+
## Author
|
161
69
|
|
162
70
|
* [Jeff Nyman](http://testerstories.com)
|
163
71
|
|
@@ -16,33 +16,45 @@ module RSpec
|
|
16
16
|
instance_exec(*args, &shared_block)
|
17
17
|
end
|
18
18
|
|
19
|
+
def Test(message, options={}, &block)
|
20
|
+
Action :test, message, options, &block
|
21
|
+
end
|
22
|
+
|
23
|
+
def Step(message, options={}, &block)
|
24
|
+
Action :step, message, options, &block
|
25
|
+
end
|
26
|
+
|
19
27
|
def Given(message, options={}, &block)
|
20
|
-
|
28
|
+
Action :given, message, options, &block
|
21
29
|
end
|
22
30
|
|
23
31
|
def When(message, options={}, &block)
|
24
|
-
|
32
|
+
Action :when, message, options, &block
|
25
33
|
end
|
26
34
|
|
27
35
|
def Then(message, options={}, &block)
|
28
|
-
|
36
|
+
Action :then, message, options, &block
|
29
37
|
end
|
30
38
|
|
31
39
|
def And(message, options = {}, &block)
|
32
|
-
|
40
|
+
Action :and, message, options, &block
|
33
41
|
end
|
34
42
|
|
35
43
|
def But(message, options = {}, &block)
|
36
|
-
|
44
|
+
Action :but, message, options, &block
|
37
45
|
end
|
38
46
|
|
39
47
|
def _(message, options = {}, &block)
|
40
|
-
|
48
|
+
Action :_, message, options, &block
|
49
|
+
end
|
50
|
+
|
51
|
+
def it(message, options = {}, &block)
|
52
|
+
Action :it, message, options, &block
|
41
53
|
end
|
42
54
|
|
43
55
|
private
|
44
56
|
|
45
|
-
def
|
57
|
+
def Action(type, message, options = {}, &block)
|
46
58
|
::RSpec.world.reporter.example_step_started(self, type, message, options)
|
47
59
|
|
48
60
|
if block_given? && !options[:pending]
|
data/lib/specify/spec.rb
CHANGED
@@ -3,6 +3,9 @@ module Specify
|
|
3
3
|
def self.included(base)
|
4
4
|
base.instance_eval do
|
5
5
|
alias :Background :before
|
6
|
+
alias :Setup :before
|
7
|
+
alias :Teardown :after
|
8
|
+
alias :Ability :context
|
6
9
|
end
|
7
10
|
end
|
8
11
|
end
|
@@ -16,4 +19,8 @@ def self.Ability(*args, &block)
|
|
16
19
|
describe(*args, &block)
|
17
20
|
end
|
18
21
|
|
22
|
+
def self.Story(*args, &block)
|
23
|
+
describe(*args, &block)
|
24
|
+
end
|
25
|
+
|
19
26
|
RSpec.configuration.include Specify::Spec
|
data/lib/specify/version.rb
CHANGED
data/lib/specify.rb
CHANGED
@@ -1,21 +1,17 @@
|
|
1
|
-
require 'specify/version'
|
2
|
-
|
3
|
-
module Specify
|
4
|
-
end
|
5
|
-
|
6
1
|
require 'rspec/core'
|
7
|
-
require 'rspec/core/example_group'
|
8
|
-
require 'rspec/core/reporter'
|
9
2
|
require 'rspec/core/world'
|
3
|
+
require 'rspec/core/reporter'
|
10
4
|
require 'rspec/core/formatters'
|
5
|
+
require 'rspec/core/example_group'
|
11
6
|
require 'rspec/core/formatters/console_codes'
|
12
7
|
require 'rspec/core/formatters/documentation_formatter'
|
13
8
|
|
14
9
|
require 'specify/spec'
|
15
|
-
require 'specify/
|
16
|
-
require 'specify/rspec/notification'
|
17
|
-
require 'specify/rspec/reporter'
|
10
|
+
require 'specify/version'
|
18
11
|
require 'specify/rspec/world'
|
12
|
+
require 'specify/rspec/reporter'
|
13
|
+
require 'specify/rspec/notification'
|
14
|
+
require 'specify/rspec/example_group'
|
19
15
|
require 'specify/rspec/documentation_formatter'
|
20
16
|
|
21
17
|
RSpec::Core::ExampleGroup.send :include, RSpec::Specify::ExampleGroup
|
@@ -34,8 +30,9 @@ if formatter = RSpec.world.reporter.find_registered_formatter(RSpec::Core::Forma
|
|
34
30
|
)
|
35
31
|
end
|
36
32
|
|
37
|
-
|
38
33
|
RSpec::Core::ExampleGroup.define_example_method :steps, with_steps: true
|
34
|
+
RSpec::Core::ExampleGroup.define_example_method :tests, with_steps: true
|
35
|
+
|
39
36
|
RSpec::Core::ExampleGroup.define_example_method :Scenario, with_steps: true
|
40
37
|
|
41
38
|
require 'specify/rspec/shared_steps'
|
data/spec/shared_steps_spec.rb
CHANGED
data/spec/steps_spec.rb
CHANGED
@@ -27,17 +27,32 @@ Ability 'specify steps' do
|
|
27
27
|
@generic = 'Generic value'
|
28
28
|
end
|
29
29
|
|
30
|
+
it 'it' do
|
31
|
+
@it = 'It value'
|
32
|
+
end
|
33
|
+
|
34
|
+
Test 'test' do
|
35
|
+
@test = 'Test value'
|
36
|
+
end
|
37
|
+
|
38
|
+
Step 'step' do
|
39
|
+
@step = 'Step value'
|
40
|
+
end
|
41
|
+
|
30
42
|
expect(@context).to eq('Given value')
|
31
43
|
expect(@action).to eq('When value')
|
32
44
|
expect(@result).to eq('Then value')
|
33
45
|
expect(@and).to eq('And value')
|
34
46
|
expect(@but).to eq('But value')
|
35
47
|
expect(@generic).to eq('Generic value')
|
48
|
+
expect(@it).to eq('It value')
|
49
|
+
expect(@test).to eq('Test value')
|
50
|
+
expect(@step).to eq('Step value')
|
36
51
|
end
|
37
52
|
end
|
38
53
|
|
39
54
|
describe 'Steps without blocks' do
|
40
|
-
|
55
|
+
tests 'will be pending' do
|
41
56
|
Given 'step without block'
|
42
57
|
When 'step without block'
|
43
58
|
Then 'step without block'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: specify
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Nyman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -99,7 +99,7 @@ licenses:
|
|
99
99
|
- MIT
|
100
100
|
metadata: {}
|
101
101
|
post_install_message: "\n(::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::) (::)\n\n
|
102
|
-
\ Specify 0.
|
102
|
+
\ Specify 0.4.0 has been installed.\n\n(::) (::) (::) (::) (::) (::) (::) (::) (::)
|
103
103
|
(::) (::) (::)\n "
|
104
104
|
rdoc_options: []
|
105
105
|
require_paths:
|