Skip to content

Latest commit

 

History

History
156 lines (114 loc) · 3.26 KB

usage.md

File metadata and controls

156 lines (114 loc) · 3.26 KB

Usage

Concepts

It is important to understand that specifications don’t have a notion of tests per se. xUnit tests are broken into two concepts: actions and checks.

@Test fun `increment changes value`() {
    // This is an action.
    counter.increment()

    // This is a check.
    assertThat(counter.current()).isEqual(1)
}
context("increment") {

    // This is an action.
    beforeEach {
        counter.increment()
    }

    // This is a check.
    it("changes value") {
        assertThat(counter.current()).isEqual(1)
    }
}

Take a closer look again — tests are trying to be two things at once, specifications make them atomic and dedicated. When this idea clicks — there is no way back to xUnit.

Specification

Specifications are declared as Spec subclasses. Spec receives a lambda on a top-level Example Group which allows to declare further Example Groups and Examples.

class CounterSpec : Spec({

    val counter by memoized { Counter.Impl() }

    it("contains default value") {
        assertThat(counter.current()).isZero()
    }
})

DSL

Example Groups can declare Examples, Example Groups and a bit more. Examples cannot declare anything.

context and describe

Declares an Example Group.

context("nothing") {

    it("does not change value") {
        assertThat(counter.current()).isEqual(0)
    }
}

describe is a context synonym. Use it for grouping context declarations when necessary.

it

Declares an Example.

it("changes value") {
    assertThat(counter.current()).isEqual(1)
}

fdescribe, fcontext and fit

Focuses an Example Group or an Example. Focusing means executing focused entries and nothing else.

// Skipped.
it("tracks analytics") {
    verify(env.analytics).trackEvent(Analytics.Event.CounterIncrement)
}

// Executed.
fit("changes value") {
    assertThat(counter.current()).isEqual(1)
}

xdescribe, xcontext, xit

Excludes an Example Group or an Example. Excluding means skipping excluded entries.

// Executed.
it("tracks analytics") {
    verify(env.analytics).trackEvent(Analytics.Event.CounterIncrement)
}

// Skipped.
xit("changes value") {
    assertThat(counter.current()).isEqual(1)
}

beforeEach and afterEach

Declares an action executed before (beforeEach) or after (afterEach) an example.

beforeEach {
    counter.increment()
}

memoized

Declares a special delegate. See RSpec let.

  • The delegated object is created on the first access.
  • The object is cached during an example execution.
  • The object is removed after the example execution.
val counter by memoized { Counter.Impl() }

This is a direct equivalent of the following xUnit declaration.

var counter: Counter? = null

@BeforeEach fun setUp() {
    counter = Counter.Impl()
}

@AfterEach fun tearDown() {
    counter = null
}