-
Notifications
You must be signed in to change notification settings - Fork 497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add --single-process-tag option to run specific Gherkin scenarios sequentially #810
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,6 +1,8 @@ | ||||||
# frozen_string_literal: true | ||||||
module ParallelTests | ||||||
class Grouper | ||||||
BY_SCENARIOS_SUPPORTED_OPTIONS = [:single_process_tag].freeze | ||||||
|
||||||
class << self | ||||||
def by_steps(tests, num_groups, options) | ||||||
features_with_steps = group_by_features_with_steps(tests, options) | ||||||
|
@@ -9,20 +11,16 @@ def by_steps(tests, num_groups, options) | |||||
|
||||||
def by_scenarios(tests, num_groups, options = {}) | ||||||
scenarios = group_by_scenarios(tests, options) | ||||||
in_even_groups_by_size(scenarios, num_groups) | ||||||
in_even_groups_by_size(scenarios, num_groups, options.slice(*BY_SCENARIOS_SUPPORTED_OPTIONS)) | ||||||
end | ||||||
|
||||||
def in_even_groups_by_size(items, num_groups, options = {}) | ||||||
groups = Array.new(num_groups) { { items: [], size: 0 } } | ||||||
|
||||||
return specify_groups(items, num_groups, options, groups) if options[:specify_groups] | ||||||
|
||||||
# add all files that should run in a single process to one group | ||||||
single_process_patterns = options[:single_process] || [] | ||||||
|
||||||
single_items, items = items.partition do |item, _size| | ||||||
single_process_patterns.any? { |pattern| item =~ pattern } | ||||||
end | ||||||
# add all files/scenarios that should run in a single process to one group | ||||||
single_items, items = separate_single_items(items, options) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice refactor! |
||||||
|
||||||
isolate_count = isolate_count(options) | ||||||
|
||||||
|
@@ -41,7 +39,7 @@ def in_even_groups_by_size(items, num_groups, options = {}) | |||||
group_features_by_size(items_to_group(items), groups[isolate_count..-1]) | ||||||
else | ||||||
# add all files that should run in a single non-isolated process to first group | ||||||
single_items.each { |item, size| add_to_group(groups.first, item, size) } | ||||||
group_features_by_size(items_to_group(single_items), [groups.first]) | ||||||
|
||||||
# group all by size | ||||||
group_features_by_size(items_to_group(items), groups) | ||||||
|
@@ -129,6 +127,23 @@ def group_by_scenarios(tests, options = {}) | |||||
ParallelTests::Cucumber::Scenarios.all(tests, options) | ||||||
end | ||||||
|
||||||
def separate_single_items(items, options) | ||||||
items.partition { |item| to_single_items?(item, options) } | ||||||
end | ||||||
|
||||||
def to_single_items?(item, options) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this whole "item is item or item and size or item and tags" is kinda funky ... if you have any good ideas how to clean that up lmk or leave a TODO comment on how that can be improved |
||||||
if options[:single_process] | ||||||
item = item_with_tags?(item) || item_with_size?(item) ? item[0] : item | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... maybe just |
||||||
options[:single_process].any? { |pattern| item =~ pattern } | ||||||
elsif options[:single_process_tag] | ||||||
raise "--single-tag option can only be used with '--group-by scenarios'" unless item_with_tags?(item) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put the raise into the option parser so it fails early ? |
||||||
item_tags = item[1] | ||||||
item_tags.any? { |tag| tag.match?(options[:single_process_tag]) } | ||||||
else | ||||||
false | ||||||
end | ||||||
end | ||||||
|
||||||
def group_features_by_size(items, groups_to_fill) | ||||||
items.each do |item, size| | ||||||
size ||= 1 | ||||||
|
@@ -138,7 +153,30 @@ def group_features_by_size(items, groups_to_fill) | |||||
end | ||||||
|
||||||
def items_to_group(items) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. some rough comment on what this method is used/does for would be nice |
||||||
items.first && items.first.size == 2 ? largest_first(items) : items | ||||||
return items_without_tags(items) if items_with_tags?(items) | ||||||
return largest_first(items) if items_with_size?(items) | ||||||
|
||||||
items | ||||||
end | ||||||
|
||||||
def items_with_tags?(items) | ||||||
items.first.is_a?(Array) && item_with_tags?(items.first) | ||||||
end | ||||||
|
||||||
def items_with_size?(items) | ||||||
items.first.is_a?(Array) && item_with_size?(items.first) | ||||||
end | ||||||
|
||||||
def item_with_tags?(item) | ||||||
item[1].is_a?(Array) | ||||||
end | ||||||
|
||||||
def item_with_size?(item) | ||||||
item[1].is_a?(Numeric) | ||||||
end | ||||||
|
||||||
def items_without_tags(items) | ||||||
items.map(&:first) | ||||||
end | ||||||
end | ||||||
end | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could just pass in all options and let it pick what it wants