spec

package module
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 13, 2019 License: Apache-2.0 Imports: 6 Imported by: 7

README

spec

Build Status GoDoc

Spec is a simple BDD test organizer for Go. It minimally extends the standard library testing package by facilitating easy organization of Go 1.7+ subtests.

Spec differs from other BDD libraries for Go in that it:

  • Does not reimplement or replace any functionality of the testing package
  • Does not provide an alternative test parallelization strategy to the testing package
  • Does not provide assertions
  • Does not encourage the use of dot-imports
  • Does not reuse any closures between test runs (to avoid test pollution)
  • Does not use global state, excessive interface types, or reflection

Spec is intended for gophers who want to write BDD tests in idiomatic Go using the standard library testing package. Spec aims to do "one thing right," and does not provide a wide DSL or any functionality outside of test organization.

Features
  • Clean, simple syntax
  • Supports focusing and pending tests
  • Supports sequential, random, reverse, and parallel test order
  • Provides granular control over test order and subtest nesting
  • Provides a test writer to manage test output
  • Provides a generic, asynchronous reporting interface
  • Provides multiple reporter implementations
Notes
  • Use go test -v to see individual subtests.
Examples

Most functionality is demonstrated here.

Quick example:

func TestObject(t *testing.T) {
    spec.Run(t, "object", func(t *testing.T, when spec.G, it spec.S) {
        var someObject *myapp.Object

        it.Before(func() {
            someObject = myapp.NewObject()
        })

        it.After(func() {
            someObject.Close()
        })

        it("should have some default", func() {
            if someObject.Default != "value" {
                t.Error("bad default")
            }
        })

        when("something happens", func() {
            it.Before(func() {
                someObject.Connect()
            })

            it("should do one thing", func() {
                if err := someObject.DoThing(); err != nil {
                    t.Error(err)
                }
            })

            it("should do another thing", func() {
                if result := someObject.DoOtherThing(); result != "good result" {
                    t.Error("bad result")
                }
            })
        }, spec.Random())

        when("some slow things happen", func() {
            it("should do one thing in parallel", func() {
                if result := someObject.DoSlowThing(); result != "good result" {
                    t.Error("bad result")
                }
            })

            it("should do another thing in parallel", func() {
                if result := someObject.DoOtherSlowThing(); result != "good result" {
                    t.Error("bad result")
                }
            })
        }, spec.Parallel())
    }, spec.Report(report.Terminal{}))
}

With less nesting:

func TestObject(t *testing.T) {
    spec.Run(t, "object", testObject, spec.Report(report.Terminal{}))
}

func testObject(t *testing.T, when spec.G, it spec.S) {
    ...
}

For focusing/reporting across multiple files in a package:

var suite spec.Suite

func init() {
    suite = spec.New("my suite", spec.Report(report.Terminal{}))
    suite("object", testObject)
    suite("other object", testOtherObject)
}

func TestObjects(t *testing.T) {
	suite.Run(t)
}

func testObject(t *testing.T, when spec.G, it spec.S) {
	...
}

func testOtherObject(t *testing.T, when spec.G, it spec.S) {
	...
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Focus

func Focus(t *testing.T, text string, f func(*testing.T, G, S), opts ...Option) bool

Focus focuses every spec in the provided suite. This is useful as a shortcut for unfocusing all focused specs.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested Seed, Report

func Pend

func Pend(t *testing.T, text string, f func(*testing.T, G, S), _ ...Option) bool

Pend skips all specs in the top-level group.

All Options are ignored.

func Run

func Run(t *testing.T, text string, f func(*testing.T, G, S), opts ...Option) bool

Run immediately executes the provided specs as a suite. Unlike other testing libraries, it is re-evaluated for each spec.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested Seed, Report

Types

type G

type G func(text string, f func(), opts ...Option)

G defines a group of specs. Unlike other testing libraries, it is re-evaluated for each subspec.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested

func (G) Focus

func (g G) Focus(text string, f func(), opts ...Option)

Focus focuses the provided group. This skips all specs in the suite except the group and other focused specs.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested

func (G) Pend

func (g G) Pend(text string, f func(), _ ...Option)

Pend skips all specs in the provided group.

All Options are ignored.

type Option

type Option func(*config)

An Option controls the behavior of a suite, group, or spec. Options are inherited by subgroups and subspecs.

Example: If the top-level Run group is specified as Random(), each subgroup will inherit the Random() order. This means that each group will be randomized individually, unless another ordering is specified on any of the subgroups. If the Run group is also passed Global(), then all specs inside Run will run in completely random order, regardless of any ordering specified on the subgroups.

func Flat

func Flat() Option

Flat indicates that a parent subtest should not be created for the group. This is the default behavior.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Global

func Global() Option

Global indicates that test order applies globally to all descendant specs. For example, a group with Random() and Global() will run all descendant specs in random order, regardless of subgroup. Specs in different subgroups may be interleaved.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Local

func Local() Option

Local indicates that the test order applies to each subgroup individually. For example, a group with Random() and Local() will run all subgroups and specs in random order, and each subgroup will be randomized, but specs in different subgroups will not be interleaved. This is the default behavior.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Nested

func Nested() Option

Nested indicates that a parent subtest should be created for the group. This allows for more control over parallelism.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Parallel

func Parallel() Option

Parallel indicates that a spec or group of specs should be run in parallel. This Option is equivalent to t.Parallel().

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend, S

func Random

func Random() Option

Random indicates that a group of specs should be run in random order. Randomization is per group, such that all groupings are maintained.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Report

func Report(r Reporter) Option

Report specifies a Reporter for a suite.

Valid Option for: New, Run, Focus, Pend

func Reverse

func Reverse() Option

Reverse indicates that a group of specs should be run in reverse order.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

func Seed

func Seed(s int64) Option

Seed specifies the random seed used for any randomized specs in a Run block. The random seed is always displayed before specs are run. If not specified, the current time is used.

Valid Option for: New, Run, Focus, Pend

func Sequential

func Sequential() Option

Sequential indicates that a group of specs should be run in order. This is the default behavior.

Valid Option for: New, Run, Focus, Pend, Suite, Suite.Focus, Suite.Pend, G, G.Focus, G.Pend

type Plan

type Plan struct {
	Text      string
	Total     int
	Pending   int
	Focused   int
	Seed      int64
	HasRandom bool
	HasFocus  bool
}

A Plan provides a Reporter with information about a suite.

type Reporter

type Reporter interface {

	// Start provides the Reporter with a Plan that describes the suite.
	// No specs will run until the Start method call finishes.
	Start(*testing.T, Plan)

	// Specs provides the Reporter with a channel of Specs.
	// The specs will start running concurrently with the Specs method call.
	// The Run method will not complete until the Specs method call completes.
	Specs(*testing.T, <-chan Spec)
}

A Reporter is provided with information about a suite as it runs.

type S

type S func(text string, f func(), opts ...Option)

S defines a spec.

Valid Options: Parallel

func (S) After

func (s S) After(f func())

After runs a function after each spec in the group.

func (S) Before

func (s S) Before(f func())

Before runs a function before each spec in the group.

func (S) Focus

func (s S) Focus(text string, f func(), opts ...Option)

Focus focuses the provided spec. This skips all specs in the suite except the spec and other focused specs.

Valid Options: Parallel

func (S) Out

func (s S) Out() io.Writer

Out provides an dedicated writer for the test to store output. Reporters usually display the contents on test failure.

Valid context: inside S blocks only, nil elsewhere

func (S) Pend

func (s S) Pend(text string, f func(), _ ...Option)

Pend skips the provided spec.

All Options are ignored.

type Spec

type Spec struct {
	Text     []string
	Failed   bool
	Skipped  bool
	Focused  bool
	Parallel bool
	Out      io.Reader
}

A Spec provides a Reporter with information about a spec immediately after the spec completes.

type Suite added in v1.1.0

type Suite func(text string, f func(*testing.T, G, S), opts ...Option) bool

Suite defines a top-level group of specs within a suite. Suite behaves like a top-level version of G. Unlike other testing libraries, it is re-evaluated for each subspec.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested

func New added in v1.1.0

func New(text string, opts ...Option) Suite

New creates an empty suite and returns an Suite function. The Suite function may be called to add top-level groups to the suite. The suite may be executed with Suite.Run.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested Seed, Report

func (Suite) After added in v1.1.0

func (s Suite) After(f func(*testing.T)) bool

After runs a function after each spec in the suite.

func (Suite) Before added in v1.1.0

func (s Suite) Before(f func(*testing.T)) bool

Before runs a function before each spec in the suite.

func (Suite) Focus added in v1.1.0

func (s Suite) Focus(text string, f func(*testing.T, G, S), opts ...Option) bool

Focus focuses the provided top-level group. This skips all specs in the suite except the group and other focused specs.

Valid Options: Sequential, Random, Reverse, Parallel Local, Global, Flat, Nested

func (Suite) Pend added in v1.1.0

func (s Suite) Pend(text string, f func(*testing.T, G, S), _ ...Option) bool

Pend skips the provided top-level group of specs.

All Options are ignored.

func (Suite) Run added in v1.1.0

func (s Suite) Run(t *testing.T) bool

Run executes the specs defined in each top-level group of the suite.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL