test-harness 0.4.3 → 0.4.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +205 -0
- data/VERSION +1 -1
- data/test-harness.gemspec +5 -5
- metadata +22 -22
- data/README.rdoc +0 -19
data/README.markdown
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
# Test Harness
|
2
|
+
|
3
|
+
Test Harness is a testing framework which allows for clean separation of test responsibilities.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
Test Harness is available as a rubygem from rubygems.org
|
7
|
+
|
8
|
+
gem install test-harness
|
9
|
+
|
10
|
+
Or add to your Gemfile:
|
11
|
+
group :development, :test do
|
12
|
+
gem 'test-harness'
|
13
|
+
end
|
14
|
+
|
15
|
+
## Structure
|
16
|
+
Rails.root/
|
17
|
+
test_harness/
|
18
|
+
/given
|
19
|
+
/ui
|
20
|
+
|
21
|
+
Using Test Harness with Cucumber and Rspec allows you to isolate and DRY both setup code (GIVEN) and your
|
22
|
+
UI driver and observer (UI) from the actual tests. This allows you to focus on testing and removes the
|
23
|
+
cluter of details communicating with the database (for setup), and communicating with the browser (for
|
24
|
+
verification).
|
25
|
+
|
26
|
+
Test Harness will autoload the files in /given and /ui folders, where it expects specific patterns for filenames
|
27
|
+
and defined classes as discussed below.
|
28
|
+
|
29
|
+
## Cucumber DSL Example
|
30
|
+
|
31
|
+
|
32
|
+
### 1. features/some_test.feature
|
33
|
+
Feature steps should be abstract at a level high enough for customer or product manager to easily understand.
|
34
|
+
|
35
|
+
Feature: Login feature
|
36
|
+
Scenario: Login
|
37
|
+
Given a user
|
38
|
+
When I submit valid credentials
|
39
|
+
Then I am logged in
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
### 2. features/step_definitions/login_step.rb
|
44
|
+
Step definition should also be at a high level void of most details, and easy to follow for the developer. It is
|
45
|
+
best to keep each step to few lines of code (3 is a good max). Notice the syntax of the assertions 'should be_something.
|
46
|
+
|
47
|
+
Test Harness provides four objects that you can use in a step definition, three of them you can use here (**given, uid, uiv**), and hopefully the fourth one (**mm** - for Mental Model) you only need to use within the test harness artifacts.
|
48
|
+
|
49
|
+
Given /^a user$/ do
|
50
|
+
given.a_user
|
51
|
+
end
|
52
|
+
|
53
|
+
When /^I submit valid credentials$/ do
|
54
|
+
uid.login_form.submit_valid_credentials
|
55
|
+
end
|
56
|
+
|
57
|
+
Then /^I am logged in$/ do
|
58
|
+
uiv.login_form.should be_logged_in
|
59
|
+
end
|
60
|
+
|
61
|
+
### 3. test_harness/given/login.rb
|
62
|
+
The **given/** folder holds the objects which performs the setup for the test. It is preferred that
|
63
|
+
you assign a single responsibility for each file to make it easy to follow and understand.
|
64
|
+
|
65
|
+
Notice that the file name is significant in this folder where the file name is used to autoload a class
|
66
|
+
of the camlized format (file_name looks for class FileName)
|
67
|
+
|
68
|
+
#### Mental Model
|
69
|
+
The **mm** object is visible through out the test components, and is used to hold objects needed during the test. Typically,
|
70
|
+
the **given** drive sets up the database or any other required setup, and assigns needed objects into the Mental Model **mm**
|
71
|
+
object. Since the **mm** object is an OpenStruct, you can freely add any new attributes by simply assigning them values.
|
72
|
+
(e.g., mm.whatever = WhatEver.create 'somethng', 'or', 'another')
|
73
|
+
|
74
|
+
The **mm.subject** is a special attribute of the Mental Model (**mm**). It's attribute (e.g., _id_) are used to
|
75
|
+
build the (url's) path of the component under test. You can assign
|
76
|
+
|
77
|
+
class TestHarness
|
78
|
+
class Given
|
79
|
+
module Login
|
80
|
+
def a_user
|
81
|
+
mm.subject = User.create("my@email.com", "password")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
### 4. test_harness/ui/login_form.rb
|
88
|
+
The UI drivers are used to communicate with the browser. The UID (UI Driver) is used for driving the browser
|
89
|
+
(*Do the clicking*) and the UIV (UI View) driver does the inspection (*Do the looking*). This separation of
|
90
|
+
responsibilities makes it easier to figure out where to expect code.
|
91
|
+
|
92
|
+
Notice that the file name is significant in this folder where the file name is used to autoload a class
|
93
|
+
of the camlized format (file_name looks for class FileName). The filename is further used in the step
|
94
|
+
definition file to refer to this component under test.
|
95
|
+
|
96
|
+
Ideally, a single web page could be divided into multiple UI components. For example, on a login page, there
|
97
|
+
is a form which could be a single component, and there could be a header which could be a separate component, and
|
98
|
+
a footer would be a separate component.
|
99
|
+
|
100
|
+
#### I. component block
|
101
|
+
This block allows you to group constants, procs, and whatever else you might need for testing this component. You
|
102
|
+
can assign any attributes to the component block which will be available in the UIDriver and UIView classes below.
|
103
|
+
|
104
|
+
The **path, within** attributes are special:
|
105
|
+
|
106
|
+
1. **path**: is used by the uid#show method to automatically show that path. You can have symbols within this string,
|
107
|
+
e.g., c.path = "/application/:group/:id". The :group and :id symbols will be replaced from the special **mm.subject**
|
108
|
+
object, and hence, the **mm.subject** must respond to mm.subject.id, and mm.subject.group.
|
109
|
+
|
110
|
+
2. **within**: is used to limit the search for any CSS elements to the children of this css identifier.
|
111
|
+
|
112
|
+
#### II. UIView block
|
113
|
+
UIView objects **Do the looking**. Use this block to define methods used by the **uiv** object in the step definitions. These typically
|
114
|
+
respond with a true/false for a **should** assertion (e.g., uiv.login_form.should be_logged_in, will corropsond to method
|
115
|
+
UIView#logged_in? in the ui/login_form.rb)
|
116
|
+
|
117
|
+
#### III. UIDriver block
|
118
|
+
UIDriver objects **Do the clicking**. Use this block to define methods used by the **uid** object in the step definitions. These typically are verbs
|
119
|
+
which perfom actions in the browser.
|
120
|
+
|
121
|
+
require "ui_component"
|
122
|
+
class TestHarness
|
123
|
+
class LoginForm < TestHarness::UIComponent
|
124
|
+
component do |c|
|
125
|
+
c.path = '/login'
|
126
|
+
c.within = 'form'
|
127
|
+
c.username = 'username'
|
128
|
+
c.password = 'password'
|
129
|
+
c.submit = 'input[name=commit]'
|
130
|
+
end
|
131
|
+
|
132
|
+
class UIView
|
133
|
+
def logged_in?
|
134
|
+
browser.current_url == index_url # check truth about being logged in
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
class UIDriver
|
139
|
+
def submit_valid_credentials
|
140
|
+
fill_in component.username, :with => mm.subject.username
|
141
|
+
fill_in component.password, :with => mm.subject.password
|
142
|
+
submit
|
143
|
+
end
|
144
|
+
|
145
|
+
def submit
|
146
|
+
find(:css, component.submit).click
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
## Cucumber Setup
|
154
|
+
In the **feature/support/setup_test_harness.rb**
|
155
|
+
|
156
|
+
require 'thwait'
|
157
|
+
require 'test_harness'
|
158
|
+
require 'spec/factories' # if you use factories
|
159
|
+
|
160
|
+
** autoload_path**: Allows you to set the path where test_harness files are found. Putting them in the
|
161
|
+
Rails.root/app folder proves problematic as they get autoloaded in production. However, depending on how
|
162
|
+
you setup you Gemfile, the test-harness gem might be excluded, and the server will fail to load.
|
163
|
+
|
164
|
+
TestHarness.configure do |c|
|
165
|
+
c.browser = Capybara
|
166
|
+
c.autoload_path = Rails.root.join('test_harness')
|
167
|
+
end
|
168
|
+
|
169
|
+
World(TestHarness::TestHelper)
|
170
|
+
|
171
|
+
Capybara.server_port = 33399
|
172
|
+
Capybara.run_server = false
|
173
|
+
Capybara.default_host = 'http://localhost'
|
174
|
+
|
175
|
+
# This is supposed to allow Selenium to wait until ajax requests are finished
|
176
|
+
Before do
|
177
|
+
page.driver.options[:resynchronize] = true
|
178
|
+
end
|
179
|
+
|
180
|
+
@rack_server_pid = fork do
|
181
|
+
Capybara::Server.new(Hummingbird::Application).boot
|
182
|
+
ThreadsWait.all_waits(Thread.list)
|
183
|
+
end
|
184
|
+
|
185
|
+
at_exit do
|
186
|
+
Process.kill(9, @rack_server_pid)
|
187
|
+
Process.wait
|
188
|
+
end
|
189
|
+
|
190
|
+
## Contributing to test_harness
|
191
|
+
|
192
|
+
|
193
|
+
Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
194
|
+
Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
195
|
+
Fork the project.
|
196
|
+
Start a feature/bugfix branch.
|
197
|
+
Commit and push until you are happy with your contribution.
|
198
|
+
Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
199
|
+
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
200
|
+
|
201
|
+
## Copyright
|
202
|
+
|
203
|
+
Copyright (c) 2012 Maher Hawash. See LICENSE.txt for
|
204
|
+
further details.
|
205
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.4
|
data/test-harness.gemspec
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "test-harness"
|
8
|
-
s.version = "0.4.
|
8
|
+
s.version = "0.4.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Maher Hawash"]
|
12
|
-
s.date = "2012-08
|
12
|
+
s.date = "2012-09-08"
|
13
13
|
s.description = "A test harness for rspec and cucumber which allows for separating responsibility between setting up the context and interacting with the browser, and cleaning up the step definition files."
|
14
14
|
s.email = "gmhawash@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
"README.
|
17
|
+
"README.markdown"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |s|
|
|
22
22
|
"Gemfile",
|
23
23
|
"Gemfile.lock",
|
24
24
|
"LICENSE.txt",
|
25
|
-
"README.
|
25
|
+
"README.markdown",
|
26
26
|
"Rakefile",
|
27
27
|
"VERSION",
|
28
28
|
"lib/configuration.rb",
|
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
|
|
42
42
|
s.homepage = "http://github.com/gmhawash/test_harness"
|
43
43
|
s.licenses = ["MIT"]
|
44
44
|
s.require_paths = ["lib"]
|
45
|
-
s.rubygems_version = "1.8.
|
45
|
+
s.rubygems_version = "1.8.15"
|
46
46
|
s.summary = "Mini test harness for rspec and cucumber"
|
47
47
|
|
48
48
|
if s.respond_to? :specification_version then
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: test-harness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 4
|
9
|
-
-
|
10
|
-
version: 0.4.
|
9
|
+
- 4
|
10
|
+
version: 0.4.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Maher Hawash
|
@@ -15,11 +15,10 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-08
|
18
|
+
date: 2012-09-08 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
|
-
|
22
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
23
22
|
none: false
|
24
23
|
requirements:
|
25
24
|
- - ">="
|
@@ -28,12 +27,12 @@ dependencies:
|
|
28
27
|
segments:
|
29
28
|
- 0
|
30
29
|
version: "0"
|
30
|
+
prerelease: false
|
31
|
+
requirement: *id001
|
31
32
|
type: :development
|
32
33
|
name: rspec
|
33
|
-
version_requirements: *id001
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
-
|
36
|
-
requirement: &id002 !ruby/object:Gem::Requirement
|
35
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
37
36
|
none: false
|
38
37
|
requirements:
|
39
38
|
- - ">="
|
@@ -42,12 +41,12 @@ dependencies:
|
|
42
41
|
segments:
|
43
42
|
- 0
|
44
43
|
version: "0"
|
44
|
+
prerelease: false
|
45
|
+
requirement: *id002
|
45
46
|
type: :development
|
46
47
|
name: rdoc
|
47
|
-
version_requirements: *id002
|
48
48
|
- !ruby/object:Gem::Dependency
|
49
|
-
|
50
|
-
requirement: &id003 !ruby/object:Gem::Requirement
|
49
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
51
50
|
none: false
|
52
51
|
requirements:
|
53
52
|
- - ">="
|
@@ -56,12 +55,12 @@ dependencies:
|
|
56
55
|
segments:
|
57
56
|
- 0
|
58
57
|
version: "0"
|
58
|
+
prerelease: false
|
59
|
+
requirement: *id003
|
59
60
|
type: :development
|
60
61
|
name: bundler
|
61
|
-
version_requirements: *id003
|
62
62
|
- !ruby/object:Gem::Dependency
|
63
|
-
|
64
|
-
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
65
64
|
none: false
|
66
65
|
requirements:
|
67
66
|
- - ">="
|
@@ -70,12 +69,12 @@ dependencies:
|
|
70
69
|
segments:
|
71
70
|
- 0
|
72
71
|
version: "0"
|
72
|
+
prerelease: false
|
73
|
+
requirement: *id004
|
73
74
|
type: :development
|
74
75
|
name: jeweler
|
75
|
-
version_requirements: *id004
|
76
76
|
- !ruby/object:Gem::Dependency
|
77
|
-
|
78
|
-
requirement: &id005 !ruby/object:Gem::Requirement
|
77
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
79
78
|
none: false
|
80
79
|
requirements:
|
81
80
|
- - ">="
|
@@ -84,9 +83,10 @@ dependencies:
|
|
84
83
|
segments:
|
85
84
|
- 0
|
86
85
|
version: "0"
|
86
|
+
prerelease: false
|
87
|
+
requirement: *id005
|
87
88
|
type: :development
|
88
89
|
name: gemcutter
|
89
|
-
version_requirements: *id005
|
90
90
|
description: A test harness for rspec and cucumber which allows for separating responsibility between setting up the context and interacting with the browser, and cleaning up the step definition files.
|
91
91
|
email: gmhawash@gmail.com
|
92
92
|
executables: []
|
@@ -95,14 +95,14 @@ extensions: []
|
|
95
95
|
|
96
96
|
extra_rdoc_files:
|
97
97
|
- LICENSE.txt
|
98
|
-
- README.
|
98
|
+
- README.markdown
|
99
99
|
files:
|
100
100
|
- .document
|
101
101
|
- .rspec
|
102
102
|
- Gemfile
|
103
103
|
- Gemfile.lock
|
104
104
|
- LICENSE.txt
|
105
|
-
- README.
|
105
|
+
- README.markdown
|
106
106
|
- Rakefile
|
107
107
|
- VERSION
|
108
108
|
- lib/configuration.rb
|
@@ -147,7 +147,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
147
147
|
requirements: []
|
148
148
|
|
149
149
|
rubyforge_project:
|
150
|
-
rubygems_version: 1.8.
|
150
|
+
rubygems_version: 1.8.15
|
151
151
|
signing_key:
|
152
152
|
specification_version: 3
|
153
153
|
summary: Mini test harness for rspec and cucumber
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= test_harness
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Contributing to test_harness
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
-
* Fork the project.
|
10
|
-
* Start a feature/bugfix branch.
|
11
|
-
* Commit and push until you are happy with your contribution.
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2012 Maher Hawash. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|