spassky 0.1.36 → 0.1.37
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +43 -4
- data/lib/spassky/client/cli.rb +3 -3
- data/lib/spassky/client/directory_reader.rb +17 -13
- data/lib/spassky/client/pusher.rb +21 -9
- data/lib/spassky/client/test_suite_runner.rb +62 -0
- data/lib/spassky/device_test_status.rb +9 -0
- data/lib/spassky/server/app.rb +28 -18
- data/lib/spassky/server/device_database.rb +20 -13
- data/lib/spassky/server/device_list.rb +7 -1
- data/lib/spassky/server/test_run.rb +13 -7
- data/lib/spassky/test_suite_result.rb +70 -0
- data/lib/spassky/{test_result_summariser.rb → test_suite_result_summariser.rb} +7 -7
- data/lib/spassky/version.rb +1 -1
- data/spassky.gemspec +0 -1
- data/spec/spassky/client/cli_spec.rb +7 -7
- data/spec/spassky/client/pusher_spec.rb +4 -4
- data/spec/spassky/client/{test_runner_spec.rb → test_suite_runner_spec.rb} +42 -42
- data/spec/spassky/server/app_spec.rb +8 -8
- data/spec/spassky/server/device_database_spec.rb +0 -10
- data/spec/spassky/{test_result_spec.rb → test_suite_result_spec.rb} +19 -19
- data/spec/spassky/{test_result_summariser_spec.rb → test_suite_result_summariser_spec.rb} +5 -5
- metadata +37 -48
- data/lib/spassky/client/test_runner.rb +0 -52
- data/lib/spassky/test_result.rb +0 -76
data/README.md
CHANGED
@@ -1,8 +1,42 @@
|
|
1
1
|
Spassky
|
2
2
|
=======
|
3
|
-
|
3
|
+
Spassky is a test framework that allows us to automate the process of running JavaScript Unit tests on various browsers and devices.
|
4
|
+
It currently supports running tests in QUnit, but in theory, will support any JavaScript framework that the browser supports.
|
5
|
+
|
6
|
+
Spassky was a protagonist in the greatest Chess match of last century - which being played by an American and a Soviet Russian, was a Cold War metaphor. Spassky eventually resigned and Fischer won the championship.
|
7
|
+
|
8
|
+
Architecture
|
9
|
+
------------
|
10
|
+
```
|
11
|
+
+-----+
|
12
|
+
| You |
|
13
|
+
+--+--+
|
14
|
+
|
|
15
|
+
|
|
16
|
+
v
|
17
|
+
+------------------------------------------+
|
18
|
+
| Spassky Central Server |
|
19
|
+
+------------------------------------------+
|
20
|
+
| | |
|
21
|
+
| | |
|
22
|
+
v v v
|
23
|
+
+-------+ +-------+ +-----+
|
24
|
+
|iPhone3| |iPhone4| |Nokia|
|
25
|
+
|-------| |-------| |-----|
|
26
|
+
| | | | | +++ |
|
27
|
+
| | | | | +++ |
|
28
|
+
| + | | + | | +++ |
|
29
|
+
+-------+ +-------+ +-----+
|
30
|
+
```
|
31
|
+
|
32
|
+
|
33
|
+
|
34
|
+
Developers push JS unit tests to the Spassky server through a command line interface.
|
35
|
+
Multiple devices connected to the central Spassky server will poll the server for a suite of tests.
|
36
|
+
The browser will be redirected to the test page, run the tests, and then are redirected to the idle loop.
|
37
|
+
|
38
|
+
|
4
39
|
|
5
|
-
![Spassky](https://github.com/BBC/spassky/raw/master/spassky.jpg)
|
6
40
|
|
7
41
|
Installation
|
8
42
|
------------
|
@@ -11,6 +45,11 @@ Installation
|
|
11
45
|
gem install spassky
|
12
46
|
```
|
13
47
|
|
48
|
+
|
49
|
+
|
50
|
+
![Spassky](https://github.com/BBC/spassky/raw/master/spassky.jpg)
|
51
|
+
|
52
|
+
|
14
53
|
Usage
|
15
54
|
-----
|
16
55
|
|
@@ -20,7 +59,7 @@ Start the server:
|
|
20
59
|
spassky server 9191
|
21
60
|
```
|
22
61
|
|
23
|
-
Connect
|
62
|
+
Connect test devices by browsing to http://localhost:9191/device/connect on the device. The device will stay in an idle meta refresh loop until it receives a test to run.
|
24
63
|
|
25
64
|
Check what devices are connected to the server:
|
26
65
|
|
@@ -52,7 +91,7 @@ We need to run automated tests on a wide range of web-enabled devices with very
|
|
52
91
|
|
53
92
|
How it works
|
54
93
|
------------
|
55
|
-
Physical devices act as test agents, connected permanently to a central server using meta refresh tags. Using a command-line utility, developers execute tests against those browsers by posting to the central server. The tests themselves are plain HTML pages, that are expected to call an assert URL (e.g. by embedding an image) within a time frame.
|
94
|
+
Physical devices act as test agents, connected permanently to a central server using meta refresh tags. Using a command-line utility, developers execute tests against those browsers by posting to the central server. The tests themselves are plain HTML pages, that are expected to call an assert URL (e.g. by embedding an image) within a time frame.
|
56
95
|
|
57
96
|
Test structure
|
58
97
|
--------------
|
data/lib/spassky/client/cli.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spassky'
|
|
2
2
|
require 'spassky/version'
|
3
3
|
require 'spassky/server/app'
|
4
4
|
require 'spassky/client/device_list_retriever'
|
5
|
-
require 'spassky/client/
|
5
|
+
require 'spassky/client/test_suite_runner'
|
6
6
|
require 'spassky/client/pusher'
|
7
7
|
require 'spassky/client/directory_reader'
|
8
8
|
require 'commandable'
|
@@ -18,8 +18,8 @@ module Spassky::Client
|
|
18
18
|
def run(pattern, test, server = DEFAULT_SERVER, colour = false)
|
19
19
|
writer = colour ? ColouredWriter : DefaultWriter
|
20
20
|
pusher = Pusher.new(server)
|
21
|
-
|
22
|
-
|
21
|
+
test_suite_runner = TestSuiteRunner.new(pusher, writer.new(STDOUT), DirectoryReader.new(pattern))
|
22
|
+
test_suite_runner.run_test_suite(pattern, test)
|
23
23
|
end
|
24
24
|
|
25
25
|
command "list devices"
|
@@ -1,31 +1,35 @@
|
|
1
1
|
module Spassky::Client
|
2
2
|
class DirectoryReader
|
3
|
-
|
4
3
|
def initialize(pattern)
|
5
4
|
@pattern = pattern
|
6
5
|
end
|
7
6
|
|
7
|
+
def read_files
|
8
|
+
if File.file? @pattern
|
9
|
+
read_file
|
10
|
+
elsif File.directory? @pattern
|
11
|
+
read_directory
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
8
17
|
def read_directory
|
9
|
-
|
18
|
+
files = {}
|
19
|
+
Dir.glob(@pattern + "/**/*").each do |path|
|
10
20
|
if File.file? path
|
11
|
-
|
12
|
-
hash[key] = File.read(path)
|
21
|
+
files[remove_pattern_from_file(path)] = File.read(path)
|
13
22
|
end
|
14
|
-
hash
|
15
23
|
end
|
24
|
+
files
|
25
|
+
end
|
16
26
|
|
27
|
+
def remove_pattern_from_file path
|
28
|
+
path.gsub(/^#{@pattern}\//, "")
|
17
29
|
end
|
18
30
|
|
19
31
|
def read_file
|
20
32
|
{ @pattern => File.read(@pattern) }
|
21
33
|
end
|
22
|
-
|
23
|
-
def read_files
|
24
|
-
if File.file? @pattern
|
25
|
-
read_file
|
26
|
-
elsif File.directory? @pattern
|
27
|
-
read_directory
|
28
|
-
end
|
29
|
-
end
|
30
34
|
end
|
31
35
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'rest-client'
|
2
|
-
require 'spassky/
|
2
|
+
require 'spassky/test_suite_result'
|
3
3
|
|
4
4
|
module Spassky::Client
|
5
5
|
class Pusher
|
@@ -9,31 +9,43 @@ module Spassky::Client
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def push(options)
|
12
|
-
|
13
|
-
result = nil
|
14
|
-
begin
|
15
|
-
result = Spassky::TestResult.from_json(RestClient.get(location))
|
12
|
+
each_test_suite_result(post_test(options)) do |result|
|
16
13
|
yield result
|
17
|
-
@sleeper.sleep 0.4
|
18
|
-
end
|
14
|
+
@sleeper.sleep 0.4
|
15
|
+
end
|
19
16
|
end
|
20
17
|
|
21
18
|
private
|
22
19
|
|
20
|
+
def each_test_suite_result location
|
21
|
+
while (result = get_test_suite_result(location)).status == 'in progress'
|
22
|
+
yield result
|
23
|
+
end
|
24
|
+
yield get_test_suite_result(location)
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_test_suite_result location
|
28
|
+
Spassky::TestSuiteResult.from_json(RestClient.get(location))
|
29
|
+
end
|
30
|
+
|
23
31
|
def test_runs_url
|
24
32
|
test_runs_url = @server_url.gsub(/\/$/, "") + "/test_runs"
|
25
33
|
end
|
26
34
|
|
27
|
-
def post_test
|
35
|
+
def post_test options
|
28
36
|
RestClient.post(test_runs_url, options) do |response, request, result|
|
37
|
+
process_test_post_response response
|
29
38
|
get_redirect_location response
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
33
|
-
def
|
42
|
+
def process_test_post_response response
|
34
43
|
if response.code == 500
|
35
44
|
raise response.to_str
|
36
45
|
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_redirect_location response
|
37
49
|
location = response.headers[:location]
|
38
50
|
raise "Expected #{test_runs_url} to respond with 302" unless location
|
39
51
|
location
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spassky/client/writer'
|
2
|
+
|
3
|
+
module Spassky::Client
|
4
|
+
class TestSuiteRunner
|
5
|
+
def initialize(pusher, writer, directory_reader)
|
6
|
+
@pusher = pusher
|
7
|
+
@writer = writer
|
8
|
+
@directory_reader = directory_reader
|
9
|
+
end
|
10
|
+
|
11
|
+
def run_test_suite(pattern, test_name)
|
12
|
+
begin
|
13
|
+
@pusher.push(:name => test_name, :contents => @directory_reader.read_files.to_json) do |result|
|
14
|
+
handle_test_suite_result(result)
|
15
|
+
end
|
16
|
+
rescue => error
|
17
|
+
fail_with_error error
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def fail_with_error error
|
24
|
+
@writer.write_failing(error.message)
|
25
|
+
Kernel.exit(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
def handle_test_suite_result(test_suite_result)
|
29
|
+
write_in_progress_status test_suite_result
|
30
|
+
unless test_suite_result.status == "in progress"
|
31
|
+
write(test_suite_result.status, test_suite_result.summary)
|
32
|
+
end
|
33
|
+
@previous_test_suite_result = test_suite_result
|
34
|
+
write_exit_code(test_suite_result)
|
35
|
+
end
|
36
|
+
|
37
|
+
def write_in_progress_status test_suite_result
|
38
|
+
test_suite_result.completed_since(@previous_test_suite_result).each do |device_test_status|
|
39
|
+
write_completed_test_status device_test_status
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def write_completed_test_status device_test_status
|
44
|
+
write(device_test_status.status, completion_status(device_test_status))
|
45
|
+
write(device_test_status.status, device_test_status.message)
|
46
|
+
end
|
47
|
+
|
48
|
+
def completion_status device_test_status
|
49
|
+
"#{device_test_status.status.upcase} #{device_test_status.test_name} on #{device_test_status.device_id}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def write status, message
|
53
|
+
method = status == 'pass' ? :write_passing : :write_failing
|
54
|
+
@writer.send(method, message)
|
55
|
+
end
|
56
|
+
|
57
|
+
def write_exit_code(result)
|
58
|
+
Kernel.exit(1) if result.status == 'fail'
|
59
|
+
Kernel.exit(2) if result.status == 'timed out'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -16,5 +16,14 @@ module Spassky
|
|
16
16
|
def completed?
|
17
17
|
@status != "in progress"
|
18
18
|
end
|
19
|
+
|
20
|
+
def self.from_hash hash
|
21
|
+
DeviceTestStatus.new({
|
22
|
+
:device_id => hash["device_id"],
|
23
|
+
:test_name => hash["test_name"],
|
24
|
+
:status => hash["status"],
|
25
|
+
:message => hash["message"]}
|
26
|
+
)
|
27
|
+
end
|
19
28
|
end
|
20
29
|
end
|
data/lib/spassky/server/app.rb
CHANGED
@@ -38,35 +38,22 @@ module Spassky::Server
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
def create_test_run
|
42
|
-
TestRun.create({
|
43
|
-
:name => params[:name],
|
44
|
-
:contents => JSON.parse(params[:contents]),
|
45
|
-
:devices => @device_list.recently_connected_devices
|
46
|
-
})
|
47
|
-
end
|
48
|
-
|
49
41
|
post '/test_runs' do
|
50
42
|
recently_connected_devices = @device_list.recently_connected_devices
|
51
|
-
if recently_connected_devices.
|
52
|
-
redirect "/test_runs/#{create_test_run.id}"
|
53
|
-
else
|
43
|
+
if recently_connected_devices.empty?
|
54
44
|
halt 500, "There are no connected devices"
|
55
45
|
end
|
46
|
+
redirect "/test_runs/#{create_test_run.id}"
|
56
47
|
end
|
57
48
|
|
58
49
|
get '/test_runs/:id' do
|
59
|
-
run =
|
50
|
+
run = test_run
|
60
51
|
run.update_connected_devices(@device_list.recently_connected_devices)
|
61
52
|
run.result.to_json
|
62
53
|
end
|
63
54
|
|
64
55
|
get '/test_runs/:id/run/:random/assert' do
|
65
|
-
|
66
|
-
:device_identifier => get_device_identifier,
|
67
|
-
:status => params[:status],
|
68
|
-
:message => params[:message]
|
69
|
-
)
|
56
|
+
save_test_result
|
70
57
|
end
|
71
58
|
|
72
59
|
get "/test_runs/:id/run/:random/*" do
|
@@ -76,11 +63,34 @@ module Spassky::Server
|
|
76
63
|
|
77
64
|
private
|
78
65
|
|
66
|
+
def test_run
|
67
|
+
TestRun.find(params[:id])
|
68
|
+
end
|
69
|
+
|
70
|
+
def create_test_run
|
71
|
+
TestRun.create({
|
72
|
+
:name => params[:name],
|
73
|
+
:contents => test_contents,
|
74
|
+
:devices => @device_list.recently_connected_devices
|
75
|
+
})
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_contents
|
79
|
+
JSON.parse(params[:contents])
|
80
|
+
end
|
81
|
+
|
79
82
|
def get_test_file_contents test_run_id, file_name
|
80
|
-
test_run = TestRun.find(params[:id])
|
81
83
|
HtmlTest.new(test_run.contents, idle_url, 1).get_file(file_name)
|
82
84
|
end
|
83
85
|
|
86
|
+
def save_test_result
|
87
|
+
test_run.save_result_for_device(
|
88
|
+
:device_identifier => get_device_identifier,
|
89
|
+
:status => params[:status],
|
90
|
+
:message => params[:message]
|
91
|
+
)
|
92
|
+
end
|
93
|
+
|
84
94
|
def redirect_to_run_tests(test_run)
|
85
95
|
redirect "/test_runs/#{test_run.id}/run/#{RandomStringGenerator.random_string}/#{test_run.name}"
|
86
96
|
end
|
@@ -15,6 +15,7 @@ module Spassky::Server
|
|
15
15
|
def initialize
|
16
16
|
download_wurfl_file unless File.exist?(WURFL_FILE)
|
17
17
|
@wurfl = WURFL.new(WURFL_FILE)
|
18
|
+
@stored_device_identifiers = {}
|
18
19
|
end
|
19
20
|
|
20
21
|
def download_wurfl_file
|
@@ -22,27 +23,33 @@ module Spassky::Server
|
|
22
23
|
Kernel.puts("Downloading WURFL database")
|
23
24
|
RestClient.proxy = ENV["http_proxy"] if ENV["http_proxy"]
|
24
25
|
content = RestClient.get(LATEST)
|
25
|
-
|
26
|
-
file.write(content)
|
27
|
-
end
|
26
|
+
save_wurfl_file content
|
28
27
|
end
|
29
28
|
|
30
29
|
def device_identifier user_agent
|
31
|
-
|
30
|
+
cached_device_identifier(user_agent) or uncached_device_identifier(user_agent)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@stored_device_identifiers[user_agent] = user_agent
|
37
|
-
else
|
38
|
-
@stored_device_identifiers[user_agent] = "#{device.model_name} (id = #{device.id}, mobile_browser = #{device.mobile_browser}, device_os_version = #{device.device_os_version})"
|
39
|
-
end
|
35
|
+
def save_wurfl_file content
|
36
|
+
File.open(WURFL_FILE, "w") do |file|
|
37
|
+
file.write(content)
|
40
38
|
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def cached_device_identifier user_agent
|
41
42
|
@stored_device_identifiers[user_agent]
|
42
43
|
end
|
43
44
|
|
44
|
-
def
|
45
|
-
@
|
45
|
+
def uncached_device_identifier user_agent
|
46
|
+
@stored_device_identifiers ||= {}
|
47
|
+
if device = @wurfl[user_agent]
|
48
|
+
@stored_device_identifiers[user_agent] = "#{device.model_name} (id = #{device.id}, mobile_browser = #{device.mobile_browser}, device_os_version = #{device.device_os_version})"
|
49
|
+
else
|
50
|
+
@stored_device_identifiers[user_agent] = user_agent
|
51
|
+
end
|
52
|
+
cached_device_identifier user_agent
|
46
53
|
end
|
47
54
|
end
|
48
55
|
|
@@ -10,12 +10,18 @@ module Spassky::Server
|
|
10
10
|
|
11
11
|
def recently_connected_devices
|
12
12
|
@devices_and_time_last_connected.keys.select do |device_id|
|
13
|
-
|
13
|
+
recent? @devices_and_time_last_connected[device_id]
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
def clear
|
18
18
|
@devices_and_time_last_connected = {}
|
19
19
|
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def recent? time
|
24
|
+
Time.now.to_f - time.to_f < 3
|
25
|
+
end
|
20
26
|
end
|
21
27
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'spassky/
|
1
|
+
require 'spassky/test_suite_result'
|
2
2
|
|
3
3
|
module Spassky::Server
|
4
4
|
class TestRun
|
@@ -19,9 +19,7 @@ module Spassky::Server
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def save_result_for_device(options)
|
22
|
-
|
23
|
-
raise "#{options[:status]} is not a valid status"
|
24
|
-
end
|
22
|
+
validate_status options[:status]
|
25
23
|
@status_by_device_id[options[:device_identifier]] = options[:status]
|
26
24
|
@message_by_device_id[options[:device_identifier]] = options[:message]
|
27
25
|
end
|
@@ -35,7 +33,7 @@ module Spassky::Server
|
|
35
33
|
end
|
36
34
|
|
37
35
|
def result
|
38
|
-
Spassky::
|
36
|
+
Spassky::TestSuiteResult.new(@status_by_device_id.map { |device_id, status|
|
39
37
|
Spassky::DeviceTestStatus.new(:device_id => device_id, :status => status, :message => @message_by_device_id[device_id], :test_name => @name)
|
40
38
|
})
|
41
39
|
end
|
@@ -55,12 +53,20 @@ module Spassky::Server
|
|
55
53
|
test_runs.find { |test_run| test_run.run_by_device_id?(device_id) == false }
|
56
54
|
end
|
57
55
|
|
56
|
+
private
|
57
|
+
|
58
|
+
def self.test_runs
|
59
|
+
@test_runs ||= []
|
60
|
+
end
|
61
|
+
|
58
62
|
def self.delete_all
|
59
63
|
@test_runs = []
|
60
64
|
end
|
61
65
|
|
62
|
-
def
|
63
|
-
|
66
|
+
def validate_status status
|
67
|
+
unless ['pass', 'fail'].include?(status)
|
68
|
+
raise "#{status} is not a valid status"
|
69
|
+
end
|
64
70
|
end
|
65
71
|
end
|
66
72
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spassky/test_suite_result_summariser'
|
2
|
+
require 'spassky/device_test_status'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Spassky
|
6
|
+
class TestSuiteResult
|
7
|
+
attr_reader :device_statuses
|
8
|
+
|
9
|
+
def initialize device_statuses
|
10
|
+
@device_statuses = device_statuses
|
11
|
+
end
|
12
|
+
|
13
|
+
def status
|
14
|
+
statuses = @device_statuses.map { |s| s.status }
|
15
|
+
return "in progress" if statuses.empty?
|
16
|
+
["in progress", "fail", "timed out", "pass"].find {|s| statuses.include? s}
|
17
|
+
end
|
18
|
+
|
19
|
+
def completed_since(older_test_suite_result)
|
20
|
+
if older_test_suite_result.nil?
|
21
|
+
device_statuses.select { |s| s.completed? }
|
22
|
+
else
|
23
|
+
find_newly_completed_device_results(older_test_suite_result)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def summary
|
28
|
+
TestSuiteResultSummariser.new(@device_statuses).summary
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_json
|
32
|
+
{
|
33
|
+
:status => "pass",
|
34
|
+
:device_statuses => @device_statuses.map do |status|
|
35
|
+
{
|
36
|
+
:device_id => status.device_id,
|
37
|
+
:test_name => status.test_name,
|
38
|
+
:status => status.status,
|
39
|
+
:message => status.message
|
40
|
+
}
|
41
|
+
end
|
42
|
+
}.to_json
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.from_json json
|
46
|
+
device_test_statuses = JSON.parse(json)['device_statuses'].map do |device_test_status|
|
47
|
+
DeviceTestStatus.from_hash(device_test_status)
|
48
|
+
end
|
49
|
+
test_suite_result = TestSuiteResult.new(device_test_statuses)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def find_newly_completed_device_results(older_test_suite_result)
|
55
|
+
completed = []
|
56
|
+
before_and_after(older_test_suite_result) do |before, after|
|
57
|
+
if before.in_progress? && after.completed?
|
58
|
+
completed << after
|
59
|
+
end
|
60
|
+
end
|
61
|
+
completed
|
62
|
+
end
|
63
|
+
|
64
|
+
def before_and_after(older_test_suite_result)
|
65
|
+
device_statuses.each_with_index do |s, i|
|
66
|
+
yield older_test_suite_result.device_statuses[i], s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -1,17 +1,17 @@
|
|
1
1
|
module Spassky
|
2
|
-
class
|
2
|
+
class TestSuiteResultSummariser
|
3
3
|
def initialize device_statuses
|
4
4
|
@device_statuses = device_statuses
|
5
5
|
end
|
6
6
|
|
7
7
|
def summary
|
8
8
|
statuses = []
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
9
|
+
{"pass" => "passed", "fail" => "failed", "timed out" => "timed out"}.each do |status, description|
|
10
|
+
status_count = status_count status
|
11
|
+
if status_count > 0
|
12
|
+
statuses << "#{status_count} #{description}"
|
13
|
+
end
|
14
|
+
end
|
15
15
|
statuses.join ", "
|
16
16
|
end
|
17
17
|
|
data/lib/spassky/version.rb
CHANGED
data/spassky.gemspec
CHANGED
@@ -8,25 +8,25 @@ module Spassky::Client
|
|
8
8
|
end
|
9
9
|
|
10
10
|
let :runner do
|
11
|
-
mock(:runner, :
|
11
|
+
mock(:runner, :run_test_suite => true)
|
12
12
|
end
|
13
13
|
|
14
14
|
before do
|
15
15
|
Pusher.stub!(:new).and_return(pusher)
|
16
|
-
|
16
|
+
TestSuiteRunner.stub!(:new).and_return(runner)
|
17
17
|
end
|
18
18
|
|
19
19
|
describe "spassky run" do
|
20
20
|
context "with a server url" do
|
21
21
|
it "creates a pusher" do
|
22
22
|
Pusher.should_receive(:new).with("server_name").and_return(pusher)
|
23
|
-
|
23
|
+
TestSuiteRunner.should_receive(:new).with(pusher, anything(), anything()).and_return(runner)
|
24
24
|
Cli.new.run "test_pattern", "test_name", "server_name"
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
it "runs a test" do
|
29
|
-
runner.should_receive(:
|
29
|
+
runner.should_receive(:run_test_suite).with("test_pattern", "test_name")
|
30
30
|
Cli.new.run "test_pattern", "test_name", "server_name"
|
31
31
|
end
|
32
32
|
|
@@ -34,7 +34,7 @@ module Spassky::Client
|
|
34
34
|
it "creates a test runner with a default writer" do
|
35
35
|
default_writer = mock :default_writer
|
36
36
|
DefaultWriter.should_receive(:new).with(STDOUT).and_return(default_writer)
|
37
|
-
|
37
|
+
TestSuiteRunner.should_receive(:new).with(anything(), default_writer, anything())
|
38
38
|
Cli.new.run "test_pattern", "test_name", "server_name"
|
39
39
|
end
|
40
40
|
end
|
@@ -43,8 +43,8 @@ module Spassky::Client
|
|
43
43
|
it "creates a test runner with a colour writer" do
|
44
44
|
coloured_writer = mock :coloured_writer
|
45
45
|
ColouredWriter.should_receive(:new).with(STDOUT).and_return(coloured_writer)
|
46
|
-
|
47
|
-
Cli.new.run "test_pattern", "test_name", "server_name",
|
46
|
+
TestSuiteRunner.should_receive(:new).with(anything(), coloured_writer, anything())
|
47
|
+
Cli.new.run "test_pattern", "test_name", "server_name", true
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -15,15 +15,15 @@ module Spassky::Client
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def in_progress_status
|
18
|
-
Spassky::
|
18
|
+
Spassky::TestSuiteResult.new([FactoryGirl.build(:device_test_status, :status => 'in progress')]).to_json
|
19
19
|
end
|
20
20
|
|
21
21
|
def passed_status
|
22
|
-
Spassky::
|
22
|
+
Spassky::TestSuiteResult.new([FactoryGirl.build(:device_test_status)]).to_json
|
23
23
|
end
|
24
24
|
|
25
25
|
def failed_status
|
26
|
-
Spassky::
|
26
|
+
Spassky::TestSuiteResult.new([FactoryGirl.build(:device_test_status, :status => 'fail')]).to_json
|
27
27
|
end
|
28
28
|
|
29
29
|
it "pushes a test to the server" do
|
@@ -78,7 +78,7 @@ module Spassky::Client
|
|
78
78
|
|
79
79
|
it "sleeps while looping during get requests" do
|
80
80
|
RestClient.stub!(:get).and_return(in_progress_status, in_progress_status, in_progress_status, passed_status)
|
81
|
-
@sleeper.should_receive(:sleep).with(0.4).exactly(
|
81
|
+
@sleeper.should_receive(:sleep).with(0.4).exactly(4).times
|
82
82
|
@pusher.push("test contents") { |result| }
|
83
83
|
end
|
84
84
|
end
|