unit-tests: Add gtest-like output
This commit is contained in:
@@ -8,15 +8,15 @@ class SimpleTestListener: TestListener {
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
override fun startTesting(runner: TestRunner) = println("Starting testing")
|
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 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 ignoreSuite(suite: TestSuite) = println("Test suite ignored: $suite")
|
||||||
|
|
||||||
override fun start(testCase: TestCase) = println("Starting test case: $testCase")
|
override fun start(testCase: TestCase) = println("Starting test case: $testCase")
|
||||||
override fun pass(testCase: TestCase) = println("Passed: $testCase")
|
override fun pass(testCase: TestCase, timeMillis: Long) = println("Passed: $testCase")
|
||||||
override fun fail(testCase: TestCase, e: Throwable) {
|
override fun fail(testCase: TestCase, e: Throwable, timeMillis: Long) {
|
||||||
println("Failed: $testCase. Exception:")
|
println("Failed: $testCase. Exception:")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
hasFails = true
|
hasFails = true
|
||||||
@@ -25,7 +25,7 @@ class SimpleTestListener: TestListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main(args:Array<String>) {
|
fun main(args:Array<String>) {
|
||||||
val listener = SimpleTestListener()
|
val listener = GTestListener()
|
||||||
TestRunner.run(listener)
|
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
|
package konan.test
|
||||||
|
|
||||||
import kotlin.AssertionError
|
|
||||||
|
|
||||||
interface TestListener {
|
interface TestListener {
|
||||||
fun startTesting(runner: TestRunner)
|
fun startTesting(runner: TestRunner)
|
||||||
fun endTesting(runner: TestRunner)
|
fun endTesting(runner: TestRunner, timeMillis: Long)
|
||||||
|
|
||||||
fun startSuite(suite: TestSuite)
|
fun startSuite(suite: TestSuite)
|
||||||
fun endSuite(suite: TestSuite)
|
fun endSuite(suite: TestSuite, timeMillis: Long)
|
||||||
fun ignoreSuite(suite: TestSuite)
|
fun ignoreSuite(suite: TestSuite)
|
||||||
|
|
||||||
fun start(testCase: TestCase)
|
fun start(testCase: TestCase)
|
||||||
fun pass(testCase: TestCase)
|
fun pass(testCase: TestCase, timeMillis: Long)
|
||||||
fun fail(testCase: TestCase, e: Throwable)
|
fun fail(testCase: TestCase, e: Throwable, timeMillis: Long)
|
||||||
fun ignore(testCase: TestCase)
|
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
|
package konan.test
|
||||||
|
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
object TestRunner {
|
object TestRunner {
|
||||||
|
|
||||||
private val _suites = mutableListOf<TestSuite>()
|
private val _suites = mutableListOf<TestSuite>()
|
||||||
@@ -11,15 +13,17 @@ object TestRunner {
|
|||||||
|
|
||||||
fun run(listener: TestListener) = with(listener) {
|
fun run(listener: TestListener) = with(listener) {
|
||||||
startTesting(this@TestRunner)
|
startTesting(this@TestRunner)
|
||||||
suites.forEach {
|
val totalTime = measureTimeMillis {
|
||||||
if (it.ignored) {
|
suites.forEach {
|
||||||
ignoreSuite(it)
|
if (it.ignored) {
|
||||||
} else {
|
ignoreSuite(it)
|
||||||
startSuite(it)
|
} else {
|
||||||
it.run(listener)
|
startSuite(it)
|
||||||
endSuite(it)
|
val time = measureTimeMillis { it.run(listener) }
|
||||||
|
endSuite(it, time)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
endTesting(this@TestRunner)
|
endTesting(this@TestRunner, totalTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package konan.test
|
package konan.test
|
||||||
|
|
||||||
import kotlin.IllegalArgumentException
|
import kotlin.IllegalArgumentException
|
||||||
|
import kotlin.system.getTimeMillis
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
interface TestCase {
|
interface TestCase {
|
||||||
val name: String
|
val name: String
|
||||||
@@ -12,6 +14,7 @@ interface TestSuite {
|
|||||||
val name: String
|
val name: String
|
||||||
val ignored: Boolean
|
val ignored: Boolean
|
||||||
val testCases: Map<String, TestCase>
|
val testCases: Map<String, TestCase>
|
||||||
|
val size : Int
|
||||||
fun run(listener: TestListener)
|
fun run(listener: TestListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,21 +60,24 @@ abstract class AbstractTestSuite<F: Function<Unit>>(override val name: String, o
|
|||||||
TestRunner.register(this)
|
TestRunner.register(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val size: Int
|
||||||
|
get() = testCases.size
|
||||||
|
|
||||||
override fun run(listener: TestListener) {
|
override fun run(listener: TestListener) {
|
||||||
doBeforeClass()
|
doBeforeClass()
|
||||||
testCases.values.forEach {
|
testCases.values.forEach {
|
||||||
if (it.ignored) {
|
if (it.ignored) {
|
||||||
listener.ignore(it)
|
listener.ignore(it)
|
||||||
} else {
|
} else {
|
||||||
|
val startTime = getTimeMillis()
|
||||||
try {
|
try {
|
||||||
listener.start(it)
|
listener.start(it)
|
||||||
doTest(it)
|
doTest(it)
|
||||||
listener.pass(it)
|
listener.pass(it, getTimeMillis() - startTime)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
listener.fail(it, e)
|
listener.fail(it, e, getTimeMillis() - startTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
doAfterClass()
|
doAfterClass()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user