unit-tests: Refactor filters in test runner

This commit is contained in:
Ilya Matveev
2017-09-26 16:20:47 +03:00
committed by ilmat192
parent 8fcc4c4f30
commit a539c9251d
4 changed files with 40 additions and 35 deletions
@@ -2,17 +2,20 @@ package konan.test
class GTestLogger : TestLoggerWithStatistics() { class GTestLogger : TestLoggerWithStatistics() {
override fun startTesting(runner: TestRunner) { private val Collection<TestSuite>.totalTestsNotIgnored: Int
super.startTesting(runner) get() = asSequence().filter { !it.ignored }.sumBy { it.testCases.values.count { !it.ignored } }
println("[==========] Running ${runner.totalTests} tests from ${runner.totalSuites} test case.")
// Just hack to deal with the Clion parser. TODO: Remove it after changes in the parser.
println("[----------] Global test environment set-up.")
}
override fun startIteration(runner: TestRunner, iteration: Int) { private val Collection<TestSuite>.totalNotIgnored: Int
get() = filter { !it.ignored }.size
override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>) {
if (runner.iterations != 1) { if (runner.iterations != 1) {
println("\nRepeating all tests (iteration $iteration) . . .\n") println("\nRepeating all tests (iteration $iteration) . . .\n")
} }
super.startIteration(runner, iteration, suites)
println("[==========] Running ${suites.totalTestsNotIgnored} tests from ${suites.totalNotIgnored} test cases.")
// Just hack to deal with the Clion parser. TODO: Remove it after changes in the parser.
println("[----------] Global test environment set-up.")
} }
private fun printResults(timeMillis: Long) = with (statistics) { private fun printResults(timeMillis: Long) = with (statistics) {
@@ -31,7 +34,7 @@ class GTestLogger : TestLoggerWithStatistics() {
} }
} }
override fun finishTesting(runner: TestRunner, timeMillis: Long) = printResults(timeMillis) override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) = printResults(timeMillis)
override fun startSuite(suite: TestSuite) = println("[----------] ${suite.size} tests from ${suite.name}") override fun startSuite(suite: TestSuite) = println("[----------] ${suite.size} tests from ${suite.name}")
@@ -4,7 +4,7 @@ interface TestListener {
fun startTesting(runner: TestRunner) fun startTesting(runner: TestRunner)
fun finishTesting(runner: TestRunner, timeMillis: Long) fun finishTesting(runner: TestRunner, timeMillis: Long)
fun startIteration(runner: TestRunner, iteration: Int) fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>)
fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long)
fun startSuite(suite: TestSuite) fun startSuite(suite: TestSuite)
@@ -20,7 +20,7 @@ interface TestListener {
open class BaseTestListener: TestListener { open class BaseTestListener: TestListener {
override fun startTesting(runner: TestRunner) {} override fun startTesting(runner: TestRunner) {}
override fun finishTesting(runner: TestRunner, timeMillis: Long) {} override fun finishTesting(runner: TestRunner, timeMillis: Long) {}
override fun startIteration(runner: TestRunner, iteration: Int) {} override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>) {}
override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) {} override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) {}
override fun startSuite(suite: TestSuite) {} override fun startSuite(suite: TestSuite) {}
override fun finishSuite(suite: TestSuite, timeMillis: Long) {} override fun finishSuite(suite: TestSuite, timeMillis: Long) {}
@@ -1,23 +1,16 @@
package konan.test package konan.test
interface TestLogger: TestListener { interface TestLogger: TestListener {
fun logTestList(runner: TestRunner) fun logTestList(runner: TestRunner, suites: Collection<TestSuite>)
fun log(message: String) fun log(message: String)
} }
open class BaseTestLogger: BaseTestListener(), TestLogger { open class BaseTestLogger: BaseTestListener(), TestLogger {
protected val TestRunner.totalTests
get() = filterTests().filter { !it.ignored }.size
protected val TestRunner.totalSuites
get() = suites.filter { !it.ignored }.size
override fun log(message: String) = println(message) override fun log(message: String) = println(message)
override fun logTestList(runner: TestRunner) { override fun logTestList(runner: TestRunner, suites: Collection<TestSuite>) {
runner.filterTests().groupBy { it.suite }.forEach { (suite, tests) -> suites.forEach { suite ->
println("${suite.name}.") println("${suite.name}.")
tests.forEach { suite.testCases.values.forEach {
println(" ${it.name}") println(" ${it.name}")
} }
} }
@@ -29,7 +22,7 @@ open class TestLoggerWithStatistics: BaseTestLogger() {
protected val statistics = MutableTestStatistics() protected val statistics = MutableTestStatistics()
override fun startTesting(runner: TestRunner) = statistics.reset() override fun startTesting(runner: TestRunner) = statistics.reset()
override fun startIteration(runner: TestRunner, iteration: Int) = statistics.reset() override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>) = statistics.reset()
override fun finishSuite(suite: TestSuite, timeMillis: Long) = statistics.registerSuite() override fun finishSuite(suite: TestSuite, timeMillis: Long) = statistics.registerSuite()
override fun pass(testCase: TestCase, timeMillis: Long) = statistics.registerPass() override fun pass(testCase: TestCase, timeMillis: Long) = statistics.registerPass()
@@ -38,7 +31,7 @@ open class TestLoggerWithStatistics: BaseTestLogger() {
} }
class SilentTestLogger: BaseTestLogger() { class SilentTestLogger: BaseTestLogger() {
override fun logTestList(runner: TestRunner) {} override fun logTestList(runner: TestRunner, suites: Collection<TestSuite>) {}
override fun log(message: String) {} override fun log(message: String) {}
} }
@@ -46,7 +39,8 @@ class SimpleTestLogger: BaseTestLogger() {
override fun startTesting(runner: TestRunner) = println("Starting testing") override fun startTesting(runner: TestRunner) = println("Starting testing")
override fun finishTesting(runner: TestRunner, timeMillis: Long) = println("Testing finished") override fun finishTesting(runner: TestRunner, timeMillis: Long) = println("Testing finished")
override fun startIteration(runner: TestRunner, iteration: Int) = println("Starting iteration: $iteration") override fun startIteration(runner: TestRunner, iteration: Int, suites: Collection<TestSuite>) =
println("Starting iteration: $iteration")
override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) = override fun finishIteration(runner: TestRunner, iteration: Int, timeMillis: Long) =
println("Iteration finished: $iteration") println("Iteration finished: $iteration")
@@ -20,14 +20,19 @@ object TestRunner {
var exitCode = 0 var exitCode = 0
private set private set
private val TestCase.matchFilters: Boolean class FilteredSuite(val innerSuite: TestSuite): TestSuite by innerSuite {
get() = filters.map { it(this) }.all { it }
private val TestSuite.testCasesFiltered private val TestCase.matchFilters: Boolean
get() = testCases.values.filter { it.matchFilters } get() = filters.map { it(this) }.all { it }
// TODO: We can cache it. override val size: Int
fun filterTests(): Collection<TestCase> = suites.flatMap { it.testCasesFiltered } get() = testCases.size
override val testCases: Map<String, TestCase> = innerSuite.testCases.filter { it.value.matchFilters }
override fun toString() = innerSuite.toString()
}
private fun filterSuites(): Collection<TestSuite> = suites.map { FilteredSuite(it) }
fun register(suite: TestSuite) = suites_.add(suite) fun register(suite: TestSuite) = suites_.add(suite)
fun register(suites: Iterable<TestSuite>) = suites_.addAll(suites) fun register(suites: Iterable<TestSuite>) = suites_.addAll(suites)
@@ -79,7 +84,7 @@ object TestRunner {
when (arg.size) { when (arg.size) {
1 -> when (arg[0]) { 1 -> when (arg[0]) {
"--gtest_list_tests", "--gtest_list_tests",
"--ktest_list_tests" -> { logger.logTestList(this); result = false } "--ktest_list_tests" -> { logger.logTestList(this, filterSuites()); result = false }
"-h", "-h",
"--help" -> { logger.log(help); result = false } "--help" -> { logger.log(help); result = false }
else -> throw IllegalArgumentException("Unknown option: $it\n$help") else -> throw IllegalArgumentException("Unknown option: $it\n$help")
@@ -96,7 +101,9 @@ object TestRunner {
"--ktest_repeat", "--ktest_repeat",
"--gtest_repeat" -> iterations = value.toIntOrNull() ?: "--gtest_repeat" -> iterations = value.toIntOrNull() ?:
throw IllegalArgumentException("Cannot parse number: $value") throw IllegalArgumentException("Cannot parse number: $value")
else -> throw IllegalArgumentException("Unknown option: $it\n$help") else -> if (key.startsWith("--ktest_")) {
throw IllegalArgumentException("Unknown option: $it\n$help")
}
} }
} }
else -> throw IllegalArgumentException("Unknown option: $it\n$help") else -> throw IllegalArgumentException("Unknown option: $it\n$help")
@@ -191,7 +198,7 @@ object TestRunner {
private fun TestSuite.run() { private fun TestSuite.run() {
doBeforeClass() doBeforeClass()
testCasesFiltered.forEach { testCase -> testCases.values.forEach { testCase ->
if (testCase.ignored) { if (testCase.ignored) {
sendToListeners { ignore(testCase) } sendToListeners { ignore(testCase) }
} else { } else {
@@ -210,9 +217,10 @@ object TestRunner {
} }
private fun runIteration(iteration: Int) { private fun runIteration(iteration: Int) {
sendToListeners { startIteration(this@TestRunner, iteration) } val suitesFiltered = filterSuites()
sendToListeners { startIteration(this@TestRunner, iteration, suitesFiltered) }
val iterationTime = measureTimeMillis { val iterationTime = measureTimeMillis {
suites.forEach { suitesFiltered.forEach {
if (it.ignored) { if (it.ignored) {
sendToListeners { ignoreSuite(it) } sendToListeners { ignoreSuite(it) }
} else { } else {