itesttool
itesttool is Web API end-to-end test tool in RSpec.
describe 'send GET request' do
_given {
headers 'referer' => 'http://local.example.com'
}
_when { get 'http://localhost:4567/index', as_json }
_then {
res.code.should eq '200'
res.body.should eq_schema_of 'json_schema/hello.json'
res['$.members..name'].should eq ['Ichiro', 'Jiro', 'Saburo']
}
end
Installation
Add this line to your application's Gemfile
gem 'itesttool'
And then execute
$ bundle install --path vendor/bundle
Usage
Require itesttool
require 'itesttool'
GET request
-
_given
is setup phase._given
is alias ofbefore
in RSpec. -
_when
is execution phase. it send HTTP request to server. -
_then
is assertion phase. in_then
block, HTTP response is setres
.res
is instance of Net::HTTPResponse.
describe 'send GET request' do
_given {
headers 'referer' => 'http://local.example.com'
}
_when { get 'http://localhost:4567/index' }
_then {
res.code.should eq '200'
}
end
assert HTTP response
assert status code:
res.code.should eq '200'
assert response body:
res.body.should eq 'Hello world!'
If respons body is the JSON, XML, HTML, you can assert an element using JSONPath, XPath, CSS Selectors.
About JSONPath and XPath, please refer to the site: http://goessner.net/articles/JsonPath/
For assert to the array, itesttool defines custom matchers.
all
be_one_and
be_sorted
[2, 3].should all be > 1 # same next code: [2, 3].each do |x| x.should be > 1 end
[2].should be_one_and be > 1 # success
[2, 3].should be_one_and be > 1 # failure
[1, 2, 3].should be_sorted :asc # success
[1, 2, 3].should be_sorted :desc # failure
[3, 2, 1].should be_sorted :desc # success
JSON
with JSONPath:
res['$.team'].should eq ['ABC']
res['$.members..name'].should eq ['Ichiro', 'Jiro', 'Saburo']
res['$.members..age'].should include 32
res['$.members[::]'].should have(3).items
res['$.members[::]'].should have_at_most(3).items
res['$.members[::]'].should have_at_least(1).items
res['$.members..name'].should all be_kind_of String
res['$.members..age'].should all be_kind_of Integer
res['$.members..age'].should all be > 11
res['$.members..age'].should all be >= 12
res['$.members..age'].should all be < 33
res['$.members..age'].should all be <= 32
res['$.members..age'].should be_sorted :desc
with select
helper method:
res.select('$.members..age') do |ages|
ages.should all be_kind_of Integer
ages.should all be > 11
ages.should all be >= 12
ages.should all be < 33
ages.should all be <= 32
ages.should be_sorted :desc
end
you can assert with the JSON Schema.
res.body.should eq_schema_of 'json_schema/hello.json'
json_schema/hello.js is JSON schema sample.
{
"type": "object",
"properties": {
"team": {"type": "string", "required": true},
"members": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string", "required": true},
"age": {"type": "integer", "required": true}
}
}
}
}
}
XML
with XPath:
res['/root/team/text()'].should eq ['ABC']
res['/root/members//name/text()'].should eq ['Ichiro', 'Jiro', 'Saburo']
res['/root/members//age/text()'].should include '32'
res['/root/members/*'].should have(3).items
res['/root/members/*'].should have_at_most(3).items
res['/root/members/*'].should have_at_least(1).items
res['/root/members//age/text()'].should all be > "11"
res.select('/root/members//age/text()') do |ages|
ages.should all be >= "10"
ages.should all be < "33"
ages.should all be <= "32"
ages.should be_sorted :desc
end
res['/root/members/member/@order'].should be_sorted :asc
HTML
with CSS Selector:
res['title'].should eq ['Page Title!']
res['h1#team'].should eq ['ABC']
res['.member dd.name'].should eq ['Ichiro', 'Jiro', 'Saburo']
res['.member dd.age'].should include '32'
res['.member'].should have(3).items
res['.member'].should have_at_most(3).items
res['.member'].should have_at_least(1).items
res['.member dd.age'].should all be > "11"
res.select('.member dd.age') do |ages|
ages.should all be >= 10
ages.should all be < 33
ages.should all be <= 32
ages.should be_sorted :desc
end
query parameter
_when { get 'http://localhost:4567/index?night=true', as_text }
_then {
res.code.should eq '200'
}
with query
helper function:
_when {
get 'http://localhost:4567/index',
as_text,
query('night' => 'true',
'times' => 3)
}
_then {
res.code.should eq '200'
}
HTTP request header
_given {
headers 'referer' => 'http://local.example.com',
'user_agent' => 'itesttool'
}
_when { get 'http://localhost:4567/index.html', as_html }
_then {
res.code.should eq '200'
}
POST request
_when {
post 'http://localhost:4567/login',
}
application/x-www-form-urlencoded
use body_as_form
:
_when {
post 'http://localhost:4567/login',
body_as_form('nickname' => 'admin',
'password' => 'pass'),
res_is_json
}
_then {
res.code.should eq '200'
res['$.nickname'].should eq ['admin']
}
application/json
use body_as_json
:
_when {
post 'http://localhost:4567/echo',
body_as_json('name' => 'Shiro',
'age' => 2),
res_is_json
}
_then {
res.code.should eq '200'
res.body.should eq '{"name":"Shiro","age":2}'
}
use string:
_when {
post 'http://localhost:4567/echo',
body('{"name":"Shiro","age":2}'),
res_is_json
}
_then {
res.code.should eq '200'
res.body.should eq '{"name":"Shiro","age":2}'
}
PUT, DELETE request
same as a post
. instead of use put
, or delete
.
License
The MIT License. See LICENSE.txt