Class: Fastlane::Saucectl::XCTest

Inherits:
Object
  • Object
show all
Includes:
FileUtils
Defined in:
lib/fastlane/plugin/saucectl/helper/xctest.rb

Overview

This class is responsible for creating test execution plans for ios applications and will distribute tests that will be be executed via the cloud provider.

Constant Summary collapse

UI =
FastlaneCore::UI
TEST_FUNCTION_REGEX =
/(test+[A-Z][a-zA-Z]+)[(][)]/.freeze

Constants included from FileUtils

FileUtils::CLASS_NAME_REGEX, FileUtils::FILE_TYPE_REGEX

Instance Method Summary collapse

Methods included from FileUtils

#find, #read_file, #search_retrieve_test_classes, #syscall

Constructor Details

#initialize(config) ⇒ XCTest

Returns a new instance of XCTest.



16
17
18
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 16

def initialize(config)
  @config = config
end

Instance Method Details

#all_testsObject



126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 126

def all_tests
  test_details = []
  test_dir = Dir["**/#{test_target}"][0]
  search_retrieve_test_classes(test_dir).each do |f|
    next unless File.basename(f) =~ CLASS_NAME_REGEX

    test_details << { class: File.basename(f).gsub(FILE_TYPE_REGEX, ""), tests: tests_from(f) }
  end

  strip_empty(test_details)
end

#fetch_disabled_testsObject



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 108

def fetch_disabled_tests
  skipped = fetch_test_plan["skippedTests"]
  ui_tests = []
  skipped.each do |item|
    if item.include?('/')
      test_case = item.gsub('/', ' ').split
      ui_tests << sort_ui_tests(test_case[0], test_case[1])
    else
      ui_tests << scan_test_class(item)
    end
  end
  ui_tests
end

#fetch_selected_testsObject



86
87
88
89
90
91
92
93
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 86

def fetch_selected_tests
  ui_tests = []
  fetch_test_plan["selectedTests"].each do |test|
    test_case = test.gsub('/', ' ').split
    ui_tests << { class: test_case[0], tests: [test_case[1].gsub(/[()]/, "").to_s] }
  end
  ui_tests
end

#fetch_target_from_test_planObject



38
39
40
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 38

def fetch_target_from_test_plan
  fetch_test_plan["target"]["name"]
end

#fetch_test_planObject



32
33
34
35
36
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 32

def fetch_test_plan
  plan_path = Dir["**/#{@config[:test_plan]}.xctestplan"][0]
  selected = File.read(plan_path)
  JSON.parse(selected)["testTargets"][0]
end

#scan_test_class(cls) ⇒ Object



138
139
140
141
142
143
144
145
146
147
148
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 138

def scan_test_class(cls)
  test_details = []
  test_dir = Dir["**/#{test_target}"][0]
  search_retrieve_test_classes(test_dir).each do |f|
    next unless File.basename(f) =~ /#{cls}/

    test_details << { class: File.basename(f).gsub(FILE_TYPE_REGEX, ""), tests: tests_from(f) }
  end

  strip_empty(test_details)
end

#sort_ui_tests(cls, test_case) ⇒ Object



122
123
124
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 122

def sort_ui_tests(cls, test_case)
  { class: cls, tests: test_case.gsub(/[()]/, "").to_s }
end

#strip_empty(test_details) ⇒ Object



159
160
161
162
163
164
165
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 159

def strip_empty(test_details)
  tests = []
  test_details.each do |test|
    tests << test unless test[:tests].size.zero?
  end
  tests
end

#strip_skipped(all_tests) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 95

def strip_skipped(all_tests)
  enabled_ui_tests = []
  skipped_tests = fetch_disabled_tests
  all_tests.each do |tests|
    tests[:tests].each do |test|
      unless skipped_tests.to_s.include?(test)
        enabled_ui_tests << { class: tests[:class].to_s, tests: [test] }
      end
    end
  end
  enabled_ui_tests
end

#test_dataObject



42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 42

def test_data
  if test_plan_exists?
    valid_test_plan?
    if fetch_test_plan.include?("skippedTests")
      strip_skipped(all_tests)
    else
      fetch_selected_tests
    end
  else
    all_tests
  end
end

#test_distributionObject



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 59

def test_distribution
  test_distribution_check
  tests_arr = []

  test_distribution = @config[:test_plan].nil? ? @config[:test_distribution] : 'testPlan'
  case test_distribution
  when 'testCase', 'testPlan'
    test_data.each do |type|
      type[:tests].each { |test| tests_arr << "#{test_target}.#{type[:class]}/#{test}" }
    end
  else
    test_data.each do |type|
      tests_arr << "#{test_target}.#{type[:class]}"
    end
  end
  tests_arr.uniq
end

#test_distribution_checkObject



77
78
79
80
81
82
83
84
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 77

def test_distribution_check
  return @config[:test_distribution] if @config[:test_distribution].kind_of?(Array)

  distribution_types = %w[class testCase shard]
  unless distribution_types.include?(@config[:test_distribution]) || @config[:test_distribution].nil?
    UI.user_error!("#{@config[:test_distribution]} is not a valid method of test distribution. \n Supported types for iOS: \n #{distribution_types}")
  end
end

#test_plan_exists?Boolean

Returns:

  • (Boolean)


20
21
22
23
24
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 20

def test_plan_exists?
  File.exist?(Dir["**/#{@config[:test_plan]}.xctestplan"][0])
rescue StandardError
  false
end

#test_targetObject



55
56
57
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 55

def test_target
  @config[:test_target].nil? ? fetch_target_from_test_plan : @config[:test_target]
end

#tests_from(path) ⇒ Object



150
151
152
153
154
155
156
157
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 150

def tests_from(path)
  stdout, = find(path, "func")
  test_cases = []
  stdout.split.each do |line|
    test_cases << line.match(TEST_FUNCTION_REGEX).to_s.gsub(/[()]/, "") if line =~ TEST_FUNCTION_REGEX
  end
  test_cases
end

#valid_test_plan?Boolean

Returns:

  • (Boolean)


26
27
28
29
30
# File 'lib/fastlane/plugin/saucectl/helper/xctest.rb', line 26

def valid_test_plan?
  File.exist?(Dir["**/#{@config[:test_plan]}.xctestplan"][0])
rescue StandardError
  UI.user_error!("#{@config[:test_plan]} was not found in workspace")
end