Skip to content

Commit

Permalink
Merge pull request vert-x3#237 from napperley/3.5.0-staging
Browse files Browse the repository at this point in the history
Add documentation for kotlintest
  • Loading branch information
vietj authored Oct 18, 2017
2 parents ebe1a97 + e80272d commit b12174e
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 0 deletions.
12 changes: 12 additions & 0 deletions kotlin-examples/kotlintest/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Kotlin Test (kotlintest)

A Vert.x example project that shows how to test Vert.x code using the **Kotlin Test** framework (software testing). This project uses Gradle so in order to run the tests execute one of the following commands in a terminal:
```
# Run this line if using a Unix based OS (eg Linux).
./gradlew test
# Run this line if using Windows.
gradlew.bat test
```

For more information on how to test Vert.x code using Kotlin Test please refer to the [testing guide](testing-guide.md).
130 changes: 130 additions & 0 deletions kotlin-examples/kotlintest/testing-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Vert.x Testing Guide

This guide will cover how to test Vert.x code in a *Kotlinic* (idiomatic Kotlin) way. In order to do testing [Kotlin Test](https://github.com/kotlintest/kotlintest) will be used as the testing framework. Although Vert.x has a [testing library](http://vertx.io/docs/vertx-unit/kotlin/) it is designed with Java in mind and isn't *Kotlinic*.

For the purposes of this guide the Kotlin Test Functional testing style will be used. For more information on all the testing styles refer to the [Kotlin Test reference](https://github.com/kotlintest/kotlintest/blob/master/doc/reference.md#testing-styles) documentation. This guide is based on the work done in this [GitHub project](https://github.com/napperley/vertx-kotlintest).


## Basics

When using Kotlin Test with the Functional testing style a class is defined which extends **FunSpec**. Like JUnit the defined class is a Test Case containing one or more tests. Each test is defined as a lambda which is passed through to the **test** function, along with the name of the test. All tests are called in the **init** block of the defined class. See the following example:

```kotlin
import io.kotlintest.specs.FunSpec

class ExampleTest : FunSpec() {
init {
test("function x should return the correct result") {
// Do some testing here.
}
}
}
```

All assertions are provided by Kotlin test as infix functions, and have the major advantage of being very concise yet readable without having to hunt around for an assertions library. Below is an example:

```kotlin
class ExampleTest : FunSpec() {
init {
test("function x should return the correct result") {
val result: String
// ...

// Example assertion.
result shouldEqual true
}
}
}
```

If an assertion fails during testing then a **AssertionException** is raised which causes a test to fail. Gradle can run tests using Kotlin Test through the standard **test** Gradle task. Kotlin Test uses the JUnit test runner which IntelliJ supports out of the box without needing to install a IntelliJ plugin.


## Test Lifecycle

In Kotlin Test it is possible to intercept the test lifecycle to execute tasks before and after a test (by overriding the **interceptTestCase** function), which is very useful for ensuring resources are initialised before a test and cleaned up after a test. Below is an example:

```kotlin
class ExampleTest : FunSpec() {
// ...

override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) {
// Before.
// ...
// Remember to run the test!
test()
// After.
// ...
}
}
```


## Best Practices

- In a Test Case define a variable called **vertx** with **Vertx?** as the type with the default value of *null*, eg:
```kotlin
class ExampleTest : FunSpec() {
private var vertx: Vertx? = null

// ...
}
```
- Every test should be in a separate named function to make it easy to manage tests, eg:
```kotlin
class ExampleTest : FunSpec() {
// ...

init {
testHttpGetStatus()
testHttpPostStatus()
// ...
}

private fun testHttpGetStatus() = test("Function httpGetStatus returns correct status") {
// ...
}

private fun testHttpPostStatus() = test("Function httpPostStatus returns correct status") {
// ...
}
}
```
- Always intercept a test to ensure that the **Vertx** object is handled properly, eg:
```kotlin
import io.kotlintest.Spec

fun Spec.runTest(before: () -> Unit, after: () -> Unit, block: () -> Unit) {
try {
before()
block()
} finally {
after()
}
}

class HttpClientExtensionsTest : FunSpec() {
// ...

init {
test("Function httpGetStatus returns correct status") {
runTest(before = this::beforeTest, after = this::afterTest) {
// ...
}
}
}

private fun beforeTest() {
vertx = Vertx.vertx()
// ...
}

private fun afterTest() {
vertx?.close()
vertx = null
// ...
}
}
```

Important to note that Kotlin 1.2 (currently in Beta) allows for a member function to be referenced without having to use **this**, eg ```::beforeTest```

0 comments on commit b12174e

Please sign in to comment.