Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 295 lines (214 sloc) 8.74 kb
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
1 ---
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
2 title: Testing with Sinatra
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
3 layout: default
8c053f5 Ryan Tomayko Minor spelling edits
rtomayko authored
4 id: testing
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
5 ---
6
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
7 Testing with Sinatra
8 ====================
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
9
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
10 Sinatra includes utility classes and modules to assist in testing
11 applications. The utilities are based heavily on Rack's
12 [`MockRequest`][Rack::MockRequest] and [`MockResponse`][Rack::MockResponse]
13 objects — a basic understanding of these classes are highly
14 recommended.
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
15
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
16 All examples in the following sections assume that `Test::Unit` is being
17 used in an attempt to be as general as possible. See the [Test Framework
18 Examples](#frameworks) for information on using Sinatra's test helpers in
19 other testing environments.
20
21 *NOTE:* There are plenty of apps [in the wild][wild] that are using other
22 testing frameworks.
23
24 Example App: `hello_world.rb`
25 -----------------------------
26
27 The following example app is used to illustrate testing features. This is
28 assumed to be in a file named `hello_world.rb`:
29
30 require 'sinatra'
31
32 get '/' do
f465dd7 Simon Rozet Fix hello world test example
sr authored
33 "Hello World #{params[:name]}".strip
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
34 end
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
35
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
36 Using The `Sinatra::Test` Mixin
37 -------------------------------
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
38
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
39 The `Sinatra::Test` module includes a variety of helper methods for
40 simulating requests against an application and asserting expectations about
41 the response. It's typically included directly within the test context and
42 makes a slew of helper methods and attributes available.
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
43
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
44 The following is a simple example that ensures the hello world app functions
45 properly:
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
46
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
47 require 'hello_world'
48 require 'test/unit'
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
49 require 'sinatra/test'
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
50
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
51 set :environment, :test
52
53 class HelloWorldTest < Test::Unit::TestCase
54 include Sinatra::Test
55
56 def test_it_says_hello_world
57 get '/'
58 assert response.ok?
59 assert_equal 'Hello World', response.body
60 end
61
62 def test_it_says_hello_to_a_person
63 get '/', :name => 'Simon'
f465dd7 Simon Rozet Fix hello world test example
sr authored
64 assert response.body.include?('Simon')
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
65 end
66 end
67
68 ### Sinatra::Test's Mock Request Methods
69
70 The `get`, `put`, `post`, `delete`, and `head` methods simulate the
71 respective type of request on the application. Tests typically begin with
72 a call to one of these methods followed by one or more assertions against
73 the resulting response.
74
75 All mock request methods have the same argument signature:
76
77 get '/path', params={}, rack_env={}
78
79 * `/path` is the request path and may optionally include a query string.
80
81 * `params` is a Hash of query/post parameters, a String request body, or
82 `nil`.
83
84 * `rack_env` is a Hash of Rack environment values. This can be used to
85 set request headers and other request related information, such as session
86 data. See the [Rack SPEC][spec] for more information on possible key/values.
87
88 ### Asserting Expectations About The Response
89
90 Once a request method has been invoked, the following attributes are
91 available for making assertions:
92
93 * `app` - The Sinatra application class that handled the mock request.
94
95 * `request` - The [`Rack::MockRequest`][Rack::MockRequest] used to generate
96 the request.
97
98 * `response` - A [`Rack::MockResponse`][Rack::MockResponse] instance with
99 information on the response generated by the application.
100
101 Assertions are typically made against the `response` object. Because this is
102 so often the case, the `Sinatra::Test` module forwards missing methods
103 directly to the `response` object, making assertions against the response
104 especially terse. Consider the following examples:
105
106 def test_it_says_hello_world
107 get '/'
108 assert response.ok?
109 assert_equal 'Hello World'.length.to_s, response.header['Content-Length']
110 assert_equal 'Hello World', response.body
111 end
112
113 And with the `response` references removed:
114
115 def test_it_says_hello_world
116 get '/'
117 assert ok?
118 assert_equal 'Hello World'.length.to_s, header['Content-Length']
119 assert_equal 'Hello World', body
120 end
121
122 ### Optional Test Setup
123
124 The `Sinatra::Test` mock request methods send requests to `@app`. If no
125 `@app` variable is set, the `Sinatra::Application` class (this is the
126 default application defined at the top-level) is assumed to be the target of
127 requests.
128
129 If you're testing a modular application that has multiple `Sinatra::Base`
130 subclasses, simply set the `@app` instance variable in the test's `setup`
131 method or before calling a mock request method:
132
133 def setup
134 @app = MySinatraApp
135 end
136
137 ### Making `Sinatra::Test` available to all test cases
138
139 If you'd like the `Sinatra::Test` methods to be available to all test cases
140 without having to include it each time, you can include the `Sinatra::Test`
141 module in the `Test::Unit::TestCase` class:
142
143 require 'test/unit'
144 require 'sinatra/test'
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
145
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
146 class Test::Unit::TestCase
147 include Sinatra::Test
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
148 end
149
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
150 Now all `TestCase` subclasses will automatically have `Sinatra::Test`
151 available to them.
152
153 Using `Sinatra::TestHarness`
154 ----------------------------
155
156 The `Sinatra::TestHarness` class works exactly like the `Sinatra::Test`
157 module but moves all mock request methods and the request/response objects
158 into a separate context so they're clearly separated from your test context.
159 Although slightly more verbose, some feel this separation results in tests
160 that are easier to understand and maintain.
161
162 require 'hello_world'
163 require 'test/unit'
164 require 'sinatra/test'
165
166 set :environment, :test
167
168 class HelloWorldTest < Test::Unit::TestCase
169 def setup
170 @client = Sinatra::TestHarness.new(Sinatra::Application)
171 end
172
173 def test_it_says_hello_world
174 response = @client.get('/')
175 assert response.ok?
176 assert_equal 'Hello World'.length.to_s, response.header['Content-Length']
177 assert_equal 'Hello World', response.body
178 end
179
180 ...
181 end
182
183 Test Framework Examples {#frameworks}
184 -----------------------
185
186 As of version `0.9.1`, Sinatra no longer provides testing framework-specific
187 helpers. Those found in `sinatra/test/*.rb` are deprecated and will be
188 removed in Sinatra `1.0`.
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
189
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
190 ### [RSpec][]
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
191
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
192 Sinatra can be tested under RSpec using the `spec/interop` library. The
193 `Sinatra::Test` module should be included within the `describe` block:
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
194
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
195 require 'hello_world' # <-- your sinatra app
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
196 require 'spec'
197 require 'spec/interop/test'
198 require 'sinatra/test'
199
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
200 set :environment, :test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
201
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
202 describe 'The HelloWorld App' do
203 include Sinatra::Test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
204
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
205 it "says hello" do
206 get '/'
207 response.should be_ok
208 response.body.should == 'Hello World'
209 end
210 end
211
212 Make `Sinatra::Test` available to all spec contexts by including it in
213 `Test::Unit::TestCase`:
214
215 require 'spec'
216 require 'spec/interop/test'
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
217 require 'sinatra/test'
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
218
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
219 Test::Unit::TestCase.send :include, Sinatra::Test
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
220
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
221 ### [Bacon][]
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
222
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
223 Testing with Bacon is similar to `test/unit` and RSpec:
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
224
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
225 require 'hello_world' # <-- your sinatra app
226 require 'bacon'
227 require 'sinatra/test'
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
228
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
229 set :environment, :test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
230
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
231 describe 'The HelloWorld App' do
232 include Sinatra::Test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
233
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
234 it "says hello" do
235 get '/'
236 response.should.be.ok
237 response.body.should.equal 'Hello World'
238 end
239 end
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
240
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
241 Make `Sinatra::Test` available to all spec contexts by including it in
242 `Bacon::Context`:
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
243
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
244 class Bacon::Context
245 include Sinatra::Test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
246 end
247
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
248 ### [Test::Spec][]
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
249
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
250 The `Sinatra::Test` module should be included within the context of the
251 `describe` block:
252
253 require 'hello_world' # <-- your sinatra app
254 require 'test/spec'
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
255 require 'sinatra/test'
256
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
257 set :environment, :test
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
258
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
259 describe 'The HelloWorld App' do
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
260 include Sinatra::Test
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
261
262 it "says hello" do
263 get '/'
264 response.should.be.ok
265 response.body.should.equal 'Hello World'
266 end
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
267 end
268
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
269 Make `Sinatra::Test` available to all spec contexts by including it in
270 `Test::Unit::TestCase`:
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
271
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
272 require 'test/spec'
273 require 'sinatra/test'
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
274
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
275 Test::Unit::TestCase.send :include, Sinatra::Test
276
277 <!-- TODO: Webrat -->
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
278
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
279 See Also
280 --------
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
281
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
282 See the source for [Sinatra::Test][] and the [accompanying specs][test] for
283 more information on `get`, `post`, `put`, `delete` and friends.
78cbc0e Kevin Fullerton Bootstrapping of changes to doc for testing
dashdotat authored
284
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
285 [Test::Unit]: http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html
286 [RSpec]: http://rspec.info
287 [Bacon]: http://github.com/chneukirchen/bacon
288 [Test::Spec]: http://rubyforge.org/projects/test-spec/
d3daf22 Simon Rozet Looks like one can't link to HEAD blob anymore
sr authored
289 [Sinatra::Test]: http://github.com/sinatra/sinatra/blob/987d622a52f3eaf28f8f6beb7451c3e43c23f075/test/test_test.rb
a0578cf Simon Rozet Actually, we can. Thanks raggi :-)
sr authored
290 [test]: http://github.com/sinatra/sinatra/blob/master/test/test_test.rb
4043048 Simon Rozet Explain how to install and use Sinatra::Test
sr authored
291 [wild]: /wild.html
11372f2 Ryan Tomayko Finish up test doc for now [#123]
rtomayko authored
292 [spec]: http://rack.rubyforge.org/doc/files/SPEC.html
293 [Rack::MockRequest]: http://rack.rubyforge.org/doc/classes/Rack/MockRequest.html
294 [Rack::MockResponse]: http://rack.rubyforge.org/doc/classes/Rack/MockResponse.html
Something went wrong with that request. Please try again.