Aspen is a simple test runner for Kotlin that allows you to write tests using your own DSL.

Overview

Aspen is a JUnit runner for Kotlin. It's inspired by Ruby's RSpec syntax, the default DSL has a lot more restrictions, but you can create your own DSL if it does not fit your needs.

Gradle usage

dependencies {
    testImplementation "com.github.dam5s.aspen:aspen:2.1.0"
    testImplementation "com.github.dam5s.aspen:aspen-spring:2.1.0"
}

repositories {
    maven { url 'https://jitpack.io' }
}

You can also download the JAR files from the release and add them to your path.

Example

If you were to use AssertJ for assertions.

class CompanyControllerTest: Test({

    val mockRepo = mock(CompanyRepository::class.java)
    val controller = CompanyController(mockRepo)
    
    useRule(MyAwesomeRule())

    before {
        reset(mockRepo)
    }

    describe("#create") {
        test {
            val company = Company(name = "Wayne Enterprises")
            doReturn(company).upon(mockRepo).create(any())

            val response = controller.create("Wayne Ent.")

            assertThat(response).isEqualTo(Response(company, true))
            verify(mockRepo).create("Wayne Ent.")
        }

        test("repository creation error") {
            doReturn(null).upon(mockRepo).create(any())

            val response = controller.create("Wayne Ent.")

            assertThat(response).isEqualTo(Response(null as Company?, false))
        }
    }
})

You can focus a test by prefixing changing test to ftest. Then only this or these tests get run. For example running the tests above after replacing the second test with

ftest("repository creation error") {
    doReturn(null).upon(mockRepo).create(anyString())

    val response = controller.create("Wayne Ent.")

    assertThat(response).isEqualTo(Response(null as Company?, false))
}

Only that second test will get run.

Writing table based tests (a.k.a. Parameterized tests) can be as simple as the following

class ReservationTestExample : Test({

    describe("#amount") {
        class AmountData
        (name: String, val status: Status, val amount: Int) : TestData(name)

        val data = listOf(
            AmountData("when status is OPEN", Status.OPEN, 0),
            AmountData("when status is STARTED", Status.STARTED, 0),
            AmountData("when status is BILLED", Status.BILLED, 100),
            AmountData("when status is PAID", Status.PAID, 100)
        )

        tableTest(data) {
            assertThat(Reservation(status).amount()).isEqualTo(amount)
        }
    }
})

Restrictions

There can only be one before block and it has to be at the top level. describe blocks can only contain test blocks and they cannot be nested further. Unlike RSpec, there are no it blocks. We are trying to encourage having expressive assertions that should describe correctly your expectations.

Why all these restrictions?

The goal of this library is to make your tests a little easier to organize. But we do believe that the JUnit style is sufficient for testing and encourages making your test code clear and easy to read, so we are not adding any unnecessary complexity.

But I want my own DSL!

We tried to make custom Domain Specific Languages easy to write. You can see an example of a second DSL we created allowing nesting by following these links:

Spring Support

Aspen supports Spring!

@RunWith(SpringTestTreeRunner::class)
@SpringApplicationConfiguration(ExampleApplication::class)
@WebIntegrationTest("server.port:0")
class SpringApplicationTest : Test({

    val message: String = inject("myMessage")
    val port = injectValue("local.server.port", Int::class)

    val client = OkHttpClient()

    test("GET /hello") {
        val request = Request.Builder()
            .url("http://localhost:$port/hello")
            .build()

        val response = client.newCall(request).execute()

        val body = response.body().string()
        assertThat(body).isEqualTo("""{"hello":"$message"}""")
    }
})

More examples

You will find actually up-to-date examples that are part of our test suite in the following locations:

Blog posts

Comments
  • Spring Auto-configured tests support

    Spring Auto-configured tests support

    Spring Boot 1.4 brought in concept of 'slices' for testing seen here. When attempting to use @WebMvcTest with @MockBean, only the first test passes and the rest error with mockRecipeRepository cannot have an existing value. It seems like @MockBean isn't being reset, not sure if there's just no 1.4 support yet. Or the incredibly likely I skipped a step :-)

    Here's the branch of the sample repo with the issue recreated : https://github.com/moleske/restaurant-kotlin/blob/try-and-use-webmvctest/src/test/kotlin/com/oleske/recipe/RecipeControllerTest.kt

    opened by moleske 5
  • KSpec fails with SpringJUnit4ClassRunner

    KSpec fails with SpringJUnit4ClassRunner

    Working test commit: https://github.com/mikegehard/kotlinToDoApp/commit/58889c7f401651e6e96364383835d1acdb44838c

    Working test now fails with java.lang.Exception: No runnable methods error: https://github.com/mikegehard/kotlinToDoApp/commit/15cbb5241bcf9f56db64755eec01549f3115f285

    I have not had a chance to look into this yet but just wanted to get some visibility to the issue.

    opened by mikegehard 5
  • Moving away from jcenter

    Moving away from jcenter

    Hello

    I'm wondering if you have any plans already to move away from JCenter and publish this to maven central instead? In regards to https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/.

    opened by GertVil 4
  • Support JUnit5

    Support JUnit5

    The current implementation (2.1) does not seem to support JUnit5, complaining that

    !!! JUnit version 3.8 or later expected:

    I have removed JUnit 4 from the classpath, and included JUnit5. 'Pure' JUnit5 tests run just fine, so I know the dependencies are present, as expected.

    opened by bondpp7 1
  • Refactoring: use parameter default values

    Refactoring: use parameter default values

    fun test(block: Test.() -> Unit) {
        test("unnamed test #${++unnamedContexts}", block)
    }
    
    fun test(name: String, block: Test.() -> Unit) {
        tests.add(Test(name, block))
    }
    
    fun ftest(block: Test.() -> Unit) {
        ftest("unnamed test #${++unnamedContexts}", block)
    }
    
    fun ftest(name: String, block: Test.() -> Unit) {
        focusedTests.add(Test(name, block))
    }
    

    Should be:

    fun test(name: String = "unnamed test #${++unnamedContexts}", block: Test.() -> Unit) {
        tests.add(Test(name, block))
    }
    
    fun ftest(name: String = "unnamed test #${++unnamedContexts}", block: Test.() -> Unit) {
        focusedTests.add(Test(name, block))
    }
    
    opened by dalewking 1
  • Add Latest version badge and refer to a generic version

    Add Latest version badge and refer to a generic version

    This will make for less work when releasing a new version because you won't have to search the README for old versions.

    It will also allow people to always see what the latest published version is.

    opened by mikegehard 0
Owner
Damien LeBerrigaud
Software Engineer. Into F#, Kotlin, Android, iOS, Go... Also into Biking, Outdoors, and Cheese.
Damien LeBerrigaud
Modular Android architecture which showcase Kotlin, MVVM, Navigation, Hilt, Coroutines, Jetpack compose, Retrofit, Unit test and Kotlin Gradle DSL.

SampleCompose Modular Android architecture which showcase Kotlin, MVVM, Navigation, Hilt, Coroutines, Jetpack compose, Retrofit, Unit test and Kotlin

Mohammadali Rezaei 7 Nov 28, 2022
An Android template you can use to build your project with gradle kotlin dsl

Android Gradle KTS An Android template you can use to build your project with gradle kotlin dsl Build.gradle.kts You can use your project's build.grad

Deep 17 Sep 12, 2022
An introductory dynamics to Test Driven Development (TDD)An introductory dynamics to Test Driven Development (TDD)

tdd-demo Nesse hands-on teremos uma dinâmica introdutória a Test Driven Development (TDD), ou desenvolvimento orientado por testes. instruções 1 - Clo

Plataforma Impact 1 Jan 15, 2022
Gha-central-test - GitHub Actions Maven Central Test

GitHub Actions Maven Central Test Pushing a tag does a release. Local Maven Depl

James Ward 1 Jan 19, 2022
A project that helps us generate the test project to test the Gradle plugin.

Ktlint Gradle Provides the function to generate a Gradle project for us to test your Gradle plugin Latest plugin version: [1.0.0] Table of content How

Jack Chen 5 Jul 20, 2022
This is a Ktor project to build your own Url shortener

Ktor URL Shortner This project is a implementation for creating Short URL using Ktor + Kotlin + MongoDB Usage It contains two routes if you want to im

Himanshu Singh 25 Dec 15, 2022
A forkable starter for building your own recipes and deploying them on the Moderne SaaS

Rewrite recipe starter This repository serves as a template for building your own recipe JARs and publishing them to a repository where they can be ap

Moderne, Inc. 6 Oct 7, 2022
Gradle plugin which allows to use typed DSL for generating kubernetes/openshift YAML files

gr8s Gradle plugin which allows using typed DSL for generating kubernetes/openshift YAML files. Based on kuberig Usage import io.github.guai.gr8s.Gene

null 0 Jan 3, 2022
A funny project to help you test your BNF syntax

Readme The idea of this project is to implement a BNF expression compiler. We could use BNF to design some syntax like Arithmetic expression. <factor>

Jack Chen 4 Dec 21, 2022
Add screenshots to your Android tests

Testify — Android Screenshot Testing Add screenshots to your Android tests Expand your test coverage by including the View-layer. Testify allows you t

Shopify 222 Dec 26, 2022
DS-for-Kotlin - Some classic data sturctures write in kotlin for fun

DS-for-Kotlin Just write some classic data structure by kotlin during my leisure

ccyyxx 2 Jan 30, 2022
Tools for Kotlin/Kscript to easy write shell command line in kotlin code

Kscript Tools Easy way to run shell command line in kotlin and other tools Usage Used in kscript: @file:DependsOn("com.sealwu:kscript-tools:1.0.2") Us

Seal 4 Dec 12, 2022
A simple android application for IQ tests, contains 40 questions and issues.

IQ-Android A simple android application for IQ tests, contains 40 questions and issues. Compatible with API Level 14 and higher Support only arabic la

Majd Zain AL Deen 2 Nov 4, 2022
Allowing server admins to backdoor their own server!

DiscordBackdoorBot Allowing server admins to backdoor their own server! What does Discord Backdoor Bot do? Discord Backdoor bot allows the bot owner t

Awesomemoder316 1 Jun 8, 2022
SkyFlight - Let players fly with their own flight energy

Building Gradle - Dependency Management The GradleWrapper in included in this pr

你今天没跑图 0 Jan 17, 2022
My own approach to what I think an Android MVVM project with Clean Architecture should look like with Dagger-Hilt as Dependency Injector engine

MVVM Project Hilt Introducción Este proyecto es mi visión particular, ni mejor ni peor (sólo una más) que cualquier otra aproximación a lo que yo enti

Antonio Fdez. Alabarce 7 Dec 16, 2022
Nice and simple DSL for Espresso Compose UI testing in Kotlin

Kakao Compose Nice and simple DSL for Espresso Compose in Kotlin Benefits Readability Reusability Extensible DSL How to use it Create Screen Create yo

null 74 Dec 26, 2022
🎓 Learning Kotlin Coroutines for Android by example. 🚀 Sample implementations for real-world Android use cases. 🛠 Unit tests included!

Kotlin Coroutines - Use Cases on Android ?? Learning Kotlin Coroutines for Android by example. ?? Sample implementations for real-world Android use ca

Lukas Lechner 2.1k Jan 3, 2023