Skip to content

Commit 8bd9640

Browse files
committed
Issue #467: iOS support globs for test-targets
1 parent b74fdab commit 8bd9640

7 files changed

Lines changed: 118 additions & 31 deletions

File tree

test_runner/src/main/kotlin/ftl/args/IosArgs.kt

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import ftl.args.ArgsHelper.createGcsBucket
66
import ftl.args.ArgsHelper.createJunitBucket
77
import ftl.args.ArgsHelper.evaluateFilePath
88
import ftl.args.ArgsHelper.mergeYmlMaps
9-
import ftl.args.ArgsHelper.validateTestMethods
109
import ftl.args.ArgsHelper.yamlMapper
1110
import ftl.args.ArgsToString.devicesToString
1211
import ftl.args.ArgsToString.listToString
@@ -62,13 +61,10 @@ class IosArgs(
6261

6362
// computed properties not specified in yaml
6463
override val testShardChunks: List<List<String>> by lazy {
64+
if (disableSharding) return@lazy listOf(emptyList<String>())
65+
6566
val validTestMethods = Xctestrun.findTestNames(xctestrunFile)
66-
validateTestMethods(testTargets, validTestMethods, "xctest binary")
67-
val testsToShard = if (testTargets.isEmpty()) {
68-
validTestMethods
69-
} else {
70-
testTargets
71-
}.distinct()
67+
val testsToShard = filterTests(validTestMethods, testTargets).distinct()
7268

7369
ArgsHelper.calculateShards(testsToShard, this)
7470
}
@@ -162,3 +158,19 @@ ${listToString(testTargets)}
162158
}
163159
}
164160
}
161+
162+
fun filterTests(validTestMethods: List<String>, testTargets: List<String>): List<String> {
163+
if (testTargets.isEmpty()) {
164+
return validTestMethods
165+
}
166+
167+
return validTestMethods.filter { test ->
168+
testTargets.forEach { target ->
169+
if (test.matches(target.toRegex())) {
170+
return@filter true
171+
}
172+
}
173+
174+
return@filter false
175+
}
176+
}

test_runner/src/main/kotlin/ftl/gc/GcIosTestMatrix.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ object GcIosTestMatrix {
4040
val gcsBucket = args.resultsBucket
4141
val matrixGcsSuffix = join(runGcsPath, shardCounter.next())
4242
val matrixGcsPath = join(gcsBucket, matrixGcsSuffix)
43-
val methods = args.testShardChunks.elementAt(testShardsIndex)
4443

4544
// Parameterized tests on iOS don't shard correctly.
4645
// Avoid changing Xctestrun file when disableSharding is on.
4746
val generatedXctestrun = if (args.disableSharding) {
4847
xcTestParsed.toByteArray()
4948
} else {
49+
val methods = args.testShardChunks.elementAt(testShardsIndex)
5050
Xctestrun.rewrite(xcTestParsed, methods)
5151
}
52+
5253
val xctestrunFileGcsPath = GcStorage.uploadXCTestFile(args, gcsBucket, matrixGcsSuffix, generatedXctestrun)
5354

5455
val iOSXCTest = IosXcTest()

test_runner/src/test/kotlin/ftl/args/IosArgsFileTest.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class IosArgsFileTest {
2727
private val xctestrunZip = getPath("src/test/kotlin/ftl/fixtures/tmp/EarlGreyExample.zip")
2828
private val xctestrunFile =
2929
getPath("src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos12.1-arm64e.xctestrun")
30-
private val testName = "EarlGreyExampleMixedTests/testBasicSelection"
30+
private val testName = "EarlGreyExampleSwiftTests/testLayout"
3131
// NOTE: Change working dir to '%MODULE_WORKING_DIR%' in IntelliJ to match gradle for this test to pass.
3232
@Test
3333
fun configLoadsSuccessfully() {
@@ -69,17 +69,16 @@ class IosArgsFileTest {
6969
val config = IosArgs.load(yamlFile2)
7070

7171
val chunk0 = arrayListOf(
72-
"EarlGreyExampleMixedTests/testGrantCameraPermission",
73-
"EarlGreyExampleMixedTests/testGrantMicrophonePermission",
74-
"EarlGreyExampleMixedTests/testBasicSelection1",
75-
"EarlGreyExampleMixedTests/testBasicSelection4"
72+
"EarlGreyExampleSwiftTests/testWithGreyAssertions",
73+
"EarlGreyExampleSwiftTests/testWithInRoot",
74+
"EarlGreyExampleSwiftTests/testWithCondition",
75+
"EarlGreyExampleSwiftTests/testWithCustomFailureHandler"
7676
)
7777

7878
val chunk1 = arrayListOf(
79-
"EarlGreyExampleMixedTests/testGrantCameraPermission",
80-
"EarlGreyExampleMixedTests/testGrantMicrophonePermission",
81-
"EarlGreyExampleMixedTests/testBasicSelection2",
82-
"EarlGreyExampleMixedTests/testBasicSelection3"
79+
"EarlGreyExampleSwiftTests/testWithGreyAssertions",
80+
"EarlGreyExampleSwiftTests/testWithCustomMatcher",
81+
"EarlGreyExampleSwiftTests/testWithCustomAssertion"
8382
)
8483

8584
val testShardChunks = config.testShardChunks

test_runner/src/test/kotlin/ftl/args/IosArgsTest.kt

Lines changed: 85 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class IosArgsTest {
2626
private val testPath = "./src/test/kotlin/ftl/fixtures/tmp/EarlGreyExample.zip"
2727
private val xctestrunFile =
2828
"./src/test/kotlin/ftl/fixtures/tmp/EarlGreyExampleSwiftTests_iphoneos12.1-arm64e.xctestrun"
29+
private val invalidApp = "../test_app/apks/invalid.apk"
2930
private val xctestrunFileAbsolutePath = xctestrunFile.absolutePath()
3031
private val testAbsolutePath = testPath.absolutePath()
3132
private val iosNonDefault = """
@@ -91,10 +92,10 @@ class IosArgsTest {
9192
fun iosArgs_invalidXcodeExits() {
9293
exceptionRule.expectMessage("Xcode 99.9 is not a supported Xcode version")
9394
IosArgs(
94-
GcloudYml(),
95-
IosGcloudYml(IosGcloudYmlParams(test = testPath, xctestrunFile = xctestrunFile, xcodeVersion = "99.9")),
96-
FlankYml(),
97-
IosFlankYml(),
95+
GcloudYml(),
96+
IosGcloudYml(IosGcloudYmlParams(test = testPath, xctestrunFile = xctestrunFile, xcodeVersion = "99.9")),
97+
FlankYml(),
98+
IosFlankYml(),
9899
""
99100
)
100101
}
@@ -256,6 +257,30 @@ IosArgs
256257
}
257258
}
258259

260+
@Test
261+
fun `disableSharding allows using invalid app`() {
262+
val yaml = """
263+
gcloud:
264+
test: $invalidApp
265+
xctestrun-file: $invalidApp
266+
flank:
267+
disableSharding: true
268+
"""
269+
IosArgs.load(yaml).testShardChunks
270+
}
271+
272+
@Test(expected = RuntimeException::class)
273+
fun `Invalid app throws`() {
274+
val yaml = """
275+
gcloud:
276+
test: $invalidApp
277+
xctestrun-file: $invalidApp
278+
flank:
279+
disableSharding: false
280+
"""
281+
IosArgs.load(yaml).testShardChunks
282+
}
283+
259284
// gcloudYml
260285

261286
@Test
@@ -591,4 +616,60 @@ IosArgs
591616
val androidArgs = IosArgs.load(yaml, cli)
592617
assertThat(androidArgs.flakyTestAttempts).isEqualTo(3)
593618
}
619+
620+
private fun getValidTestsSample() = listOf(
621+
"ClassOneTest/testOne",
622+
"ClassOneTest/testTwo",
623+
"ClassOneScreenshots/testOne",
624+
"ClassTwoScreenshots/testTwo",
625+
"ClassThreeTest/testName",
626+
"ClassFourTest/testFour"
627+
)
628+
629+
@Test
630+
fun filterTests_emptyFilter() {
631+
val tests = getValidTestsSample()
632+
val actual = filterTests(tests, emptyList())
633+
634+
assertThat(actual).containsExactlyElementsIn(tests)
635+
}
636+
637+
@Test
638+
fun filterTests_regularFilter() {
639+
val tests = getValidTestsSample()
640+
val filter = listOf("ClassOneTest/testOne", "ClassFourTest/testFour")
641+
val actual = filterTests(tests, filter)
642+
643+
val expected = listOf("ClassOneTest/testOne", "ClassFourTest/testFour")
644+
645+
assertThat(actual).containsExactlyElementsIn(expected)
646+
}
647+
648+
@Test
649+
fun filterTests_starFilter() {
650+
val tests = getValidTestsSample()
651+
val filter = listOf(".*?Test/testOne", ".*?/testFour")
652+
val actual = filterTests(tests, filter)
653+
654+
val expected = listOf(
655+
"ClassOneTest/testOne",
656+
"ClassFourTest/testFour"
657+
)
658+
659+
assertThat(actual).containsExactlyElementsIn(expected)
660+
}
661+
662+
@Test
663+
fun filterTests_starAndRegularFilter() {
664+
val tests = getValidTestsSample()
665+
val filter = listOf(".*?Screenshots/testTwo", "ClassOneTest/testOne")
666+
val actual = filterTests(tests, filter)
667+
668+
val expected = listOf(
669+
"ClassTwoScreenshots/testTwo",
670+
"ClassOneTest/testOne"
671+
)
672+
673+
assertThat(actual).containsExactlyElementsIn(expected)
674+
}
594675
}

test_runner/src/test/kotlin/ftl/fixtures/flank.ios.gcs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ gcloud:
1616

1717
flank:
1818
test-targets:
19-
- EarlGreyExampleMixedTests/testBasicSelection
19+
- EarlGreyExampleSwiftTests/testLayout
2020
testShards: 1
2121
repeatTests: 1

test_runner/src/test/kotlin/ftl/fixtures/flank.ios.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ gcloud:
1313

1414
flank:
1515
test-targets:
16-
- EarlGreyExampleMixedTests/testBasicSelection
16+
- EarlGreyExampleSwiftTests/testLayout
1717
testShards: 1
1818
repeatTests: 1

test_runner/src/test/kotlin/ftl/fixtures/flank2.ios.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@ flank:
1515
testShards: 2
1616
repeatTests: 1
1717
test-targets:
18-
- EarlGreyExampleMixedTests/testGrantCameraPermission
19-
- EarlGreyExampleMixedTests/testGrantMicrophonePermission
20-
- EarlGreyExampleMixedTests/testBasicSelection1
21-
- EarlGreyExampleMixedTests/testBasicSelection2
22-
- EarlGreyExampleMixedTests/testBasicSelection3
23-
- EarlGreyExampleMixedTests/testBasicSelection4
18+
- EarlGreyExampleSwiftTests/testWith.*$
2419
test-targets-always-run:
25-
- EarlGreyExampleMixedTests/testGrantCameraPermission
26-
- EarlGreyExampleMixedTests/testGrantMicrophonePermission
20+
- EarlGreyExampleSwiftTests/testWithGreyAssertions

0 commit comments

Comments
 (0)