unit-tests: Add gtest-like output

This commit is contained in:
Ilya Matveev
2017-09-20 15:03:26 +03:00
committed by ilmat192
parent fbb9163abf
commit f3fd6579a0
5 changed files with 120 additions and 23 deletions
@@ -8,15 +8,15 @@ class SimpleTestListener: TestListener {
private set
override fun startTesting(runner: TestRunner) = println("Starting testing")
override fun endTesting(runner: TestRunner) = println("Testing finished")
override fun endTesting(runner: TestRunner, timeMillis: Long) = println("Testing finished")
override fun startSuite(suite: TestSuite) = println("Starting test suite: $suite")
override fun endSuite(suite: TestSuite) = println("Test suite finished: $suite")
override fun endSuite(suite: TestSuite, timeMillis: Long) = println("Test suite finished: $suite")
override fun ignoreSuite(suite: TestSuite) = println("Test suite ignored: $suite")
override fun start(testCase: TestCase) = println("Starting test case: $testCase")
override fun pass(testCase: TestCase) = println("Passed: $testCase")
override fun fail(testCase: TestCase, e: Throwable) {
override fun pass(testCase: TestCase, timeMillis: Long) = println("Passed: $testCase")
override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) {
println("Failed: $testCase. Exception:")
e.printStackTrace()
hasFails = true
@@ -25,7 +25,7 @@ class SimpleTestListener: TestListener {
}
fun main(args:Array<String>) {
val listener = SimpleTestListener()
val listener = GTestListener()
TestRunner.run(listener)
exitProcess( if (listener.hasFails) -1 else 0 )
exitProcess( if (listener.hasFailedTests) -1 else 0 )
}
@@ -0,0 +1,67 @@
package konan.test
val TestRunner.totalTests
get() = suites.map { it.size }.reduce { sum, size -> sum + size }
val TestRunner.totalSuites
get() = suites.size
class GTestListener: TestListener, AbstractTestStatistics() {
private val TestCase.prettyName get() = "${suite.name}.$name"
private val failedTests_ = mutableListOf<TestCase>()
private var totalSuites = 0
override fun startTesting(runner: TestRunner) {
println("[==========] Running ${runner.totalTests} tests from ${runner.totalSuites} test case.")
println("[----------] Global test environment set-up.") // TODO: just emulation
}
private fun printResults(timeMillis: Long) {
println("[----------] Global test environment tear-down")
println("[==========] $total tests from $totalSuites test cases ran. ($timeMillis ms total)")
println("[ PASSED ] $passed tests.")
if (hasFailedTests) {
println("[ FAILED ] $failed tests, listed below:")
failedTests.forEach {
println("[ FAILED ] ${it.prettyName}")
}
println("\n$failed FAILED TESTS")
}
if (ignored != 0) {
println("YOU HAVE $ignored DISABLED TEST(S)")
}
}
override fun endTesting(runner: TestRunner, timeMillis: Long) = printResults(timeMillis)
override fun startSuite(suite: TestSuite) = println("[----------] ${suite.size} tests from ${suite.name}")
override fun endSuite(suite: TestSuite, timeMillis: Long) {
totalSuites++
println("[----------] ${suite.size} tests from ${suite.name} ($timeMillis ms total)\n")
}
override fun ignoreSuite(suite: TestSuite) {}
override fun start(testCase: TestCase) = println("[ RUN ] ${testCase.prettyName}")
override fun pass(testCase: TestCase, timeMillis: Long) {
registerPass()
println("[ OK ] ${testCase.prettyName} ($timeMillis ms)")
}
override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) {
registerFail()
failedTests_.add(testCase)
e.printStackTrace()
println("[ FAILED ] ${testCase.prettyName} ($timeMillis ms)")
}
override fun ignore(testCase: TestCase) = registerIgnore()
override val failedTests: Collection<TestCase>
get() = failedTests_
override val hasFailedTests: Boolean
get() = failed != 0
}
@@ -1,17 +1,37 @@
package konan.test
import kotlin.AssertionError
interface TestListener {
fun startTesting(runner: TestRunner)
fun endTesting(runner: TestRunner)
fun endTesting(runner: TestRunner, timeMillis: Long)
fun startSuite(suite: TestSuite)
fun endSuite(suite: TestSuite)
fun endSuite(suite: TestSuite, timeMillis: Long)
fun ignoreSuite(suite: TestSuite)
fun start(testCase: TestCase)
fun pass(testCase: TestCase)
fun fail(testCase: TestCase, e: Throwable)
fun pass(testCase: TestCase, timeMillis: Long)
fun fail(testCase: TestCase, e: Throwable, timeMillis: Long)
fun ignore(testCase: TestCase)
}
interface TestStatistics {
val total: Int
val passed: Int
val failed: Int
val ignored: Int
// TODO: Do we need such properties for other cases?
val failedTests: Collection<TestCase>
val hasFailedTests: Boolean
}
abstract class AbstractTestStatistics: TestStatistics {
override var total: Int = 0; protected set
override var passed: Int = 0; protected set
override var failed: Int = 0; protected set
override var ignored: Int = 0; protected set
protected fun registerPass() { total++; passed++ }
protected fun registerFail() { total++; failed++ }
protected fun registerIgnore() { total++; ignored++ }
}
@@ -1,5 +1,7 @@
package konan.test
import kotlin.system.measureTimeMillis
object TestRunner {
private val _suites = mutableListOf<TestSuite>()
@@ -11,15 +13,17 @@ object TestRunner {
fun run(listener: TestListener) = with(listener) {
startTesting(this@TestRunner)
suites.forEach {
if (it.ignored) {
ignoreSuite(it)
} else {
startSuite(it)
it.run(listener)
endSuite(it)
val totalTime = measureTimeMillis {
suites.forEach {
if (it.ignored) {
ignoreSuite(it)
} else {
startSuite(it)
val time = measureTimeMillis { it.run(listener) }
endSuite(it, time)
}
}
}
endTesting(this@TestRunner)
endTesting(this@TestRunner, totalTime)
}
}
@@ -1,6 +1,8 @@
package konan.test
import kotlin.IllegalArgumentException
import kotlin.system.getTimeMillis
import kotlin.system.measureTimeMillis
interface TestCase {
val name: String
@@ -12,6 +14,7 @@ interface TestSuite {
val name: String
val ignored: Boolean
val testCases: Map<String, TestCase>
val size : Int
fun run(listener: TestListener)
}
@@ -57,21 +60,24 @@ abstract class AbstractTestSuite<F: Function<Unit>>(override val name: String, o
TestRunner.register(this)
}
override val size: Int
get() = testCases.size
override fun run(listener: TestListener) {
doBeforeClass()
testCases.values.forEach {
if (it.ignored) {
listener.ignore(it)
} else {
val startTime = getTimeMillis()
try {
listener.start(it)
doTest(it)
listener.pass(it)
listener.pass(it, getTimeMillis() - startTime)
} catch (e: Throwable) {
listener.fail(it, e)
listener.fail(it, e, getTimeMillis() - startTime)
}
}
}
doAfterClass()
}