Skip to main content

TW AppTest

Tegral Web AppTest is a simple and straight-forward integration/end-to-end testing library for Tegral Web applications.

Package information
Package nameCatalog dependencyFull Gradle name
tegral-web-apptesttegralLibs.web.apptestguru.zoroark.tegral:tegral-web-apptest:VERSION

Note that, while AppTest may seem similar to Controllers tests on the surface, but they have a few fundamental differences:

  • Controller tests are made for lightweight testing that does not require much else other than a pre-setup Ktor environment.
  • Controller tests follow the "test subject" pattern, whereas integration tests do not provide direct access to the controllers
  • Controller tests are built with mocking in mind, which is not the case of integration tests.
  • AppTest tests allow installation of special features to abstract away complicated test setups that may occur with databases, Ktor, etc.
  • AppTest automatically starts and stops services

Writing a test

Let's say that we have a module that contains all of our application's components.

class GreetingService {
fun greet(who: String?): String = "Hello World!"
}

class GreetingController(scope: InjectionScope) : KtorController() {
private val service: GreetingService by scope()

override fun Routing.install() {
get("/greet") {
call.respond(service.greet())
}
}
}

val appModule = tegralDiModule {
put(::GreetingService)
put(::GreetingController)
}

Tests with AppTest are written by subclassing the TegralWebIntegrationTest class:

class ExampleTest : TegralWebIntegrationTest({
// Integration test AppDSL-like block
}) {
// ...
}

You can then add features, modules, etc. in the block provided to the TegralWebIntegrationTest constructor:

class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
// ...
}

Then, add tests using the test function. Here's an example of a test for the /greet endpoint in our example:

class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {
@Test
fun `greet endpoint test without arguments`() = test {
// ...
}
}

Within the test block, you have access to the client object that allows you to send HTTP requests to your client, just like you would with a regular Ktor client.

class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {

@Test
fun `greet endpoint test without arguments`() = test {
val result = client.get("/greet").body<Greeting>()
assertEquals(Greeting("hello", "world"), result)
}
}

Configuring the client

You can further configure the client as you see fit by using the createClient function.

class ExampleTest : TegralWebIntegrationTest({
put(appModule)
}) {

@Test
fun `greet endpoint test without arguments`() = test {
val customClient = createClient(null) { // null is because we want the default app
// Configure your client here
// See https://ktor.io/docs/create-client.html#configure-client
}
// ...
}
}