Last active
August 16, 2017 08:07
-
-
Save Ashraf-Ali-aa/0a70aec9d1f9bf5dec581f5f8a84f0cd to your computer and use it in GitHub Desktop.
xcuitest runner
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
UITest: | |
Workspace: 'Test.xcworkspace' | |
Scheme: 'TestUITests' | |
Bundle: 'TestUITests' | |
SearchPaths: | |
- 'TestUITests/UITests/*/*UITests.swift' | |
Device: 'platform=iOS Simulator,name=iPad Air,OS=10.2' | |
PatternMatching: | |
testSuite: 'class\W+(?<class_name>\w*)' | |
testCase: '(?<scenario>(s|S)cenario.*)?\s+\S+\s(?<tags>(((?!@))|@.*))\s+\S+\s(?<test_case>test\w*)' | |
XcodeBuild: | |
- "set -o pipefail && env NSUnbufferedIO=YES" | |
- "xcodebuild clean test" | |
- "-workspace %{workspace} -scheme %{scheme}" | |
- "-derivedDataPath build/UITests" | |
- "-destination \'%{device}\' %{option}" | |
- "| tee build/ui-test.log" | |
- "| xcpretty -r junit -r html" |
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
include UITests | |
desc <<-DOC | |
Run UI test cases using tags | |
Examples: | |
Test multiple tags: rake test:case[app_preview/sleep] | |
Filter out tags: rake test:case[-app_preview] | |
DOC | |
task :case, [:tag] => [:list_case] do |_t, args| | |
UITests.run_tests_using_tags(args[:tag]) | |
end | |
desc 'Run UI test suite using a tag' | |
task :suite, [:tag] => [:list_suite] do |_t, args| | |
UITests.run_tests_using_tags('test_suite', args[:tag]) | |
end | |
desc 'List all Tags' | |
task :list_all_tags do | |
UITests.list_all_tags | |
end | |
# desc 'List test cases that are Tagged' | |
task :list_case, [:tag] do |_t, args| | |
UITests.list_test_cases_with_tags(args[:tag]) | |
end | |
# desc 'List test suite that are Tagged' | |
task :list_suite, [:tag] do |_t, args| | |
UITests.list_test_suite_with_tags(args[:tag]) | |
end | |
task :ci do | |
UITests.run_tests_using_tags(:test_case, ['-flakey_test']) | |
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
require 'json' | |
require 'yaml' | |
module UITests | |
@yaml_data = YAML.load_file('.hive.yml') | |
@workspace = @yaml_data['UITest']['Workspace'] | |
@scheme = @yaml_data['UITest']['Scheme'] | |
@device = @yaml_data['UITest']['Device'] | |
@search_paths = @yaml_data['UITest']['SearchPaths'] | |
@test_bundle = @yaml_data['UITest']['Bundle'] | |
@build_settings = @yaml_data['XcodeBuild'].join(' ') | |
def test_case_commands(tags = []) | |
list_tests(:test_case, tags).map { |list| "-only-testing:#{list}" }.join(' ') | |
end | |
def test_suite_commands | |
list_tests(:test_suite).map { |list| "-only-testing:#{list}" }.join(' ') | |
end | |
def list_all_tags | |
data = filter_data.select { |h| h[:tags] }.map { |h| h[:tags] }.flatten | |
return puts 'No test cases found with that tag' if data.empty? | |
create_table(%w[Num Tags Count], item_count(data)) | |
end | |
def list_test_cases_with_tags(tags) | |
tag_list = tags.is_a?(Array) ? tags : tags.split('/') | |
data = list_tests(:test_case, tag_list) | |
return puts 'No test cases found with that tag' if data.empty? | |
create_grid('Tag:', tags, data) | |
end | |
def list_test_suite_with_tags(tags) | |
tag_list = tags.is_a?(Array) ? tags : tags.split('/') | |
data = list_tests(:test_suite, tag_list) | |
return puts 'No test suite found with that tag' if data.empty? | |
create_grid('Tag:', tags, data) | |
end | |
def run_tests_using_tags(type = :test_case, tags = []) | |
option = type == :test_case ? test_case_commands(tags) : test_suite_commands | |
return puts 'No tests found!' if option.empty? | |
list_test_cases_with_tags(tags) | |
Signal.trap('INT') do | |
puts 'Test interrupted' | |
exit 1 | |
end | |
command = format( | |
@build_settings, | |
workspace: @workspace, | |
scheme: @scheme, | |
device: @device, | |
option: option | |
) | |
system command | |
end | |
private | |
def item_count(data) | |
data.each_with_object(Hash.new(0)) { |word, counts| counts[word] += 1 } | |
end | |
def create_grid(message, tag, data) | |
puts '' | |
puts '-------------' | |
puts '-------------' | |
puts "#{message} #{tag}" | |
puts data | |
puts '-------------' | |
puts '-------------' | |
puts '' | |
end | |
def create_table(header, data) | |
text_format = '%-5s %-20s %-20s' | |
puts text_format % header | |
counts = 0 | |
data.each_with_index do |(num, id, name), i| | |
puts format(text_format, i + 1, num, id, name) | |
counts += id | |
end | |
puts "\nTotal Tests: #{counts}" | |
end | |
def find_ui_test_files | |
folders = File.join(@search_paths) | |
Dir.glob(folders) | |
end | |
# Parse test files and output the data as a Hash | |
# file: "TestUITests/UITests/Legals/EulaUITests.swift", | |
# test_suite: "EulaUITests", | |
# scenario: "Scenario:", | |
# tags: [Tags], | |
# test_case: "testRetainingEulaAcceptance" | |
def construct_test_case_data(file) | |
data = [] | |
test_file = File.open(file, 'r:UTF-8').read | |
test_suite = test_file.scan(/#{@yaml_data['UITest']['PatternMatching']['testSuite']}/).flatten.first | |
test_cases = test_file.scan(/#{@yaml_data['UITest']['PatternMatching']['testCase']}/) | |
test_cases.each do |test_case| | |
test_data = Hash.new { |hash, key| hash[key] = [] } | |
test_data[:file] = file | |
test_data[:test_suite] = test_suite | |
test_data[:scenario] = test_case[0] | |
test_data[:tags] = test_case[1].tr('@', '').split(' ') || [] | |
test_data[:test_case] = test_case[2] | |
data << test_data | |
end | |
data | |
end | |
def filter_data(tags = []) | |
filtered_out_tags = tags.select { |tag| tag.include?('-') }.map { |e| e.tr('-', '') } | |
available_tags = tags.map { |tag| tag.tr('-', '') } - filtered_out_tags | |
test_data = generate_data.flatten | |
data = available_tags.empty? ? test_data : test_data.select { |item| (item[:tags] & tags).any? } | |
data.reject { |item| (item[:tags] & filtered_out_tags).any? } | |
end | |
# @option opts [Symbol] :test_case Scan for Test cases | |
# @option opts [Symbol] :test_suite Scan for Test Suites | |
def list_tests(type = :test_case, tags = []) | |
data = [] | |
filter_data(tags).each do |match| | |
option = case type | |
when :test_case | |
"#{@test_bundle}/#{match[:test_suite]}/#{match[:test_case]}" | |
else | |
"#{@test_bundle}/#{match[:test_suite]}" | |
end | |
data << option | |
end | |
data | |
end | |
def generate_data | |
data = [] | |
find_ui_test_files.each do |file| | |
test_case = construct_test_case_data(file) | |
data << test_case unless test_case.empty? | |
end | |
data | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment