Kotlin Specification Framework

Related tags

Utility kspec
Overview

(NO LONGER MAINTANED) KSpec -> Spek.

KSpec

Bintray Build Status codecov.io

Specifications for Kotlin.

Basic Structure

class TheMostAmazingAnimalSpec: KSpec() {
    override fun spec() {
        describe("the most amazing animal in the universe") {
            val animal = GetMostAmazingAnimal()
            it("should be a panda") {
                assertThat(animal.type, equalTo("panda"))
            }
            
            context("not a panda") {
                it("nope, not going to accept it") {
                    assertThat({
                        assertThat(animal.type, not(equalTo("panda")))
                    }, thrown(EndOfTheWorldException::class))
                }
            }
        }
    }
}

Context

KSpec is heavily inspired by RSpec, Context is synonymous to RSpec's scopes.

Example

The test method in JUnit and created using it.

ExampleGroup

Groups similar examples together (they might be testing the same Subject - more on this later) and is created by using describe or context. Be cautious in placing logic code in them as they are eagerly evaluated

Fixtures

KSpec provides before, beforeEach, afterEach and after callbacks for each context.

Subject

Just like RSpec, KSpec also support subjects.

class TheMostAmazingAnimalSpec: KSpec() {
    override fun spec() {
        describe("the most amazing animal in the universe") {
            subject {
                return@subject GetMostAmazingAnimal();
            }
            
            it("should be a panda") {
                assertThat(subject.type, equalTo("panda"))
            }
            
            context("not a panda") {
                it("nope, not going to accept it") {
                    assertThat({
                        assertThat(subject.type, not(equalTo("panda")))
                    }, thrown(EndOfTheWorldException::class))
                }
            }
        }
    }
}

Shared Examples

Sometimes it's convenient to reuse examples - like testing a subclass.

class CalculatorSpec: KSpec() {
    override fun spec() {
        describe(Calculator::class) {
            itBehavesLike(calculator())
        }
    }
    
    companion object {
        fun calculator() = sharedExample<Calculator> {
            describe("add") {
                it("1 + 1 = 2") {
                    assertThat(subject.add(1, 1), equalTo(2))
                }
            }
            ...
        }
    }
}

class AdvancedCalculatorSpec: KSpec() {
    override fun spec() {
        describe(AdvancedCalculator::class) {
            itBehavesLike(CalculatorSpec.calculator())
        }
    }
}

Pending

You can write specs in advance, KSpec will ignore them during execution.

class SomeSpec: KSpec() {
    override fun spec() {
        xdescribe("a pending group") {
            it("won't be executed") { }
        }

        xcontext("another pending group", "some reason")

        xit("a pending example") { }
    }
}

Focused

KSpec supports focusing execution only on several contexts. Use fdescribe and fcontext to create a focused group, and fit to create a focused example. KSpec will only run focused contexts if there are any, othewise it will run everything.

Tagging

TODO

Filters

This allows to control which contexts to run. It can be configured per spec (by overriding configure) or by using Shared Configurations.

class SomeSpec: KSpec() {
    override fun configure(config: KSpecConfig) {
       // config.filter.<filter> = tags
    }
}

include

Only include contexts having at least one of the tags specified.

exclude

Exclude any contexts having at least one of the tags specified.

matching

Similar to the include filter, the only difference is that if there is no match run everything.

Shared Configurations

Declare shared configurations by extending Configuration and apply it to a spec via @Configurations.

class SharedConfiguration: Configuration {
    override fun apply(config: KSpecConfig) {
        ...
    }
}

class AnotherConfiguration: Configuration {
    override fun apply(config: KSpecConfig) {
        ...
    }
}

// use it
@Configurations(
    SharedConfiguration::class,
    AnotherConfiguration::class
)
class SomeSpec: KSpec() {
    ...
}

Usage

Console Runner

TODO

Gradle

Currently you need to use a JUnit4 Runner to be able to run specs with gradle. Make sure to annotate your test classes with @RunWith(JUnitKSpecRunner::class).

repositories {
    jcenter()
}

dependencies {
    testCompile "io.polymorphicpanda.kspec:kspec-core:<kspec-version>"
    testCompile "io.polymorphicpanda.kspec:kspec-junit-runner:<kspec-version>"
}

Development version

Gradle

repositories {
    maven {
        url "http://oss.jfrog.org/artifactory/oss-snapshot-local/"
    }
}
Comments
  • Provide infrastructure for writing IDE and build tools plugin

    Provide infrastructure for writing IDE and build tools plugin

    Problem

    Currently the only way to get IDE and build tools support is via JUnitKSpecRunner. This approach is very limited as you cant run a specific spec.

    Possible solutions

    1. JUnit 5 looks promising, especially the test-engine-api and the launcher. If all goes well with it, we don't even need to write any plugins (someone may already did).
    2. Write a custom test engine for KSpec. Currently exploring it, you can checkout this branch.
    enhancement 
    opened by raniejade 13
  • Improve ContextVisitor

    Improve ContextVisitor

    Introduce ContextVisitResult that control the tree traversal. There are still some checks missing like when preVisitExampleGroup returns SKIP and handling for the return value of postVisitExampleGroup.

    opened by raniejade 2
  • Add infrastructure to support writing IDE and build tool plugins

    Add infrastructure to support writing IDE and build tool plugins

    Resolves #32.

    Broken down kspec-core into several modules.

    • kspec-core - core classes.
    • kspec-engine - defines the runtime behaviour of KSpec.
    • kspec-launcher - provides infrastructure in writing IDE and build tool plugins.
    • kspec-console-runner - console runner for KSpec (uses kspec-launcher).
    opened by raniejade 1
  • Implement focused and pending groups

    Implement focused and pending groups

    This resolves #19, resolves #21 and bring a lot of changes internally. Example groups can now be tagged and its children will automatically inherit those tags. before, after and around hooks now gets called for every example group as well.

    opened by raniejade 1
  • Implement focused examples

    Implement focused examples

    Resolves #14

    Added filtering via tags when running examples.

    config.filter.include(tag1, tag2) // run only examples with tag1 or tag2
    config.filter.exclude(tag1, tag2) // exclude examples with either tag1 or tag2
    
    config.filter.matching(tag1, ...tagn) // same as filter.include but will only apply if
                                          // any example matches the given tags
    

    focus() tag is provided and is the default value for config.filter.matching. To focus an example tag it with focus() or use fit(...) instead of it(...).

    opened by raniejade 1
  • Improve junit reporting

    Improve junit reporting

    Current runner extends ParentRunner, which treats the class containing the @RunWith annotation to be the root test suite. As an improvement we can make every Given clause as the root test suite.

    e.g.

    class TestSpec: Speck({
        Given("this foo") {
            When("this bar") {
                Then("foobar") { 
                    ...
                }
            }
        }
    })
    

    Current runner will have this hierarchy:

    TestSpec
      --> Given this foo
          --> When this bar
             --> Then foobar
    

    What we really want is:

    Given this foo
    --> When this bar
       --> Then foobar
    
    enhancement 
    opened by raniejade 1
  • Support shared configurations

    Support shared configurations

    Specs can be configured by overriding configure:

    class SomeSpec: KSpec() {
        override fun configure(config: KSpecConfig) {
            ...
        }
        ...
    }
    

    Configuration can be shared via inheritance however it's not that flexible. Allow specifying configurations via an annotation (@Configurations) which can contains an array of Configuration classes, e.g:

    Configuration

    class SharedConfiguration: Configuration {
        override fun apply(config: KSpecConfig) {
            ...
        }
    }
    

    Spec

    @Configurations(SharedConfiguration::class)
    class SomeSpec: KSpec() {
        ...
    }
    

    Configurations are applied in the order they are listed.

    enhancement 
    opened by raniejade 0
  • Implement focused and pending groups

    Implement focused and pending groups

    This resolves #19, resolves #21 and bring a lot of changes internally. Example groups can now be tagged and its children will automatically inherit those tags. before, after and around hooks now gets called for every example group as well.

    opened by raniejade 0
  • Rework pending examples

    Rework pending examples

    #17 introduces the ability to filter examples before a run, we can rework pending examples to take advantage of that. Implementation should be the same as how focused examples are implemented.

    enhancement 
    opened by raniejade 0
  • Implement focused groups

    Implement focused groups

    Support fdescribe and fcontext, semantics is the same with fit.

    With #24 we can do a lot more processing, move tags property up the hierarchy to Context.

    enhancement 
    opened by raniejade 0
  • Implement hooks

    Implement hooks

    This can be done per spec basis.

    class SomeSpec: KSpec() {
        override fun configure(configuration: KSpecConfiguration) {
        }
    
        ...
    }
    

    Provide the following methods:

    • [x] before(example) - invoked before an example is executed.
    • [x] after(example) - invoked after an example is executed.
    • [x] around(example) - provide a way to wrap an execution of an example (e.g. run in a different thread - timeout?)
    opened by raniejade 0
  • Property-based testing

    Property-based testing

    Does KSpec support any form of property based testing. There are no examples I have found so far.

    Property-based testing is testing à la QuickCheck, Hypothesis, ScalaCheck, KotlinTest, Specks, Spock/Spock Generator, etc.

    opened by russel 0
  • Intellij Integration with JUnitKSpecRunner

    Intellij Integration with JUnitKSpecRunner

    It would be good nice if individual KSpec blocks could be run but the intelliJ test runner, without needing to use fit, fdescribe etc.

    Is anyone working on this now?

    enhancement 
    opened by jasonm23 3
  • Use local delegated properties with subjects

    Use local delegated properties with subjects

    So Jetbrains just announced Kotlin's Post 1.0 Roadmap and one of the planned features is local delegated properties. This can be very useful with subjects!

    describe(Foo::class) {
        val foo by subject() // using no-arg constructor
    }
    
    // or
    
    describe(Foo::class) {
        val foo by subject {
            return@subject Foo(1, 2)
        }
    }
    

    This is very similar to RSpec's memoized helpers, heck we can even support let.

    describe("foo") {
        var count = 0
        val something by let {
            return@let ++count
        }
    
        it("it should be 1") {
            assert(something == 1)
        }
    
        it("it should be 2") {
            assert(something == 2)
        }
    }
    
    enhancement 
    opened by raniejade 0
  • Introduce lambda constructor parameter to shorten specification.

    Introduce lambda constructor parameter to shorten specification.

    Here is a small sample that introduces an intermediate class that shortens specification classes. We lose flexibility a bit (no way to change the runner via @RunWith) and it also clashes the name with the Spec interface. This was inspired by https://github.com/JetBrains/spek/pull/71.

    import com.natpryce.hamkrest.assertion.assertThat
    import com.natpryce.hamkrest.equalTo
    import io.polymorphicpanda.kspec.KSpec
    import io.polymorphicpanda.kspec.describe
    import io.polymorphicpanda.kspec.it
    import io.polymorphicpanda.kspec.junit.JUnitKSpecRunner
    import org.junit.runner.RunWith
    
    @RunWith(JUnitKSpecRunner::class)
    open class Spec(private val definition: Spec.() -> Unit) : KSpec() {
        override fun spec() {
            definition()
        }
    }
    
    class ExampleSpec : Spec({
        describe("a group") {
            it("example") {
                assertThat(2 + 3, equalTo(5))
            }
        }
    })
    
    opened by hastebrot 1
Releases(v0.4.0)
Owner
Ranie Jade Ramiso
Maintainer of @spekframework
Ranie Jade Ramiso
A tiny framework to execute shell scripts on Android

Skippy A tiny framework to execute shell scripts on Android Why I first sought out to create a basic script manager for Android.

Tyler 4 Jul 31, 2022
Command framework built around Kord, built to be robust and scalable, following Kord's convention and design patterns.

Command framework built around Kord, built to be robust and scalable, following Kord's convention and design patterns.

ZeroTwo Bot 4 Jun 15, 2022
Remove the dependency of compiled kotlin on kotlin-stdlib

Dekotlinify This project aims to take compiled Kotlin Java bytecode (compiled by the standard Kotlin compiler) and remove all references to the Kotlin

Joseph Burton 10 Nov 29, 2022
gRPC and protocol buffers for Android, Kotlin, and Java.

Wire “A man got to have a code!” - Omar Little See the project website for documentation and APIs. As our teams and programs grow, the variety and vol

Square 3.9k Dec 31, 2022
A DSL to handle soft keyboard visibility change event written in Kotlin.

About A DSL to handle soft keyboard visibility change event written in Kotlin. How to use? Step 1. Add it in your root build.gradle at the end of repo

Vinícius Oliveira 17 Jan 7, 2023
Kotlin matrix class which supports determinant, inverse matrix, matmul, etc.

Kotrix is a set of classes that helps people dealing with linear algebra in Kotlin.

Kanguk Lee 5 Dec 8, 2022
Fuzzy string matching for Kotlin (JVM, native, JS, Web Assembly) - port of Fuzzy Wuzzy Python lib

FuzzyWuzzy-Kotlin Fuzzy string matching for Kotlin (JVM, iOS) - fork of the Java fork of of Fuzzy Wuzzy Python lib. For use in on JVM, Android, or Kot

WillowTree, LLC 54 Nov 8, 2022
🐫🐍🍢🅿 Multiplatform Kotlin library to convert strings between various case formats including Camel Case, Snake Case, Pascal Case and Kebab Case

KaseChange Multiplatform Kotlin library to convert strings between various case formats Supported Case Formats SCREAMING_SNAKE_CASE snake_case PascalC

PearX Team 67 Dec 30, 2022
Multiplaform kotlin library for calculating text differences. Based on java-diff-utils, supports JVM, JS and native targets.

kotlin-multiplatform-diff This is a port of java-diff-utils to kotlin with multiplatform support. All credit for the implementation goes to original a

Peter Trifanov 51 Jan 3, 2023
Multi-module, Kotlin, MVI, Compose, Hilt, Navigation Component, Use-cases, Room, Retrofit

Work in progress Multi-module demo app that gets data from dota2 api. API https://docs.opendota.com/ Players by rank (GET) https://api.opendota.com/ap

Mitch Tabian 321 Dec 27, 2022
recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

recompose is a tool for converting Android layouts in XML to Kotlin code using Jetpack Compose.

Sebastian Kaspari 565 Jan 2, 2023
Markdown renderer for Kotlin Compose Multiplatform (Android, Desktop)

Markdown renderer for Kotlin Compose Multiplatform (Android, Desktop)

Mike Penz 129 Jan 1, 2023
Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dagger Hilt, MVP Moxy, Retrofit, Kotlin coroutine, Sealed class

Dostonjon 1 Nov 2, 2021
Item Helper For Kotlin

Item Helper For Kotlin

Blugon 2 Dec 3, 2021
kotlin mvvm+dataBinding+retrofit2+Arouter等BaseActivity、BaseFragment、BaseDialogFragment基类封装

kotlin-mvvm kotlin mvvm+dataBinding+retrofit2+ARouter等BaseActivity、BaseFragment、BaseDialogFragment基类封装 Android开发项目基本使用框架,封装了各类组件,在基类实现了沉浸式状态栏,可以自己更改颜色

奋斗中的骚年 3 Jul 12, 2022
Bar Service Kotlin Client

A simple starter service client written in Kotlin against generated models (protos)A simple starter service client written in Kotlin against generated models (protos)

Logesh Dinakaran 0 Nov 9, 2021
Kotlin validation with a focus on readability

kommodus Kotlin validation with a focus on readability import com.github.kommodus.constraints.* import com.github.kommodus.Validation data class Test

Serhii Shobotov 0 Dec 12, 2021
Kotlin to Dart compiler

Dotlin is a Kotlin to Dart compiler. The aim is to integrate Kotlin as a language into the Dart ecosystem, combing best of both worlds: The Kotlin lan

Dotlin 184 Jan 6, 2023
Modern Kotlin version of com.example.semitop7.FireTVStyle keyboard

ftv-style-keyboard Modern Kotlin version of com.example.semitop7.FireTVStyle keyboard Manual activation on FireTV via adb shell: adb shell ime enable

nikk 1 Oct 4, 2022