Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion trainer/lib/trainer/test_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ def summaries_to_data(summaries, failures, output_remove_retry_attempts: false)
# Used by store number of passes and failures by identifier
# This is used when Xcode 13 (and up) retries tests
# The identifier is duplicated until test succeeds or max count is reached

# HOWEVER: Swift Testing parameterized tests will show up as duplicate identifiers:
# eg. -[FastlaneTrainerSwiftTestingTests parameterizedExampleShouldFail(value:)]
# Treating those as retry attempts means no param test failures show up in the xml, which is bad:
# https://github.com/fastlane/fastlane/issues/29174
tests_by_identifier = {}

test_rows = all_tests.map do |test|
Expand Down Expand Up @@ -295,15 +300,18 @@ def summaries_to_data(summaries, failures, output_remove_retry_attempts: false)
# Set failure message if failure found
failure = test.find_failure(failures)
if failure
# puts "FAILED"
# puts failure.test_case_name
test_row[:failures] = [{
file_name: "",
line_number: 0,
message: "",
performance_failure: {},
failure_message: failure.failure_message
}]

# puts info[:failure_count]
info[:failure_count] += 1
# puts info[:failure_count]
elsif test.test_status == "Skipped"
test_row[:skipped] = true
info[:skip_count] += 1
Expand Down Expand Up @@ -394,6 +402,7 @@ def parse_content(xcpretty_naming)
guid: current_test["TestSummaryGUID"],
duration: current_test["Duration"]
}

if current_test["FailureSummaries"]
current_row[:failures] = current_test["FailureSummaries"].collect do |current_failure|
{
Expand Down
30 changes: 26 additions & 4 deletions trainer/lib/trainer/xcresult.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,9 +173,15 @@ def all_subtests
end

def find_failure(failures)
sanitizer = proc { |name| name.gsub(/\W/, "_") }
# Used to sanitize both test case name and identifier for reliable comparison
sanitizer = proc do |name|
name.gsub(/\W/, "_"). # replace all non-word characters with an underscore
gsub(/^_+/, ""). # remove leading underscores, generally a result of Swift Testing parameterized tests
gsub(/_+$/, "") # remove trailing underscores, generally a result of Swift Testing parameterized tests
end
sanitized_identifier = sanitizer.call(self.identifier)
if self.test_status == "Failure"
# puts ""
# Tries to match failure on test case name
# Example TestFailureIssueSummary:
# producingTarget: "TestThisDude"
Expand All @@ -186,10 +192,26 @@ def find_failure(failures)
# or identifier: "TestThisDude/testFailureJosh2" (when Objective-C)

found_failure = failures.find do |failure|
# Sanitize both test case name and identifier in a consistent fashion, then replace all non-word
# chars with underscore, and compare them
sanitized_test_case_name = sanitizer.call(failure.test_case_name)
sanitized_identifier == sanitized_test_case_name

# It's possible that identifier would be prefixed with group name for Swift Testing
# but also...do we need strict equality here, or just enough similarity?
# puts "identifier: #{self.identifier}"
# puts "sanitized_identifier:"
# puts sanitized_identifier
# # puts "test_case_name: #{failure.test_case_name}"
# puts "sanitized_test_case_name:"
# puts sanitized_test_case_name
# sanitized_identifier.end_with?(sanitized_test_case_name)
# puts sanitized_identifier == sanitized_test_case_name
# sanitized_identifier == sanitized_test_case_name
# puts failure.inspect
puts sanitized_identifier
puts sanitized_test_case_name
# puts sanitized_identifier == sanitized_test_case_name
sanitized_identifier == sanitized_test_case_name || sanitized_identifier.end_with?(sanitized_test_case_name)
# puts sanitized_identifier.end_with?(sanitized_test_case_name)
# sanitized_identifier.end_with?(sanitized_test_case_name)
end
return found_failure
else
Expand Down
26 changes: 26 additions & 0 deletions trainer/spec/fixtures/SwiftTesting.junit
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites tests="2" failures="1">
<testsuite name="FastlaneTrainerSwiftTestingTests" tests="2" failures="1" skipped="0" time="0.0024025440216064453">
<properties>
<property name="Configuration" value="Configuration 1"/>
</properties>
<testcase classname="NestedTests" name="nestedExampleShouldFail()" time="0.001239776611328125">
<failure message="Expectation failed: true == false (/Users/jhagglund/dev2/FastlaneTrainerSwiftTesting/FastlaneTrainerSwiftTestingTests/FastlaneTrainerSwiftTestingTests.swift#EndingLineNumber=18&amp;StartingLineNumber=18)">
</failure>
</testcase>
<testcase classname="NestedTests" name="nestedExampleShouldFail()" time="0.0004439353942871094">
<failure message="Expectation failed: true == false (/Users/jhagglund/dev2/FastlaneTrainerSwiftTesting/FastlaneTrainerSwiftTestingTests/FastlaneTrainerSwiftTestingTests.swift#EndingLineNumber=18&amp;StartingLineNumber=18)">
</failure>
</testcase>
<testcase classname="NestedTests" name="nestedExampleShouldFail()" time="9.012222290039062e-05">
<failure message="Expectation failed: true == false (/Users/jhagglund/dev2/FastlaneTrainerSwiftTesting/FastlaneTrainerSwiftTestingTests/FastlaneTrainerSwiftTestingTests.swift#EndingLineNumber=18&amp;StartingLineNumber=18)">
</failure>
</testcase>
<testcase classname="FastlaneTrainerSwiftTestingTests" name="topLevelShouldPass()" time="0.00015282630920410156">
</testcase>
<testcase classname="FastlaneTrainerSwiftTestingTests" name="topLevelShouldPass()" time="0.0004169940948486328">
</testcase>
<testcase classname="FastlaneTrainerSwiftTestingTests" name="topLevelShouldPass()" time="5.888938903808594e-05">
</testcase>
</testsuite>
</testsuites>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"name":"testmanagerd.log","type":1}]
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
29 changes: 29 additions & 0 deletions trainer/spec/fixtures/SwiftTesting.xcresult/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>dateCreated</key>
<date>2025-03-01T00:58:58Z</date>
<key>externalLocations</key>
<array/>
<key>rootId</key>
<dict>
<key>hash</key>
<string>0~bwxBNsVr6SQCABg0yK_RRGiChrFqh24mJjYprxgKT04u2OL4CPJ4fcFTHEgv4VwiykX8NN2Ee7q-0K1iykoEIA==</string>
</dict>
<key>storage</key>
<dict>
<key>backend</key>
<string>fileBacked2</string>
<key>compression</key>
<string>standard</string>
</dict>
<key>version</key>
<dict>
<key>major</key>
<integer>3</integer>
<key>minor</key>
<integer>53</integer>
</dict>
</dict>
</plist>
Binary file not shown.
52 changes: 29 additions & 23 deletions trainer/spec/junit_generator_spec.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
describe Trainer do
describe Trainer::JunitGenerator do
it "works for a valid .plist file" do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid1.plist")
junit = File.read("./trainer/spec/fixtures/Valid1.junit")
expect(tp.to_junit).to eq(junit)
end
# it "works for a valid .plist file" do
# tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid1.plist")
# junit = File.read("./trainer/spec/fixtures/Valid1.junit")
# expect(tp.to_junit).to eq(junit)
# end

it "works for a valid .plist file and xcpretty naming" do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid1.plist", { xcpretty_naming: true })
junit = File.read("./trainer/spec/fixtures/Valid1-x.junit")
expect(tp.to_junit).to eq(junit)
end
# it "works for a valid .plist file and xcpretty naming" do
# tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid1.plist", { xcpretty_naming: true })
# junit = File.read("./trainer/spec/fixtures/Valid1-x.junit")
# expect(tp.to_junit).to eq(junit)
# end

it "works for a with all tests passing" do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid2.plist")
junit = File.read("./trainer/spec/fixtures/Valid2.junit")
expect(tp.to_junit).to eq(junit)
end
# it "works for a with all tests passing" do
# tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid2.plist")
# junit = File.read("./trainer/spec/fixtures/Valid2.junit")
# expect(tp.to_junit).to eq(junit)
# end

it "works for a with all tests passing and xcpretty naming" do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid2.plist", { xcpretty_naming: true })
junit = File.read("./trainer/spec/fixtures/Valid2-x.junit")
expect(tp.to_junit).to eq(junit)
end
# it "works for a with all tests passing and xcpretty naming" do
# tp = Trainer::TestParser.new("./trainer/spec/fixtures/Valid2.plist", { xcpretty_naming: true })
# junit = File.read("./trainer/spec/fixtures/Valid2-x.junit")
# expect(tp.to_junit).to eq(junit)
# end

# it "works with an xcresult", requires_xcode: true do
# tp = Trainer::TestParser.new("./trainer/spec/fixtures/Test.test_result.xcresult")
# junit = File.read("./trainer/spec/fixtures/XCResult.junit")
# expect(tp.to_junit).to eq(junit)
# end

it "works with an xcresult", requires_xcode: true do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/Test.test_result.xcresult")
junit = File.read("./trainer/spec/fixtures/XCResult.junit")
it "works with an xcresult from Swfit Testing", requires_xcode: true do
tp = Trainer::TestParser.new("./trainer/spec/fixtures/SwiftTesting.xcresult")
junit = File.read("./trainer/spec/fixtures/SwiftTesting.junit")
expect(tp.to_junit).to eq(junit)
end
end
Expand Down
Loading