Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: [IT] Add test cases #1316

Merged
merged 32 commits into from
Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
003d082
Improve integration tests
pawelpasterz Nov 7, 2020
69f9f3f
Add full IT
pawelpasterz Nov 10, 2020
abf43cf
Major refactor
pawelpasterz Nov 11, 2020
183760a
remove
pawelpasterz Nov 11, 2020
d06c2ac
Update gitignore
pawelpasterz Nov 11, 2020
7bea932
Update template
pawelpasterz Nov 11, 2020
3512e49
Add tests
pawelpasterz Nov 12, 2020
3f26e3e
Linting
pawelpasterz Nov 12, 2020
ac1d736
Remove redundant changes
pawelpasterz Nov 12, 2020
bb72e74
Refactor multiple apks case
pawelpasterz Nov 12, 2020
a8ecceb
Fix filter
pawelpasterz Nov 12, 2020
e3370a1
Cr fixes and turn off ios test on windows
adamfilipow92 Nov 13, 2020
b842121
Fix android filtered integration test on windows
adamfilipow92 Nov 13, 2020
31ef140
Fix RunTimeout integration test on windows
adamfilipow92 Nov 13, 2020
526d586
Fix test filtering on windows
adamfilipow92 Nov 13, 2020
0555f87
Fix Sanity test on windows
adamfilipow92 Nov 13, 2020
4e93e1c
Fix IgnoreFailed tests on windows
adamfilipow92 Nov 13, 2020
5447245
Update IntergrationTestsUtils.kt
adamfilipow92 Nov 13, 2020
6e408f5
Fix multiple apks it on windows
adamfilipow92 Nov 13, 2020
d6ebc8a
Fix multiple apks tests on windows
adamfilipow92 Nov 13, 2020
687b80b
Update TestFilteringIT-compare
adamfilipow92 Nov 16, 2020
869873b
Update SanityRoboIT-compare
adamfilipow92 Nov 16, 2020
f7f2d48
Review changes
pawelpasterz Nov 17, 2020
768d27e
Update compare files
pawelpasterz Nov 19, 2020
fb2c090
Fix integration tests
adamfilipow92 Nov 20, 2020
ee8190f
Fix multiple devices and multiple apk tests
adamfilipow92 Nov 23, 2020
7d22941
Fix integration tests on windows
adamfilipow92 Nov 24, 2020
1b5df51
Update MultipleDevicesIT.kt
adamfilipow92 Nov 24, 2020
93fbabc
Cr fixes
adamfilipow92 Nov 25, 2020
075ff25
Cr changes
adamfilipow92 Nov 25, 2020
99df937
Update compare and yml files
pawelpasterz Dec 1, 2020
8a302c8
Update compare files
pawelpasterz Dec 3, 2020
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
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ Fixes #

- [ ] Documented
- [ ] Unit tested
- [ ] Integration tests updated
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ results
xcuserdata/
test_projects/ios/*/build*
android_shards.json
ios_shards.json
*.log
25 changes: 25 additions & 0 deletions integration_tests/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
java
kotlin(Plugins.Kotlin.PLUGIN_JVM)
Expand Down Expand Up @@ -31,6 +34,7 @@ detekt {
dependencies {
implementation(kotlin("stdlib"))
testImplementation(Dependencies.JUNIT)
testImplementation(Dependencies.TRUTH)
detektPlugins(Dependencies.DETEKT_FORMATTING)
}

Expand All @@ -44,4 +48,25 @@ tasks.test {
systemProperty("working-directory", System.getProperty("working-directory"))
systemProperty("output-pattern", System.getProperty("output-pattern"))
systemProperty("expected-output-code", System.getProperty("expected-output-code"))
filter {
excludeTestsMatching("*IT")
}
}

tasks.register<Test>("integrationTests") {
group = "Verification"
description = "Runs flank integration tests"
filter {
includeTestsMatching("*IT")
}
testLogging {
events("skipped", "failed")
exceptionFormat = TestExceptionFormat.FULL
}
maxParallelForks = Runtime.getRuntime().availableProcessors() / 2
}

val compileTestKotlin: KotlinCompile by tasks
compileTestKotlin.kotlinOptions {
freeCompilerArgs = listOf("-Xinline-classes")
}
2 changes: 1 addition & 1 deletion integration_tests/src/test/kotlin/FlankCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ data class FlankCommand(val flankPath: String, val ymlPath: String, val params:

private fun FlankCommand.create() = "java -jar $flankPath ${params.joinToString(separator = " ")} -c=$ymlPath"

fun FlankCommand.run(workingDirectory: String) = create().runCommand(File(workingDirectory))
fun FlankCommand.run(workingDirectory: String, testSuite: String = "") = create().runCommand(File(workingDirectory), testSuite)
50 changes: 50 additions & 0 deletions integration_tests/src/test/kotlin/integration/AllTestFilteredIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Assume.assumeFalse
import run
import org.junit.Test

class AllTestFilteredIT {
private val name = this::class.java.simpleName

@Test
fun `filter all tests - android`() {
val name = "$name-android"
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/all_test_filtered_android.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 1)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertNoOutcomeSummary(resOutput)
}

@Test
fun `filter all tests - ios`() {
assumeFalse(isWindows)
val name = "$name-ios"
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/all_test_filtered_ios.yml",
params = iosRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 0)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertNoOutcomeSummary(resOutput)
}
}
29 changes: 29 additions & 0 deletions integration_tests/src/test/kotlin/integration/IgnoreFailedIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import run

class IgnoreFailedIT {
private val name = this::class.java.simpleName
@Test
fun `return with exit code 0 for failed tests`() {
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/flank_android_ignore_failed.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 0)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertContainsOutcomeSummary(resOutput) {
failure = 1
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package integration

import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertEquals
import utils.ProcessResult
import java.io.File

const val FLANK_JAR_PATH = "../test_runner/build/libs/flank.jar"
const val CONFIGS_PATH = "./src/test/resources/cases"

val androidRunCommands = listOf("firebase", "test", "android", "run")
val iosRunCommands = listOf("firebase", "test", "ios", "run")

fun assertExitCode(result: ProcessResult, expectedExitCode: Int) = assertEquals(
"""
Exit code:
expected $expectedExitCode
actual ${result.exitCode}
Output:
${result.output}
""".trimIndent(),
expectedExitCode,
result.exitCode
)

@Suppress("SetterBackingFieldAssignment")
data class OutcomeSummary(val matcher: MutableMap<TestOutcome, Int> = mutableMapOf<TestOutcome, Int>().withDefault { 0 }) {
var success: Int = 0
set(value) {
matcher[TestOutcome.SUCCESS] = value
}

var failure: Int = 0
set(value) {
matcher[TestOutcome.FAILURE] = value
}

var flaky: Int = 0
set(value) {
matcher[TestOutcome.FLAKY] = value
}
}

fun assertContainsUploads(input: String, vararg uploads: String) = uploads.forEach {
assertThat(input).contains("Uploading $it")
}

fun assertContainsOutcomeSummary(input: String, block: OutcomeSummary.() -> Unit) =
OutcomeSummary().apply(block).matcher.entries.forEach { (outcome, times) ->
val actual = outcome.regex.findAll(input).toList().size
if (actual != times) throw AssertionError("""
|Incorrect number of ${outcome.name}
| expected: $times
| but was: $actual
|Output:
|${"┌[\\s\\S]*┘".toRegex().find(input)?.value?.trimIndent()}
""".trimMargin()
)
}

fun assertNoOutcomeSummary(input: String) {
if ("┌[\\s\\S]*┘".toRegex().matches(input)) throw AssertionError("There should be no outcome table.")
}

enum class TestOutcome(val regex: Regex) {
SUCCESS(fromCommon("success")),
FLAKY(fromCommon("flaky")),
FAILURE(fromCommon("failure")),
}

private val fromCommon =
{ outcome: String ->
if (isWindows) "\\?\\s$outcome\\s\\?\\smatrix-[a-zA-Z0-9]*\\s\\?\\s*[a-zA-Z0-9-]*\\s*\\?\\s[a-zA-Z0-9\\s,-]*\\s*\\?".toRegex()
else "│\\s$outcome\\s│\\s${"matrix"}-[a-zA-Z0-9]*\\s│\\s*[a-zA-Z0-9-]*\\s*│\\s[a-zA-Z0-9\\s,-]*\\s*│".toRegex()
}

fun String.removeUnicode() = replace("\u001B\\[\\d{1,2}m".toRegex(), "").trimIndent()

fun findInCompare(name: String) = File("./src/test/resources/compare/$name-compare").readText().trimIndent()

private val osName = System.getProperty("os.name")?.toLowerCase() ?: ""

val isWindows: Boolean by lazy {
osName.indexOf("win") >= 0
}
34 changes: 34 additions & 0 deletions integration_tests/src/test/kotlin/integration/MultipleApksIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import run

class MultipleApksIT {
private val name = this::class.java.simpleName

@Test
fun `flank full option run`() {
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/flank_android_multiple_apk.yml",
params = androidRunCommands
).run("./", name)

assertExitCode(result, 10)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertContainsUploads(resOutput,
"app-multiple-success-debug-androidTest.apk",
"app-multiple-error-debug-androidTest.apk",
"MainActivity_robo_script.json"
)

assertContainsOutcomeSummary(resOutput) {
success = 3
failure = 1
}
}
}
37 changes: 37 additions & 0 deletions integration_tests/src/test/kotlin/integration/MultipleDevicesIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import run
import org.junit.Test

class MultipleDevicesIT {
private val name = this::class.java.simpleName

@Test
fun `run tests on multiple devices - android`() {
val name = "$name-android"
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/flank_android_multiple_devices.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 10)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertContainsUploads(resOutput,
"app-multiple-success-debug-androidTest.apk",
"app-multiple-error-debug-androidTest.apk",
"performanceMetrics.json"
)
assertContainsOutcomeSummary(resOutput) {
success = 6
failure = 3
}
}
}
27 changes: 27 additions & 0 deletions integration_tests/src/test/kotlin/integration/RunTimeoutIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import run

class RunTimeoutIT {
private val name = this::class.java.simpleName
@Test
fun `cancel test run on timeout`() {
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/flank_android_run_timeout.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 1)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertNoOutcomeSummary(resOutput)
}
}
30 changes: 30 additions & 0 deletions integration_tests/src/test/kotlin/integration/SanityRoboIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import run

class SanityRoboIT {
private val name = this::class.java.simpleName

@Test
fun `sanity robo`() {
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/sanity_robo.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = this::class.java.simpleName
)

assertExitCode(result, 0)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertContainsOutcomeSummary(resOutput) {
success = 1
}
}
}
30 changes: 30 additions & 0 deletions integration_tests/src/test/kotlin/integration/TestFilteringIT.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package integration

import FlankCommand
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import run

class TestFilteringIT {
private val name = this::class.java.simpleName

@Test
fun `run test from only one apk`() {
val result = FlankCommand(
flankPath = FLANK_JAR_PATH,
ymlPath = "$CONFIGS_PATH/test_filtering_android.yml",
params = androidRunCommands
).run(
workingDirectory = "./",
testSuite = name
)

assertExitCode(result, 0)

val resOutput = result.output.removeUnicode()
assertThat(resOutput).containsMatch(findInCompare(name))
assertContainsOutcomeSummary(resOutput) {
success = 1
}
}
}
Loading