Last active
April 24, 2023 19:53
-
-
Save stufro/71ebea8cc89925837bd42e84bb0c5b5c to your computer and use it in GitHub Desktop.
Splitting up cucumber feature files based on number of scenarios
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# recursively places features into groups in turn | |
class CucumberSlicer | |
def initialize(slices:) | |
@slices = slices | |
end | |
def slice | |
feature_files = Dir.glob("features/**/*.feature") | |
sorted_features = feature_files.map { |filepath| [filepath, scenario_count(filepath)] } | |
.sort_by { |_file, count| count } | |
.map { |file, _| file } | |
populate_slices(initialize_slices, 0, sorted_features) | |
end | |
private | |
def scenario_count(filepath) | |
File.open(filepath).grep(/Scenario:|(?<!Examples:\s)^\s*\|/).count | |
end | |
def populate_slices(slices, slice_index, features) | |
return slices if features.count.zero? | |
slices[slice_index] << features.pop | |
populate_slices(slices, (slice_index + 1) % @slices, features) | |
end | |
def initialize_slices | |
Array.new(@slices) { [] } | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# prevents 1 group becoming larger than the others by calculating if the group has space for the number of | |
# scenarios before placing into the group | |
class CucumberSlicer | |
class << self | |
def slice(num_slices: 5) | |
feature_filepaths = Dir.glob("features/**/*.feature") | |
features = gather_features_metadata(feature_filepaths) | |
average_scenario_count = total_scenario_count(features) / num_slices | |
slices = initialize_slices(num_slices) | |
features.each do |feature| | |
slice = pick_a_slice(slices, feature[:scenario_count], average_scenario_count) | |
add_feature_to_a_slice(feature, slice) | |
end | |
slices.pluck(:feature_filepaths) | |
end | |
private | |
def add_feature_to_a_slice(feature, slice) | |
slice[:scenario_count] += feature[:scenario_count] | |
slice[:feature_filepaths] << feature[:feature_filepath] | |
end | |
def pick_a_slice(slices, feature_size, target_size) | |
slices.find { |slice| (slice[:scenario_count] + feature_size) <= (target_size + 1) } | |
end | |
def gather_features_metadata(feature_filepaths) | |
feature_filepaths.map do |feature_filepath| | |
scenario_count = File.read(feature_filepath).scan(/Scenario:|(?<!Examples:\s)^\s*\|/).count | |
{ scenario_count:, feature_filepath: } | |
end | |
end | |
def total_scenario_count(features) | |
features.sum { |feature| feature[:scenario_count] } | |
end | |
def initialize_slices(num_slices) | |
Array.new(num_slices) { { scenario_count: 0, feature_filepaths: [] } } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment