parallel_calabash 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +29 -4
- data/bin/parallel_calabash +4 -0
- data/lib/parallel_calabash.rb +4 -2
- data/lib/parallel_calabash/feature_grouper.rb +38 -2
- data/lib/parallel_calabash/result_formatter.rb +2 -2
- data/lib/parallel_calabash/version.rb +1 -1
- data/spec/lib/parallel_calabash/feature_grouper_spec.rb +89 -0
- data/spec/lib/parallel_calabash/runner_spec.rb +25 -0
- data/spec/test_data/features/aaa.feature +43 -0
- data/spec/test_data/features/bbb.feature +19 -0
- data/spec/test_data/features/ccc.feature +14 -0
- data/spec/test_data/features/ddd.feature +10 -0
- data/spec/test_data/features/eee.feature +7 -0
- data/spec/test_data/features/fff.feature +0 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b3cc74523250c60f0398e05a6c48f836440f25a6
|
4
|
+
data.tar.gz: 83f6df11b48c1f1bd8a005aed355f3eaf9a91cd3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 381b18478ffaa24329d6bbeb26834e479cbe1270606a1a401416562b84f61ec8d6b0eb229fbd4281927a7bbad7901d91057705fc7712d5da2fa277b3b6da096d
|
7
|
+
data.tar.gz: 95cbc60ccee529eb91c750604081c1c9ea99bb1bd8b1f57df8261dcc3fee872805535dea1518b236d90a1d0f4898b2c09c5da30200df292db6c2cac6eebdc8d3
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
|
-
#
|
1
|
+
# calabash parallel execution
|
2
2
|
|
3
|
-
|
3
|
+
## NOTE: This is not yet tested on windows.
|
4
|
+
|
5
|
+
|
6
|
+
Run calabash-android tests in parallel on multiple connected devices. This is inspired by parallel_tests https://rubygems.org/gems/parallel_tests
|
7
|
+
|
8
|
+
eg. bundle exec parallel_calabash -a my.apk -o'--format pretty' features/ --serialize-stdout
|
4
9
|
|
5
10
|
## Installation
|
6
11
|
|
@@ -12,7 +17,7 @@ gem 'parallel_calabash'
|
|
12
17
|
|
13
18
|
And then execute:
|
14
19
|
|
15
|
-
$ bundle
|
20
|
+
$ bundle install
|
16
21
|
|
17
22
|
Or install it yourself as:
|
18
23
|
|
@@ -20,7 +25,27 @@ Or install it yourself as:
|
|
20
25
|
|
21
26
|
## Usage
|
22
27
|
|
23
|
-
|
28
|
+
Usage: parallel_calabash [options]
|
29
|
+
|
30
|
+
Example: parallel_calabash -a my.apk -o 'cucumber_opts_like_tags_profile_etc_here' features/
|
31
|
+
|
32
|
+
|
33
|
+
-h, --help Show this message
|
34
|
+
-v, --version Show version
|
35
|
+
-a, --apk apk_path apk file path
|
36
|
+
-o, --cucumber_opts '[OPTIONS]' execute with those cucumber options
|
37
|
+
|
38
|
+
-d distribution_tag, divide features into groups as per occurrence of given tag
|
39
|
+
--distribution-tag
|
40
|
+
--serialize-stdout Serialize stdout output show output only after process completion
|
41
|
+
|
42
|
+
## REPROTING
|
43
|
+
|
44
|
+
use ENV['TEST_PROCESS_NUMBER'] environment variable in your ruby scripts to find out the process number. you can use this for reporting purpose.
|
45
|
+
|
46
|
+
eg. modify default profile in cucumber.yml as below to get different report from different process
|
47
|
+
|
48
|
+
default: --format html --out reports/Automation_report_<%= ENV['TEST_PROCESS_NUMBER'] %>.html --format pretty
|
24
49
|
|
25
50
|
## Contributing
|
26
51
|
|
data/bin/parallel_calabash
CHANGED
@@ -25,6 +25,10 @@ def parse_arguments(arguments)
|
|
25
25
|
options[:apk_path] = apk_path
|
26
26
|
end
|
27
27
|
|
28
|
+
opts.on("-d", "--distribution-tag distribution_tag", "divide features into groups as per occurrence of given tag") do |distribution_tag|
|
29
|
+
options[:distribution_tag] = distribution_tag
|
30
|
+
end
|
31
|
+
|
28
32
|
opts.on("-o", "--cucumber_opts '[OPTIONS]'", "execute with those cucumber options") do |cucumber_opts|
|
29
33
|
options[:cucumber_options] = cucumber_opts
|
30
34
|
end
|
data/lib/parallel_calabash.rb
CHANGED
@@ -26,7 +26,7 @@ module ParallelCalabash
|
|
26
26
|
|
27
27
|
test_results = nil
|
28
28
|
report_time_taken do
|
29
|
-
groups = FeatureGrouper.feature_groups(options[:feature_folder], number_of_processes)
|
29
|
+
groups = FeatureGrouper.feature_groups(options[:feature_folder], number_of_processes,options[:distribution_tag])
|
30
30
|
puts "#{number_of_processes} processes for #{groups.flatten.size} features"
|
31
31
|
test_results = Parallel.map(groups, :in_threads => groups.size) do |group|
|
32
32
|
Runner.run_tests(group, groups.index(group), options)
|
@@ -44,7 +44,9 @@ module ParallelCalabash
|
|
44
44
|
def report_time_taken
|
45
45
|
start = Time.now
|
46
46
|
yield
|
47
|
-
|
47
|
+
time_in_sec = Time.now - start
|
48
|
+
mm, ss = time_in_sec.divmod(60)
|
49
|
+
puts "\nTook #{mm} Minutes, #{ss.round(2)} Seconds"
|
48
50
|
end
|
49
51
|
|
50
52
|
end
|
@@ -3,7 +3,11 @@ module ParallelCalabash
|
|
3
3
|
|
4
4
|
class << self
|
5
5
|
|
6
|
-
def feature_groups(feature_folder, group_size)
|
6
|
+
def feature_groups(feature_folder, group_size,weighing_factor = nil)
|
7
|
+
weighing_factor.nil? ? feature_groups_by_feature_files(feature_folder, group_size) : feature_groups_by_weight(feature_folder, group_size,weighing_factor)
|
8
|
+
end
|
9
|
+
|
10
|
+
def feature_groups_by_feature_files(feature_folder, group_size)
|
7
11
|
files = feature_files_in_folder feature_folder
|
8
12
|
min_number_files_per_group = files.size/group_size
|
9
13
|
remaining_number_of_files = files.size % group_size
|
@@ -19,13 +23,45 @@ module ParallelCalabash
|
|
19
23
|
groups.reject(&:empty?)
|
20
24
|
end
|
21
25
|
|
22
|
-
def feature_files_in_folder
|
26
|
+
def feature_files_in_folder(feature_dir)
|
23
27
|
if File.directory?(feature_dir.first)
|
24
28
|
files = Dir[File.join(feature_dir, "**{,/*/**}/*")].uniq
|
25
29
|
files.grep(/\.feature$/)
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
33
|
+
def weight_of_feature(feature_file, weighing_factor)
|
34
|
+
content = File.read(feature_file)
|
35
|
+
content.scan(/#{weighing_factor}\b/).size
|
36
|
+
end
|
37
|
+
|
38
|
+
def features_with_weights(feature_dir, weighing_factor)
|
39
|
+
files = feature_files_in_folder feature_dir
|
40
|
+
features_and_weight = []
|
41
|
+
files.each do |file|
|
42
|
+
features_and_weight << {:feature => file, :weight => weight_of_feature(file, weighing_factor)}
|
43
|
+
end
|
44
|
+
features_and_weight
|
45
|
+
end
|
46
|
+
|
47
|
+
def feature_groups_by_weight(feature_folder, group_size, weighing_factor)
|
48
|
+
features = features_with_weights feature_folder, weighing_factor
|
49
|
+
feature_groups = Array.new(group_size).map{|e| e = []}
|
50
|
+
features.each do |feature|
|
51
|
+
feature_groups[index_of_lightest_group(feature_groups)] << feature
|
52
|
+
end
|
53
|
+
feature_groups.map{|group| group.map{|feature_hash| feature_hash[:feature]}}
|
54
|
+
end
|
55
|
+
|
56
|
+
def index_of_lightest_group feature_groups
|
57
|
+
lightest = feature_groups.min { |x, y| weight_of_group(x) <=> weight_of_group(y) }
|
58
|
+
index = feature_groups.index(lightest)
|
59
|
+
end
|
60
|
+
|
61
|
+
def weight_of_group group
|
62
|
+
group.inject(0) { |sum, b| sum + b[:weight] }
|
63
|
+
end
|
64
|
+
|
29
65
|
end
|
30
66
|
|
31
67
|
end
|
@@ -22,7 +22,7 @@ module ParallelCalabash
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def summarize_results(results)
|
25
|
-
output = []
|
25
|
+
output = ["\n\n************ FINAL SUMMARY ************"]
|
26
26
|
|
27
27
|
failing_scenarios = results.grep(failing_scenario_regex)
|
28
28
|
if failing_scenarios.any?
|
@@ -69,7 +69,7 @@ module ParallelCalabash
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def failing_scenario_regex
|
72
|
-
/^cucumber features\/.+:\d+/
|
72
|
+
/^cucumber .*features\/.+:\d+/
|
73
73
|
end
|
74
74
|
|
75
75
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'parallel_calabash/feature_grouper'
|
4
|
+
|
5
|
+
describe ParallelCalabash::FeatureGrouper do
|
6
|
+
|
7
|
+
describe :feature_files_in_folder do
|
8
|
+
it 'should find all feature files path in the given folder' do
|
9
|
+
expect(ParallelCalabash::FeatureGrouper.feature_files_in_folder ['spec/test_data/features']).to eq \
|
10
|
+
["spec/test_data/features/aaa.feature", "spec/test_data/features/bbb.feature", "spec/test_data/features/ccc.feature", "spec/test_data/features/ddd.feature", "spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe :feature_groups do
|
15
|
+
|
16
|
+
it 'should group all features in only one group' do
|
17
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups(['spec/test_data/features'], 1)).to eq \
|
18
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/bbb.feature", "spec/test_data/features/ccc.feature", "spec/test_data/features/ddd.feature", "spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"]]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should divide features in 2 groups' do
|
22
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups(['spec/test_data/features'], 2)).to eq \
|
23
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/bbb.feature", "spec/test_data/features/ccc.feature"], ["spec/test_data/features/ddd.feature", "spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"]]
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should divide features in 3 groups' do
|
27
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups(['spec/test_data/features'], 3)).to eq \
|
28
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/bbb.feature"], ["spec/test_data/features/ccc.feature", "spec/test_data/features/ddd.feature"], ["spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"]]
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should divide features in 4 groups' do
|
32
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups(['spec/test_data/features'], 4)).to eq \
|
33
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/eee.feature"], ["spec/test_data/features/bbb.feature", "spec/test_data/features/fff.feature"], ["spec/test_data/features/ccc.feature"], ["spec/test_data/features/ddd.feature"]]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should divide features in 5 groups' do
|
37
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups(['spec/test_data/features'], 5)).to eq \
|
38
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/fff.feature"], ["spec/test_data/features/bbb.feature"], ["spec/test_data/features/ccc.feature"], ["spec/test_data/features/ddd.feature"], ["spec/test_data/features/eee.feature"]]
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe :feature_weight do
|
44
|
+
it 'should find number of occurrence of given tag in feature' do
|
45
|
+
expect(ParallelCalabash::FeatureGrouper.weight_of_feature('spec/test_data/features/aaa.feature', '@tag1')).to eq 14
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should find number of occurrence of given tag in feature' do
|
49
|
+
expect(ParallelCalabash::FeatureGrouper.weight_of_feature('spec/test_data/features/bbb.feature', '@tag1')).to eq 5
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe :features_with_weights do
|
54
|
+
it 'should give all features along with their weights' do
|
55
|
+
expect(ParallelCalabash::FeatureGrouper.features_with_weights(['spec/test_data/features'], '@tag1')).to eq \
|
56
|
+
[{:feature => "spec/test_data/features/aaa.feature", :weight => 14}, {:feature => "spec/test_data/features/bbb.feature", :weight => 5}, {:feature => "spec/test_data/features/ccc.feature", :weight => 4}, {:feature => "spec/test_data/features/ddd.feature", :weight => 3}, {:feature => "spec/test_data/features/eee.feature", :weight => 2}, {:feature => "spec/test_data/features/fff.feature", :weight => 0}]
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe :feature_groups_by_weight do
|
62
|
+
it 'should groups all features equally into 2 groups per their weight' do
|
63
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups_by_weight(['spec/test_data/features'], 2, '@tag1')).to eq \
|
64
|
+
[["spec/test_data/features/aaa.feature", "spec/test_data/features/fff.feature"], ["spec/test_data/features/bbb.feature", "spec/test_data/features/ccc.feature", "spec/test_data/features/ddd.feature", "spec/test_data/features/eee.feature"]]
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should groups all features equally into 3 groups as per their weight' do
|
68
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups_by_weight(['spec/test_data/features'], 3, '@tag1')).to eq \
|
69
|
+
[["spec/test_data/features/aaa.feature"], ["spec/test_data/features/bbb.feature", "spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"], ["spec/test_data/features/ccc.feature", "spec/test_data/features/ddd.feature"]]
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should groups all features equally into 4 groups as per their weight' do
|
73
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups_by_weight(['spec/test_data/features'], 4, '@tag1')).to eq \
|
74
|
+
[["spec/test_data/features/aaa.feature"], ["spec/test_data/features/bbb.feature"], ["spec/test_data/features/ccc.feature", "spec/test_data/features/fff.feature"], ["spec/test_data/features/ddd.feature", "spec/test_data/features/eee.feature"]]
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should groups all features equally into 5 groups as per their weight' do
|
78
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups_by_weight(['spec/test_data/features'], 5, '@tag1')).to eq \
|
79
|
+
[["spec/test_data/features/aaa.feature"], ["spec/test_data/features/bbb.feature"], ["spec/test_data/features/ccc.feature"], ["spec/test_data/features/ddd.feature"], ["spec/test_data/features/eee.feature", "spec/test_data/features/fff.feature"]]
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should groups all features equally into 6 groups as per their weight' do
|
83
|
+
expect(ParallelCalabash::FeatureGrouper.feature_groups_by_weight(['spec/test_data/features'], 6, '@tag1')).to eq \
|
84
|
+
[["spec/test_data/features/aaa.feature"], ["spec/test_data/features/bbb.feature"], ["spec/test_data/features/ccc.feature"], ["spec/test_data/features/ddd.feature"], ["spec/test_data/features/eee.feature"], ["spec/test_data/features/fff.feature"]]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'parallel_calabash'
|
3
|
+
|
4
|
+
describe ParallelCalabash::Runner do
|
5
|
+
describe :command_for_process do
|
6
|
+
it 'should return command with env variables' do
|
7
|
+
ParallelCalabash::AdbHelper.should_receive(:device_for_process).with(0).and_return("5555")
|
8
|
+
expect(ParallelCalabash::Runner.command_for_process(0, 'base_command')).to eq \
|
9
|
+
"AUTOTEST=1;export AUTOTEST ADB_DEVICE_ARG=5555;export ADB_DEVICE_ARG TEST_PROCESS_NUMBER=1;export TEST_PROCESS_NUMBER;base_command"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
describe :execute_command_for_process do
|
15
|
+
it 'should execute the command with correct env variables set and return exit status 0 when command gets executed successfully' do
|
16
|
+
ParallelCalabash::AdbHelper.should_receive(:device_for_process).with(3).and_return("DEVICE3")
|
17
|
+
expect(ParallelCalabash::Runner.execute_command_for_process(3,'echo $ADB_DEVICE_ARG;echo $TEST_PROCESS_NUMBER',true)).to eq ({:stdout=>"DEVICE3\n4\n", :exit_status=>0})
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should return exit status of 1' do
|
21
|
+
expect(ParallelCalabash::Runner.execute_command_for_process(3,"ruby -e 'exit(1)'",true)).to eq ({:stdout=>"", :exit_status=>1})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Feature: aaa feature
|
2
|
+
|
3
|
+
@tag1
|
4
|
+
Scenario:
|
5
|
+
|
6
|
+
@tag1
|
7
|
+
Scenario:
|
8
|
+
|
9
|
+
@tag1
|
10
|
+
Scenario:
|
11
|
+
|
12
|
+
@tag1
|
13
|
+
Scenario:
|
14
|
+
|
15
|
+
@tag1
|
16
|
+
Scenario:
|
17
|
+
|
18
|
+
@tag1
|
19
|
+
Scenario:
|
20
|
+
|
21
|
+
@tag1
|
22
|
+
Scenario:
|
23
|
+
|
24
|
+
@tag1
|
25
|
+
Scenario:
|
26
|
+
|
27
|
+
@tag1
|
28
|
+
Scenario:
|
29
|
+
|
30
|
+
@tag1
|
31
|
+
Scenario:
|
32
|
+
|
33
|
+
@tag1
|
34
|
+
Scenario:
|
35
|
+
|
36
|
+
@tag1
|
37
|
+
Scenario:
|
38
|
+
|
39
|
+
@tag1
|
40
|
+
Scenario:
|
41
|
+
|
42
|
+
@tag1
|
43
|
+
Scenario:
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: parallel_calabash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rajdeep
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-10-
|
11
|
+
date: 2014-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,7 +75,15 @@ files:
|
|
75
75
|
- lib/parallel_calabash/runner.rb
|
76
76
|
- lib/parallel_calabash/version.rb
|
77
77
|
- parallel_calabash.gemspec
|
78
|
+
- spec/lib/parallel_calabash/feature_grouper_spec.rb
|
79
|
+
- spec/lib/parallel_calabash/runner_spec.rb
|
78
80
|
- spec/spec_helper.rb
|
81
|
+
- spec/test_data/features/aaa.feature
|
82
|
+
- spec/test_data/features/bbb.feature
|
83
|
+
- spec/test_data/features/ccc.feature
|
84
|
+
- spec/test_data/features/ddd.feature
|
85
|
+
- spec/test_data/features/eee.feature
|
86
|
+
- spec/test_data/features/fff.feature
|
79
87
|
homepage: https://github.com/rajdeepv/parallel_calabash
|
80
88
|
licenses:
|
81
89
|
- MIT
|
@@ -101,4 +109,12 @@ signing_key:
|
|
101
109
|
specification_version: 4
|
102
110
|
summary: calabash android tests in parallel
|
103
111
|
test_files:
|
112
|
+
- spec/lib/parallel_calabash/feature_grouper_spec.rb
|
113
|
+
- spec/lib/parallel_calabash/runner_spec.rb
|
104
114
|
- spec/spec_helper.rb
|
115
|
+
- spec/test_data/features/aaa.feature
|
116
|
+
- spec/test_data/features/bbb.feature
|
117
|
+
- spec/test_data/features/ccc.feature
|
118
|
+
- spec/test_data/features/ddd.feature
|
119
|
+
- spec/test_data/features/eee.feature
|
120
|
+
- spec/test_data/features/fff.feature
|