spassky 0.1.32 → 0.1.33
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +4 -1
- data/Rakefile +1 -0
- data/bin/spassky +1 -1
- data/features/device_timeout.feature +1 -3
- data/features/list_devices.feature +1 -7
- data/features/run_html_tests.feature +4 -4
- data/features/run_qunit_tests.feature +4 -4
- data/features/server.feature +2 -2
- data/features/step_definitions/steps.rb +14 -2
- data/features/summary.feature +37 -0
- data/lib/spassky/client/cli.rb +27 -8
- data/lib/spassky/client/test_runner.rb +5 -0
- data/lib/spassky/server/device_database.rb +2 -1
- data/lib/spassky/test_result.rb +3 -23
- data/lib/spassky/test_result_summariser.rb +22 -0
- data/lib/spassky/version.rb +1 -1
- data/spassky.gemspec +2 -0
- data/spassky.jpg +0 -0
- data/spec/spassky/client/cli_spec.rb +57 -29
- data/spec/spassky/client/test_runner_spec.rb +16 -0
- data/spec/spassky/test_result_spec.rb +6 -29
- data/spec/spassky/test_result_summariser_spec.rb +41 -0
- metadata +53 -30
- data/Gemfile.lock +0 -94
- data/bin/spassky-server +0 -14
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# Spassky #
|
2
2
|
A distributed web testing tool. We use it at the BBC for testing our web apps on a wide range of mobile devices.
|
3
3
|
|
4
|
+
|
5
|
+
![Spassky](https://github.com/BBC/spassky/raw/master/spassky.jpg)
|
6
|
+
|
4
7
|
# Installation #
|
5
8
|
|
6
9
|
```
|
@@ -47,4 +50,4 @@ Physical devices act as test agents, connected permanently to a central server u
|
|
47
50
|
## Some features that would be nice to have ##
|
48
51
|
- Conveniently run QUnit / Jasmine / other tests
|
49
52
|
- Run tests on a subset of agents
|
50
|
-
- Assertions on network activity (e.g. for caching tests)
|
53
|
+
- Assertions on network activity (e.g. for caching tests)
|
data/Rakefile
CHANGED
data/bin/spassky
CHANGED
@@ -21,11 +21,9 @@ Feature: Device Timeout
|
|
21
21
|
Scenario: One device times out
|
22
22
|
Given a connected mobile device "ipad"
|
23
23
|
When the device disconnects
|
24
|
-
And I run "spassky
|
24
|
+
And I run "spassky run timed-out.html <host>" with the server host
|
25
25
|
Then the output should contain:
|
26
26
|
"""
|
27
27
|
TIMED OUT timed-out.html on ipad
|
28
28
|
"""
|
29
29
|
And the exit status should be 2
|
30
|
-
|
31
|
-
|
@@ -7,15 +7,9 @@ Feature: List Connected Devices
|
|
7
7
|
Given a Wireless Universal Resource FiLe
|
8
8
|
And a connected mobile device "Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3"
|
9
9
|
And a connected mobile device "Mozilla/5.0(iPad; U; CPU iPhone OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B314 Safari/531.21.10"
|
10
|
-
When I run "spassky <host>
|
10
|
+
When I run "spassky devices <host>" with the server host
|
11
11
|
Then the output should contain:
|
12
12
|
"""
|
13
13
|
iPhone (id = apple_iphone_ver1_suba543, mobile_browser = Safari, device_os_version = 1.0)
|
14
14
|
iPad (id = apple_ipad_ver1_sub5312110, mobile_browser = Safari, device_os_version = 3.2)
|
15
15
|
"""
|
16
|
-
|
17
|
-
#:id => "apple_iphone_ver1_suba543",
|
18
|
-
#:mobile_browser => "Safari",
|
19
|
-
#:pointing_method => "touchscreen",
|
20
|
-
#:model_name => "iPhone",
|
21
|
-
#:device_os_version => "1.0",
|
@@ -34,7 +34,7 @@ Feature: Run HTML Tests
|
|
34
34
|
|
35
35
|
Scenario: No connected devices
|
36
36
|
Given I have no connected devices
|
37
|
-
When I run "spassky
|
37
|
+
When I run "spassky run passing.html <host>" with the server host
|
38
38
|
Then the output should contain:
|
39
39
|
"""
|
40
40
|
There are no connected devices
|
@@ -43,7 +43,7 @@ Feature: Run HTML Tests
|
|
43
43
|
|
44
44
|
Scenario: One passing test on one device
|
45
45
|
Given a connected mobile device "blackberry"
|
46
|
-
When I run "spassky
|
46
|
+
When I run "spassky run passing.html <host>" with the server host
|
47
47
|
Then the output should contain:
|
48
48
|
"""
|
49
49
|
PASS passing.html on blackberry
|
@@ -53,7 +53,7 @@ Feature: Run HTML Tests
|
|
53
53
|
Scenario: One passing test on two devices
|
54
54
|
Given a connected mobile device "blackberry"
|
55
55
|
And a connected mobile device "iphone"
|
56
|
-
When I run "spassky
|
56
|
+
When I run "spassky run passing.html <host>" with the server host
|
57
57
|
Then the output should contain:
|
58
58
|
"""
|
59
59
|
PASS passing.html on blackberry
|
@@ -66,7 +66,7 @@ Feature: Run HTML Tests
|
|
66
66
|
|
67
67
|
Scenario: Failing test
|
68
68
|
Given a connected mobile device "blackberry"
|
69
|
-
When I run "spassky
|
69
|
+
When I run "spassky run failing.html <host>" with the server host
|
70
70
|
Then the output should contain:
|
71
71
|
"""
|
72
72
|
FAIL failing.html on blackberry
|
@@ -19,7 +19,7 @@ Feature: Run QUnit Tests
|
|
19
19
|
ok(true, "it passed");
|
20
20
|
});
|
21
21
|
"""
|
22
|
-
And a file named "qunit_passing/qunit_test/qunit.js" with
|
22
|
+
And a file named "qunit_passing/qunit_test/qunit.js" with qunit.js in it
|
23
23
|
And a file named "qunit_passing/qunit_test/suite.html" with:
|
24
24
|
"""
|
25
25
|
<html>
|
@@ -32,7 +32,7 @@ Feature: Run QUnit Tests
|
|
32
32
|
</html>
|
33
33
|
"""
|
34
34
|
And a connected mobile device "blackberry"
|
35
|
-
When I run "spassky
|
35
|
+
When I run "spassky run qunit_passing/qunit_test <host>" with the server host
|
36
36
|
Then the output should contain:
|
37
37
|
"""
|
38
38
|
PASS qunit_test on blackberry
|
@@ -54,7 +54,7 @@ Feature: Run QUnit Tests
|
|
54
54
|
ok(false, "it failed");
|
55
55
|
});
|
56
56
|
"""
|
57
|
-
And a file named "qunit_failing/qunit_test/qunit.js" with
|
57
|
+
And a file named "qunit_failing/qunit_test/qunit.js" with qunit.js in it
|
58
58
|
And a file named "qunit_failing/qunit_test/suite.html" with:
|
59
59
|
"""
|
60
60
|
<html>
|
@@ -67,7 +67,7 @@ Feature: Run QUnit Tests
|
|
67
67
|
</html>
|
68
68
|
"""
|
69
69
|
And a connected mobile device "blackberry"
|
70
|
-
When I run "spassky
|
70
|
+
When I run "spassky run qunit_failing/qunit_test <host>" with the server host
|
71
71
|
Then the output should contain:
|
72
72
|
"""
|
73
73
|
FAIL qunit_test on blackberry
|
data/features/server.feature
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Feature: Server
|
2
2
|
In order to spawn a spassky server
|
3
3
|
As a developer
|
4
|
-
I want to be able to type 'spassky
|
4
|
+
I want to be able to type 'spassky server 9393' to launch a server
|
5
5
|
|
6
6
|
Scenario: Launch Server
|
7
|
-
Given I run spassky
|
7
|
+
Given I run the command "spassky server 9393"
|
8
8
|
Then it should not crash
|
@@ -9,6 +9,18 @@ Given /^a connected mobile device "([^"]*)"$/ do |user_agent|
|
|
9
9
|
@last_user_agent = user_agent
|
10
10
|
end
|
11
11
|
|
12
|
+
Given /^I have two connected devices$/ do
|
13
|
+
1.upto(2) do |device_number|
|
14
|
+
user_agent = "device#{device_number}"
|
15
|
+
register_driver_with_user_agent user_agent
|
16
|
+
using_session(user_agent) do
|
17
|
+
visit '/device/connect'
|
18
|
+
@uri = URI.parse(current_url)
|
19
|
+
end
|
20
|
+
@last_user_agent = user_agent
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
12
24
|
Given /^I have no connected devices$/ do
|
13
25
|
@uri = URI.parse(current_url)
|
14
26
|
end
|
@@ -49,8 +61,8 @@ When /^the device disconnects$/ do
|
|
49
61
|
end
|
50
62
|
end
|
51
63
|
|
52
|
-
Given /^I run spassky
|
53
|
-
@spassky_server_process = ChildProcess.build('./bin/spassky
|
64
|
+
Given /^I run the command "spassky server 9393"$/ do
|
65
|
+
@spassky_server_process = ChildProcess.build('./bin/spassky server 9393')
|
54
66
|
@spassky_server_process.start
|
55
67
|
end
|
56
68
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Feature: Summary
|
2
|
+
In order to gauge the state of the project
|
3
|
+
As a News stakeholder
|
4
|
+
I want to summarised test results aftr a test run
|
5
|
+
|
6
|
+
Background: Two tests, one passes, one fails
|
7
|
+
Given a file named "passing.html" with:
|
8
|
+
"""
|
9
|
+
<html>
|
10
|
+
<head></head>
|
11
|
+
<body>
|
12
|
+
<script type="text/javascript">
|
13
|
+
assert(true, 'this test should pass');
|
14
|
+
</script>
|
15
|
+
</body>
|
16
|
+
</html>
|
17
|
+
"""
|
18
|
+
And a file named "failing.html" with:
|
19
|
+
"""
|
20
|
+
<html>
|
21
|
+
<head></head>
|
22
|
+
<body>
|
23
|
+
<script type="text/javascript">
|
24
|
+
assert(false, 'this test should fail');
|
25
|
+
</script>
|
26
|
+
</body>
|
27
|
+
</html>
|
28
|
+
"""
|
29
|
+
|
30
|
+
Scenario: One test passing on all devices
|
31
|
+
Given I have two connected devices
|
32
|
+
When I run "spassky run passing.html <host>" with the server host
|
33
|
+
Then the output should contain "2 passed"
|
34
|
+
|
35
|
+
#2 passed
|
36
|
+
#2 passed, 1 failed
|
37
|
+
#3 passed, 1 failed, 1 timed out
|
data/lib/spassky/client/cli.rb
CHANGED
@@ -1,19 +1,38 @@
|
|
1
|
+
require 'spassky'
|
2
|
+
require 'spassky/version'
|
3
|
+
require 'spassky/server/app'
|
1
4
|
require 'spassky/client/device_list_retriever'
|
2
5
|
require 'spassky/client/test_runner'
|
3
6
|
require 'spassky/client/pusher'
|
4
7
|
require 'spassky/client/directory_reader'
|
8
|
+
require 'commandable'
|
5
9
|
|
6
10
|
module Spassky::Client
|
7
11
|
class Cli
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
extend Commandable
|
13
|
+
|
14
|
+
DEFAULT_PORT = "9191"
|
15
|
+
DEFAULT_SERVER = "http://localhost:#{DEFAULT_PORT}"
|
16
|
+
|
17
|
+
command "run a test"
|
18
|
+
def run(test, server = DEFAULT_SERVER, colour = false)
|
19
|
+
writer = colour ? ColouredWriter : DefaultWriter
|
20
|
+
pusher = Pusher.new(server)
|
21
|
+
test_runner = TestRunner.new(pusher, writer.new(STDOUT), DirectoryReader.new)
|
22
|
+
test_runner.run_tests(test)
|
23
|
+
end
|
24
|
+
|
25
|
+
command "list devices"
|
26
|
+
def devices(server = DEFAULT_SERVER)
|
27
|
+
Spassky::Client::DeviceListRetriever.new(server).get_connected_devices.each do |device|
|
28
|
+
puts device
|
16
29
|
end
|
17
30
|
end
|
31
|
+
|
32
|
+
command "run the spassky server"
|
33
|
+
def server(port = DEFAULT_PORT)
|
34
|
+
Spassky::Server::App.set :port, port
|
35
|
+
Spassky::Server::App.run!
|
36
|
+
end
|
18
37
|
end
|
19
38
|
end
|
@@ -11,10 +11,15 @@ module Spassky::Client
|
|
11
11
|
def run_tests(pattern)
|
12
12
|
previous_test_result = nil
|
13
13
|
test_name = File.basename(pattern)
|
14
|
+
begin
|
14
15
|
@pusher.push(:name => test_name, :contents => @directory_reader.read_files(pattern).to_json) do |result|
|
15
16
|
handle_test_result(previous_test_result, result)
|
16
17
|
previous_test_result = result
|
17
18
|
end
|
19
|
+
rescue => error
|
20
|
+
@writer.write_failing(error.message)
|
21
|
+
Kernel.exit(1)
|
22
|
+
end
|
18
23
|
end
|
19
24
|
|
20
25
|
def handle_test_result(previous_test_result, test_result)
|
@@ -4,7 +4,7 @@ require "singleton"
|
|
4
4
|
require "fileutils"
|
5
5
|
|
6
6
|
module Spassky::Server
|
7
|
-
LATEST = 'http://
|
7
|
+
LATEST = 'http://sourceforge.net/projects/wurfl/files/WURFL/2.2/wurfl-2.2.xml.gz/download'
|
8
8
|
WURFL_DIRECTORY = File.join(File.dirname(__FILE__), "..", "..", "..", "wurfl")
|
9
9
|
WURFL_FILE = File.join(WURFL_DIRECTORY, "wurfl-latest.xml.gz")
|
10
10
|
|
@@ -20,6 +20,7 @@ module Spassky::Server
|
|
20
20
|
def download_wurfl_file
|
21
21
|
FileUtils.mkdir_p(WURFL_DIRECTORY)
|
22
22
|
Kernel.puts("Downloading WURFL database")
|
23
|
+
RestClient.proxy = ENV["http_proxy"] if ENV["http_proxy"]
|
23
24
|
content = RestClient.get(LATEST)
|
24
25
|
File.open(WURFL_FILE, "w") do |file|
|
25
26
|
file.write(content)
|
data/lib/spassky/test_result.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'spassky/test_result_summariser'
|
1
2
|
require 'json'
|
2
3
|
|
3
4
|
module Spassky
|
@@ -15,14 +16,6 @@ module Spassky
|
|
15
16
|
"pass"
|
16
17
|
end
|
17
18
|
|
18
|
-
def count_fails
|
19
|
-
@device_statuses.count { |s| s.status == "fail" }
|
20
|
-
end
|
21
|
-
|
22
|
-
def count_timeouts
|
23
|
-
@device_statuses.count { |s| s.status == "timed out" }
|
24
|
-
end
|
25
|
-
|
26
19
|
def completed_since(older_test_result)
|
27
20
|
if older_test_result.nil?
|
28
21
|
device_statuses.select { |s| s.completed? }
|
@@ -31,22 +24,9 @@ module Spassky
|
|
31
24
|
end
|
32
25
|
end
|
33
26
|
|
27
|
+
|
34
28
|
def summary
|
35
|
-
|
36
|
-
count = @device_statuses.size
|
37
|
-
if count_timeouts > 0
|
38
|
-
result = "1 test timed out on #{count} device"
|
39
|
-
else
|
40
|
-
status = "passed"
|
41
|
-
fail_count = count_fails
|
42
|
-
if fail_count > 0
|
43
|
-
status = "failed"
|
44
|
-
count = fail_count
|
45
|
-
end
|
46
|
-
result = "1 test #{status} on #{count} device"
|
47
|
-
end
|
48
|
-
result << "s" if @device_statuses.size > 1
|
49
|
-
return result
|
29
|
+
TestResultSummariser.new(@device_statuses).summary
|
50
30
|
end
|
51
31
|
|
52
32
|
def to_json
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Spassky
|
2
|
+
class TestResultSummariser
|
3
|
+
def initialize device_statuses
|
4
|
+
@device_statuses = device_statuses
|
5
|
+
end
|
6
|
+
|
7
|
+
def summary
|
8
|
+
statuses = []
|
9
|
+
passes = status_count "pass"
|
10
|
+
fails = status_count "fail"
|
11
|
+
timeouts = status_count "timed out"
|
12
|
+
statuses << "#{passes} passed" if passes > 0
|
13
|
+
statuses << "#{fails} failed" if fails > 0
|
14
|
+
statuses << "#{timeouts} timed out" if timeouts > 0
|
15
|
+
statuses.join ", "
|
16
|
+
end
|
17
|
+
|
18
|
+
def status_count status
|
19
|
+
@device_statuses.find_all { |device_status| device_status.status == status }.size
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/spassky/version.rb
CHANGED
data/spassky.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_dependency 'sinatra'
|
24
24
|
s.add_dependency 'rainbow'
|
25
25
|
s.add_dependency 'wurfl-lite'
|
26
|
+
s.add_dependency 'commandable'
|
26
27
|
|
27
28
|
s.add_development_dependency 'rake'
|
28
29
|
s.add_development_dependency 'rspec'
|
@@ -30,4 +31,5 @@ Gem::Specification.new do |s|
|
|
30
31
|
s.add_development_dependency 'capybara'
|
31
32
|
s.add_development_dependency 'aruba'
|
32
33
|
s.add_development_dependency 'fakefs'
|
34
|
+
s.add_development_dependency 'ruby-debug19'
|
33
35
|
end
|
data/spassky.jpg
ADDED
Binary file
|
@@ -16,58 +16,86 @@ module Spassky::Client
|
|
16
16
|
TestRunner.stub!(:new).and_return(runner)
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
describe "spassky run" do
|
20
|
+
it "creates a pusher with the server url as the first argument" do
|
21
|
+
Pusher.should_receive(:new).with("server_name").and_return(pusher)
|
22
|
+
TestRunner.should_receive(:new).with(pusher, anything(), anything()).and_return(runner)
|
23
|
+
Cli.new.run "test_name", "server_name"
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
it "runs a single test with the name as the second argument" do
|
27
|
+
runner.should_receive(:run_tests).with("test_name")
|
28
|
+
Cli.new.run "test_name", "server_name"
|
29
|
+
end
|
29
30
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
31
|
+
context "without colour output option" do
|
32
|
+
it "creates a test runner with a default writer" do
|
33
|
+
default_writer = mock :default_writer
|
34
|
+
DefaultWriter.should_receive(:new).with(STDOUT).and_return(default_writer)
|
35
|
+
TestRunner.should_receive(:new).with(anything(), default_writer, anything())
|
36
|
+
Cli.new.run "test_name", "server_name"
|
37
|
+
end
|
36
38
|
end
|
37
|
-
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
context "with colour output option" do
|
41
|
+
it "creates a test runner with a colour writer" do
|
42
|
+
coloured_writer = mock :coloured_writer
|
43
|
+
ColouredWriter.should_receive(:new).with(STDOUT).and_return(coloured_writer)
|
44
|
+
TestRunner.should_receive(:new).with(anything(), coloured_writer, anything())
|
45
|
+
Cli.new.run "test_name", "server_name", "--colour"
|
46
|
+
end
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
|
-
context "
|
50
|
+
context "spassky devices" do
|
49
51
|
it "creates a new device list retriever with the passed in url" do
|
50
52
|
device_list_retriever = mock :device_list_retriever
|
51
53
|
device_list_retriever.stub!(:get_connected_devices).and_return([])
|
52
54
|
DeviceListRetriever.should_receive(:new).with("http://localhost:9000").and_return(device_list_retriever)
|
53
|
-
Cli
|
55
|
+
Cli.new.devices "http://localhost:9000"
|
54
56
|
end
|
55
57
|
|
56
58
|
it "gets a list of devices" do
|
57
59
|
device_list_retriever = mock :device_list_retriever
|
58
60
|
device_list_retriever.should_receive(:get_connected_devices).and_return([])
|
59
61
|
DeviceListRetriever.stub!(:new).and_return(device_list_retriever)
|
60
|
-
Cli
|
62
|
+
Cli.new.devices "http://localhost:9000"
|
61
63
|
end
|
62
64
|
|
63
65
|
it "outputs a list of devices" do
|
64
66
|
device_list_retriever = mock :device_list_retriever
|
65
67
|
device_list_retriever.stub!(:get_connected_devices).and_return(["iphone", "ipad", "nokia"])
|
66
68
|
DeviceListRetriever.stub!(:new).and_return(device_list_retriever)
|
67
|
-
Cli.
|
68
|
-
|
69
|
-
|
70
|
-
|
69
|
+
cli = Cli.new
|
70
|
+
cli.should_receive(:puts).with("iphone")
|
71
|
+
cli.should_receive(:puts).with("ipad")
|
72
|
+
cli.should_receive(:puts).with("nokia")
|
73
|
+
cli.devices "http://localhost:9000"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "spassky server" do
|
78
|
+
before do
|
79
|
+
Spassky::Server::App.stub!(:run!)
|
80
|
+
end
|
81
|
+
|
82
|
+
context "without a port specified" do
|
83
|
+
it "sets the default port" do
|
84
|
+
Spassky::Server::App.should_receive(:set).with(:port, Cli::DEFAULT_PORT)
|
85
|
+
Cli.new.server
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "with a port specified" do
|
90
|
+
it "uses the specified port" do
|
91
|
+
Spassky::Server::App.should_receive(:set).with(:port, 9393)
|
92
|
+
Cli.new.server(9393)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it "launches the server" do
|
97
|
+
Spassky::Server::App.should_receive(:run!)
|
98
|
+
Cli.new.server
|
71
99
|
end
|
72
100
|
end
|
73
101
|
end
|
@@ -81,6 +81,22 @@ module Spassky::Client
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
+
context "server pusher raises exception" do
|
85
|
+
before do
|
86
|
+
@test_pusher.stub!(:push).and_raise("hell")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "writes out the error" do
|
90
|
+
@writer.should_receive(:write_failing).with("hell")
|
91
|
+
@test_runner.run_tests("foo_test")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "exits with an error code" do
|
95
|
+
Kernel.should_receive(:exit).with(1)
|
96
|
+
@test_runner.run_tests("foo_test")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
84
100
|
context "in progress" do
|
85
101
|
it "writes nothing" do
|
86
102
|
@test_pusher.stub!(:push).and_yield(new_in_progress_test_result)
|
@@ -9,13 +9,12 @@ module Spassky
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
12
|
+
it "has a summary" do
|
13
|
+
device_statuses = stub(:device_statuses)
|
14
|
+
test_result_summariser = stub(:test_result_summariser)
|
15
|
+
test_result_summariser.stub!(:summary).and_return("the summary")
|
16
|
+
TestResultSummariser.stub!(:new).with(device_statuses).and_return(test_result_summariser)
|
17
|
+
TestResult.new(device_statuses).summary.should == "the summary"
|
19
18
|
end
|
20
19
|
|
21
20
|
context "when all devices pass" do
|
@@ -25,14 +24,6 @@ module Spassky
|
|
25
24
|
Spassky::DeviceTestStatus.new('agent2', 'pass', 'test')
|
26
25
|
]).status.should == "pass"
|
27
26
|
end
|
28
|
-
|
29
|
-
it "outputs a pluralised summary" do
|
30
|
-
test_result = TestResult.new([
|
31
|
-
Spassky::DeviceTestStatus.new('agent1', 'pass', 'test'),
|
32
|
-
Spassky::DeviceTestStatus.new('agent2', 'pass', 'test')
|
33
|
-
])
|
34
|
-
test_result.summary.should == "1 test passed on 2 devices"
|
35
|
-
end
|
36
27
|
end
|
37
28
|
|
38
29
|
context "when any device fails" do
|
@@ -42,13 +33,6 @@ module Spassky
|
|
42
33
|
Spassky::DeviceTestStatus.new('agent2', 'fail', 'test')
|
43
34
|
]).status.should == "fail"
|
44
35
|
end
|
45
|
-
|
46
|
-
it "outputs a summary" do
|
47
|
-
test_result = TestResult.new([
|
48
|
-
Spassky::DeviceTestStatus.new('agent1', 'fail', 'test')
|
49
|
-
])
|
50
|
-
test_result.summary.should == "1 test failed on 1 device"
|
51
|
-
end
|
52
36
|
end
|
53
37
|
|
54
38
|
context "when any test is still in progress" do
|
@@ -62,13 +46,6 @@ module Spassky
|
|
62
46
|
end
|
63
47
|
|
64
48
|
context "when 1 test times out" do
|
65
|
-
it "outputs the correct summary" do
|
66
|
-
test_result = TestResult.new([
|
67
|
-
Spassky::DeviceTestStatus.new('agent1', 'timed out', 'test')
|
68
|
-
])
|
69
|
-
test_result.summary.should == "1 test timed out on 1 device"
|
70
|
-
end
|
71
|
-
|
72
49
|
it "has the status 'timed out'" do
|
73
50
|
test_result = TestResult.new([
|
74
51
|
Spassky::DeviceTestStatus.new('agent1', 'timed out', 'test'),
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
module Spassky
|
4
|
+
describe TestResultSummariser do
|
5
|
+
it "shows passing tests" do
|
6
|
+
device_statuses = [
|
7
|
+
DeviceTestStatus.new('agent1', 'pass', 'test'),
|
8
|
+
DeviceTestStatus.new('agent2', 'pass', 'test')
|
9
|
+
]
|
10
|
+
TestResultSummariser.new(device_statuses).summary.should == "2 passed"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "shows failing tests" do
|
14
|
+
device_statuses = [
|
15
|
+
DeviceTestStatus.new('agent1', 'fail', 'test'),
|
16
|
+
DeviceTestStatus.new('agent2', 'fail', 'test')
|
17
|
+
]
|
18
|
+
TestResultSummariser.new(device_statuses).summary.should == "2 failed"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "shows timed out tests" do
|
22
|
+
device_statuses = [
|
23
|
+
DeviceTestStatus.new('agent1', 'timed out', 'test'),
|
24
|
+
DeviceTestStatus.new('agent2', 'timed out', 'test')
|
25
|
+
]
|
26
|
+
TestResultSummariser.new(device_statuses).summary.should == "2 timed out"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "shows failed, passed and timed out tests" do
|
30
|
+
device_statuses = [
|
31
|
+
DeviceTestStatus.new('agent1', 'pass', 'test'),
|
32
|
+
DeviceTestStatus.new('agent2', 'pass', 'test'),
|
33
|
+
DeviceTestStatus.new('agent3', 'fail', 'test'),
|
34
|
+
DeviceTestStatus.new('agent4', 'fail', 'test'),
|
35
|
+
DeviceTestStatus.new('agent5', 'timed out', 'test'),
|
36
|
+
DeviceTestStatus.new('agent6', 'timed out', 'test')
|
37
|
+
]
|
38
|
+
TestResultSummariser.new(device_statuses).summary.should == "2 passed, 2 failed, 2 timed out"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spassky
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.33
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,12 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2011-
|
15
|
-
default_executable:
|
14
|
+
date: 2011-09-02 00:00:00.000000000Z
|
16
15
|
dependencies:
|
17
16
|
- !ruby/object:Gem::Dependency
|
18
17
|
name: rest-client
|
19
|
-
requirement: &
|
18
|
+
requirement: &2168560600 !ruby/object:Gem::Requirement
|
20
19
|
none: false
|
21
20
|
requirements:
|
22
21
|
- - ! '>='
|
@@ -24,10 +23,10 @@ dependencies:
|
|
24
23
|
version: '0'
|
25
24
|
type: :runtime
|
26
25
|
prerelease: false
|
27
|
-
version_requirements: *
|
26
|
+
version_requirements: *2168560600
|
28
27
|
- !ruby/object:Gem::Dependency
|
29
28
|
name: json
|
30
|
-
requirement: &
|
29
|
+
requirement: &2168560040 !ruby/object:Gem::Requirement
|
31
30
|
none: false
|
32
31
|
requirements:
|
33
32
|
- - ! '>='
|
@@ -35,10 +34,10 @@ dependencies:
|
|
35
34
|
version: '0'
|
36
35
|
type: :runtime
|
37
36
|
prerelease: false
|
38
|
-
version_requirements: *
|
37
|
+
version_requirements: *2168560040
|
39
38
|
- !ruby/object:Gem::Dependency
|
40
39
|
name: sinatra
|
41
|
-
requirement: &
|
40
|
+
requirement: &2168559360 !ruby/object:Gem::Requirement
|
42
41
|
none: false
|
43
42
|
requirements:
|
44
43
|
- - ! '>='
|
@@ -46,10 +45,10 @@ dependencies:
|
|
46
45
|
version: '0'
|
47
46
|
type: :runtime
|
48
47
|
prerelease: false
|
49
|
-
version_requirements: *
|
48
|
+
version_requirements: *2168559360
|
50
49
|
- !ruby/object:Gem::Dependency
|
51
50
|
name: rainbow
|
52
|
-
requirement: &
|
51
|
+
requirement: &2168558800 !ruby/object:Gem::Requirement
|
53
52
|
none: false
|
54
53
|
requirements:
|
55
54
|
- - ! '>='
|
@@ -57,10 +56,10 @@ dependencies:
|
|
57
56
|
version: '0'
|
58
57
|
type: :runtime
|
59
58
|
prerelease: false
|
60
|
-
version_requirements: *
|
59
|
+
version_requirements: *2168558800
|
61
60
|
- !ruby/object:Gem::Dependency
|
62
61
|
name: wurfl-lite
|
63
|
-
requirement: &
|
62
|
+
requirement: &2168558160 !ruby/object:Gem::Requirement
|
64
63
|
none: false
|
65
64
|
requirements:
|
66
65
|
- - ! '>='
|
@@ -68,10 +67,21 @@ dependencies:
|
|
68
67
|
version: '0'
|
69
68
|
type: :runtime
|
70
69
|
prerelease: false
|
71
|
-
version_requirements: *
|
70
|
+
version_requirements: *2168558160
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: commandable
|
73
|
+
requirement: &2168557360 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ! '>='
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: *2168557360
|
72
82
|
- !ruby/object:Gem::Dependency
|
73
83
|
name: rake
|
74
|
-
requirement: &
|
84
|
+
requirement: &2168556680 !ruby/object:Gem::Requirement
|
75
85
|
none: false
|
76
86
|
requirements:
|
77
87
|
- - ! '>='
|
@@ -79,10 +89,10 @@ dependencies:
|
|
79
89
|
version: '0'
|
80
90
|
type: :development
|
81
91
|
prerelease: false
|
82
|
-
version_requirements: *
|
92
|
+
version_requirements: *2168556680
|
83
93
|
- !ruby/object:Gem::Dependency
|
84
94
|
name: rspec
|
85
|
-
requirement: &
|
95
|
+
requirement: &2168556160 !ruby/object:Gem::Requirement
|
86
96
|
none: false
|
87
97
|
requirements:
|
88
98
|
- - ! '>='
|
@@ -90,10 +100,10 @@ dependencies:
|
|
90
100
|
version: '0'
|
91
101
|
type: :development
|
92
102
|
prerelease: false
|
93
|
-
version_requirements: *
|
103
|
+
version_requirements: *2168556160
|
94
104
|
- !ruby/object:Gem::Dependency
|
95
105
|
name: cucumber
|
96
|
-
requirement: &
|
106
|
+
requirement: &2168555260 !ruby/object:Gem::Requirement
|
97
107
|
none: false
|
98
108
|
requirements:
|
99
109
|
- - ! '>='
|
@@ -101,10 +111,10 @@ dependencies:
|
|
101
111
|
version: '0'
|
102
112
|
type: :development
|
103
113
|
prerelease: false
|
104
|
-
version_requirements: *
|
114
|
+
version_requirements: *2168555260
|
105
115
|
- !ruby/object:Gem::Dependency
|
106
116
|
name: capybara
|
107
|
-
requirement: &
|
117
|
+
requirement: &2168554560 !ruby/object:Gem::Requirement
|
108
118
|
none: false
|
109
119
|
requirements:
|
110
120
|
- - ! '>='
|
@@ -112,10 +122,10 @@ dependencies:
|
|
112
122
|
version: '0'
|
113
123
|
type: :development
|
114
124
|
prerelease: false
|
115
|
-
version_requirements: *
|
125
|
+
version_requirements: *2168554560
|
116
126
|
- !ruby/object:Gem::Dependency
|
117
127
|
name: aruba
|
118
|
-
requirement: &
|
128
|
+
requirement: &2168553980 !ruby/object:Gem::Requirement
|
119
129
|
none: false
|
120
130
|
requirements:
|
121
131
|
- - ! '>='
|
@@ -123,10 +133,21 @@ dependencies:
|
|
123
133
|
version: '0'
|
124
134
|
type: :development
|
125
135
|
prerelease: false
|
126
|
-
version_requirements: *
|
136
|
+
version_requirements: *2168553980
|
127
137
|
- !ruby/object:Gem::Dependency
|
128
138
|
name: fakefs
|
129
|
-
requirement: &
|
139
|
+
requirement: &2168553200 !ruby/object:Gem::Requirement
|
140
|
+
none: false
|
141
|
+
requirements:
|
142
|
+
- - ! '>='
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: *2168553200
|
148
|
+
- !ruby/object:Gem::Dependency
|
149
|
+
name: ruby-debug19
|
150
|
+
requirement: &2168552160 !ruby/object:Gem::Requirement
|
130
151
|
none: false
|
131
152
|
requirements:
|
132
153
|
- - ! '>='
|
@@ -134,25 +155,22 @@ dependencies:
|
|
134
155
|
version: '0'
|
135
156
|
type: :development
|
136
157
|
prerelease: false
|
137
|
-
version_requirements: *
|
158
|
+
version_requirements: *2168552160
|
138
159
|
description: ''
|
139
160
|
email:
|
140
161
|
- andrew.vos@gmail.com
|
141
162
|
executables:
|
142
163
|
- spassky
|
143
|
-
- spassky-server
|
144
164
|
extensions: []
|
145
165
|
extra_rdoc_files: []
|
146
166
|
files:
|
147
167
|
- .gitignore
|
148
168
|
- .rvmrc
|
149
169
|
- Gemfile
|
150
|
-
- Gemfile.lock
|
151
170
|
- LICENSE
|
152
171
|
- README.md
|
153
172
|
- Rakefile
|
154
173
|
- bin/spassky
|
155
|
-
- bin/spassky-server
|
156
174
|
- config.ru
|
157
175
|
- examples/qunit-failing/main.js
|
158
176
|
- examples/qunit-failing/qunit.js
|
@@ -167,6 +185,7 @@ files:
|
|
167
185
|
- features/run_qunit_tests.feature
|
168
186
|
- features/server.feature
|
169
187
|
- features/step_definitions/steps.rb
|
188
|
+
- features/summary.feature
|
170
189
|
- features/support/env.rb
|
171
190
|
- features/support/fixtures/qunit.js
|
172
191
|
- lib/spassky.rb
|
@@ -186,8 +205,10 @@ files:
|
|
186
205
|
- lib/spassky/server/random_string_generator.rb
|
187
206
|
- lib/spassky/server/test_run.rb
|
188
207
|
- lib/spassky/test_result.rb
|
208
|
+
- lib/spassky/test_result_summariser.rb
|
189
209
|
- lib/spassky/version.rb
|
190
210
|
- spassky.gemspec
|
211
|
+
- spassky.jpg
|
191
212
|
- spec/spassky/client/cli_spec.rb
|
192
213
|
- spec/spassky/client/device_list_retriever_spec.rb
|
193
214
|
- spec/spassky/client/directory_reader_spec.rb
|
@@ -200,8 +221,8 @@ files:
|
|
200
221
|
- spec/spassky/server/random_string_generator_spec.rb
|
201
222
|
- spec/spassky/server/test_run_spec.rb
|
202
223
|
- spec/spassky/test_result_spec.rb
|
224
|
+
- spec/spassky/test_result_summariser_spec.rb
|
203
225
|
- spec/spec_helper.rb
|
204
|
-
has_rdoc: true
|
205
226
|
homepage: http://github.com/BBC/spassky
|
206
227
|
licenses: []
|
207
228
|
post_install_message:
|
@@ -222,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
243
|
version: '0'
|
223
244
|
requirements: []
|
224
245
|
rubyforge_project: spassky
|
225
|
-
rubygems_version: 1.6
|
246
|
+
rubygems_version: 1.8.6
|
226
247
|
signing_key:
|
227
248
|
specification_version: 3
|
228
249
|
summary: ''
|
@@ -234,6 +255,7 @@ test_files:
|
|
234
255
|
- features/run_qunit_tests.feature
|
235
256
|
- features/server.feature
|
236
257
|
- features/step_definitions/steps.rb
|
258
|
+
- features/summary.feature
|
237
259
|
- features/support/env.rb
|
238
260
|
- features/support/fixtures/qunit.js
|
239
261
|
- spec/spassky/client/cli_spec.rb
|
@@ -248,4 +270,5 @@ test_files:
|
|
248
270
|
- spec/spassky/server/random_string_generator_spec.rb
|
249
271
|
- spec/spassky/server/test_run_spec.rb
|
250
272
|
- spec/spassky/test_result_spec.rb
|
273
|
+
- spec/spassky/test_result_summariser_spec.rb
|
251
274
|
- spec/spec_helper.rb
|
data/Gemfile.lock
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
spassky (0.1.3)
|
5
|
-
json
|
6
|
-
rainbow
|
7
|
-
rest-client
|
8
|
-
sinatra
|
9
|
-
wurfl-lite
|
10
|
-
|
11
|
-
GEM
|
12
|
-
remote: http://rubygems.org/
|
13
|
-
specs:
|
14
|
-
amatch (0.2.7)
|
15
|
-
spruz (~> 0.2)
|
16
|
-
aruba (0.4.3)
|
17
|
-
bcat (>= 0.6.1)
|
18
|
-
childprocess (>= 0.1.9)
|
19
|
-
cucumber (>= 0.10.7)
|
20
|
-
rdiscount (>= 1.6.8)
|
21
|
-
rspec (>= 2.6.0)
|
22
|
-
bcat (0.6.1)
|
23
|
-
rack (~> 1.0)
|
24
|
-
builder (3.0.0)
|
25
|
-
capybara (1.0.0)
|
26
|
-
mime-types (>= 1.16)
|
27
|
-
nokogiri (>= 1.3.3)
|
28
|
-
rack (>= 1.0.0)
|
29
|
-
rack-test (>= 0.5.4)
|
30
|
-
selenium-webdriver (~> 0.2.0)
|
31
|
-
xpath (~> 0.1.4)
|
32
|
-
childprocess (0.1.9)
|
33
|
-
ffi (~> 1.0.6)
|
34
|
-
cucumber (1.0.0)
|
35
|
-
builder (>= 2.1.2)
|
36
|
-
diff-lcs (>= 1.1.2)
|
37
|
-
gherkin (~> 2.4.1)
|
38
|
-
json (>= 1.4.6)
|
39
|
-
term-ansicolor (>= 1.0.5)
|
40
|
-
diff-lcs (1.1.2)
|
41
|
-
fakefs (0.3.2)
|
42
|
-
ffi (1.0.9)
|
43
|
-
gherkin (2.4.5)
|
44
|
-
json (>= 1.4.6)
|
45
|
-
hpricot (0.8.4)
|
46
|
-
json (1.5.3)
|
47
|
-
json_pure (1.5.3)
|
48
|
-
mime-types (1.16)
|
49
|
-
nokogiri (1.5.0)
|
50
|
-
rack (1.3.1)
|
51
|
-
rack-test (0.6.0)
|
52
|
-
rack (>= 1.0)
|
53
|
-
rainbow (1.1.1)
|
54
|
-
rake (0.9.2)
|
55
|
-
rdiscount (1.6.8)
|
56
|
-
rest-client (1.6.1)
|
57
|
-
mime-types (>= 1.16)
|
58
|
-
rspec (2.6.0)
|
59
|
-
rspec-core (~> 2.6.0)
|
60
|
-
rspec-expectations (~> 2.6.0)
|
61
|
-
rspec-mocks (~> 2.6.0)
|
62
|
-
rspec-core (2.6.4)
|
63
|
-
rspec-expectations (2.6.0)
|
64
|
-
diff-lcs (~> 1.1.2)
|
65
|
-
rspec-mocks (2.6.0)
|
66
|
-
rubyzip (0.9.4)
|
67
|
-
selenium-webdriver (0.2.2)
|
68
|
-
childprocess (>= 0.1.9)
|
69
|
-
ffi (>= 1.0.7)
|
70
|
-
json_pure
|
71
|
-
rubyzip
|
72
|
-
sinatra (1.2.6)
|
73
|
-
rack (~> 1.1)
|
74
|
-
tilt (< 2.0, >= 1.2.2)
|
75
|
-
spruz (0.2.13)
|
76
|
-
term-ansicolor (1.0.5)
|
77
|
-
tilt (1.3.2)
|
78
|
-
wurfl-lite (1.1.0)
|
79
|
-
amatch (>= 0.2.5)
|
80
|
-
hpricot (!= 0.8.3, >= 0.8.2)
|
81
|
-
xpath (0.1.4)
|
82
|
-
nokogiri (~> 1.3)
|
83
|
-
|
84
|
-
PLATFORMS
|
85
|
-
ruby
|
86
|
-
|
87
|
-
DEPENDENCIES
|
88
|
-
aruba
|
89
|
-
capybara
|
90
|
-
cucumber
|
91
|
-
fakefs
|
92
|
-
rake
|
93
|
-
rspec
|
94
|
-
spassky!
|
data/bin/spassky-server
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
3
|
-
|
4
|
-
require 'rubygems'
|
5
|
-
require 'spassky'
|
6
|
-
require 'spassky/server/app'
|
7
|
-
|
8
|
-
if ARGV[0] == "--port" || ARGV[0] == "-p"
|
9
|
-
PORT = ARGV[1]
|
10
|
-
end
|
11
|
-
PORT ||= 9191
|
12
|
-
|
13
|
-
Spassky::Server::App.set :port, PORT
|
14
|
-
Spassky::Server::App.run!
|