it

package module
v2.2.4 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2025 License: MIT Imports: 8 Imported by: 1

README

It Should Be Tested.

The library implements a human-friendly syntax for assertions to validates correctness of your code. It's style allows to write BDD-like specifications: "X should Y", "A equals to B", etc.

Documentation Build Status Git Hub Coverage Status Go Report Card

Inspiration

There is a vision that change of code style in testing helps developers to "switch gears". It's sole purpose to write unit tests assertions in natural language. The library is inspired by features of ScalaTest and tries to adapt similar syntax for Golang.

It Should /* actual */ Be /* expected */

It Should X Equal Y
It Should X Less Y
It Should String X Contain Y
It Should Seq X Equal Y¹, ... Yⁿ

The approximation of the style into Golang syntax:

it.Then(t).
  Should(it.Equal(x, y)).
  Should(it.Less(x, y)).
  Should(it.String(x).Contain(y)).
  Should(it.Seq(x).Equal(/* ... */))

Getting Started

The latest version of the library is available at its main branch. All development, including new features and bug fixes, take place on the main branch using forking and pull requests as described in contribution guidelines. The stable version is available via Golang modules.

  1. Use go get to retrieve the library and add it as dependency to your application.
go get -u github.com/fogfish/it
  1. Import it in your unit tests
import (
  "github.com/fogfish/it"
)

See the go doc for api spec.

Style

The coding style is like standard Golang unit tests but assert are written as a chain of asserts in a specification style: "X should Y," "A must B," etc.

func TestMyFeature(t *testing.T) {
  /* Given */
  /*  ...  */

  /* When  */
  /*  ...  */

  it.Then(t).
    Should(/* X Equal Y */).
    Should(/* String X Contain Y */)
}

The library support 3 imperative keyword Must, Should and May as defined by RFC 2119. Its prohibition variants MustNot, ShouldNot and May.

Use the Skip imperative keyword to ignore the assert and its result.

Assertions

A first order logic expression asserts the result of unit test.

it.Then(t).
  // Inline logical predicates
  Should(it.True(x == y && x > 10)).
  // Use closed function
  Should(it.Be(func() bool { return x == y && x > 10})).
  // X should be same type as Y
  Should(it.SameAs(x, y)).
  // X should be nil
  Should(it.Nil(x))
Intercepts

Intercept any failures in target code block. Intercepts supports actual panics and function that return of errors.

func fWithPanic() {/* ... */}
func fWithError() error {/* ... */}

it.Then(t).
  // Intercept panic in the code block
  Should(it.Fail(fWithPanic)).
  // Intercept error in the code block
  Should(it.Fail(fWithError)).

Assert error for behavior to check the "type" of returned error

var err interface { Timeout() }

it.Then(t).
  // Intercept panic in the code block and assert for behavior
  Should(it.Fail(fWithPanic).With(&err)).
  Should(it.Fail(fWithError).With(&err)).
  //  Intercept panic in the code block and match the error code
  Should(it.Fail(fWithError).Contain("error code"))

The it.Fail interceptor evaluates code block inside and it is limited to function that return single value. The it.Error interceptor captures returns of function.

func fNaryError() (string, error) {/* ... */}

it.Then(t).
  Should(it.Error(fNaryError())).
  Should(it.Error(fNaryError()).With(&err)).
  Should(it.Error(fNaryError()).Contain("error code"))
Equality and identity

Match unit test results with equality constraint.

it.Then(t).Should(
  // X should be equal Y (equal support only scalar types)
  it.Equal(x, y),
  // X should be equivalent Y (supports any product types)
  it.Equiv(x, y),
  // X should be like Y (if one of value is interface)
  it.Like(x, y),
)
Ordering

Compare unit test results with ordering constraint.

it.Then(t).
  // X should be less than Y
  Should(it.Less(x, y)).
  // X should be less or equal to Y
  Should(it.LessOrEqual(x, y)).
  // X should be greater than Y
  Should(it.Greater(x, y)).
  // X should be greater or equal to Y
  Should(it.GreaterOrEqual(x, y)) 
String matchers
it.Then(t).
  // String X should have prefix X
  Should(it.String(x).HavePrefix(y)).
  // String X should have suffix X
  Should(it.String(x).HaveSuffix(y)).
  // String X should contain X
  Should(it.String(x).Contain(y)).
Slices and Sequence matchers
it.Then(t).
  // Seq X should be empty
  Should(it.Seq(x).BeEmpty(y)).
  // Seq X should equal Y¹, ... Yⁿ
  Should(it.Seq(x).Equal(y1, ..., yn))
  // Seq X should contain Y
  Should(it.Seq(x).Contain(y1, ..., yn))
  // Seq X should contain one of Y
  Should(it.Seq(x).Contain().OneOf(y1, ..., yn)).
  // Seq X should contain all of Y
  Should(it.Seq(x).Contain().AllOf(y1, ..., yn))
Map matchers
it.Then(t).
  // Map X should have key K with value Y
  Should(it.Map(X).Have(k, y)) 
JSON matchers

The matcher checks expected value against string pattern. It takes a valid JSON as string and compare it against input object. It matches only defined values and supports wildcard matching. For example:

// matches anything
`"_"`

// match string to regular expression
`"regex:example"` 

// matches any object with key "site"
`{"site": "_"}`

// matches array of length 1 
`["_"]`

// matches array of any length with head element equal to "example.com"
`["example", "..."]`

// matches any object with key "site" equal to "example.com"
`{"site": "example.com"}`

// matches any array of length 2 with first object having the key 
`[{"site": "_"}, "_"]`

// matches nested objects
`{"site": {"host": "_"}}`
it.Then(t).Should(
  it.Json(obj).Equiv(`{
    "foo": "bar"
  }`)
)

How To Contribute

The library is MIT licensed and accepts contributions via GitHub pull requests:

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

The build and testing process requires Go version 1.13 or later.

Build and run service in your development console. The following command boots Erlang virtual machine and opens Erlang shell.

git clone https://github.com/fogfish/gurl
cd gurl
go test -cover
commit message

The commit message helps us to write a good release note, speed-up review process. The message should address two question what changed and why. The project follows the template defined by chapter Contributing to a Project of Git book.

bugs

If you experience any issues with the library, please let us know via GitHub issues. We appreciate detailed and accurate reports that help us to identity and replicate the issue.

License

See LICENSE

Documentation

Overview

Package it implements a human-friendly syntax for assertions to validates correctness of your code. It's style allows to write BDD-like specifications: "X should Y", "A equals to B", etc.

Inspiration

There is a vision that change of code style in testing helps developers to "switch gears". It's sole purpose to write unit tests assertions in natural language. The library is inspired by features of http://www.scalatest.org and tries to adapt similar syntax for Golang.

It Should / actual / Be / expected /

It Should X Equal Y
It Should X Less Y
It Should String X Contain Y
It Should Seq X Equal Y¹, ... Yⁿ

The approximation of the style into Golang syntax:

it.Then(t).
  Should(it.Equal(x, y)).
  Should(it.Less(x, y)).
  Should(it.String(x).Contain(y)).
  Should(it.Seq(x).Equal(/ ... /))

Syntax at Glance

Each assertion begins with phrase:

it Then ...

Continues with one of imperative keyword as defined by RFC 2119

Must, Must Not, Should, Should Not, May, May Not

Assertions with inline closure is a technique to define arbitrary boolean expression.

it.Then(t).
  Should(it.True(be > 1 && be < 10 && be != 5))

Intercept any failures in target features

it.Then(t).
  ShouldNot(it.Fail(refToCodeBlock))

Matches equality and identity

it.Then(t).
  Should(it.Equal(x, y))

Matches type

it.Then(t).
  Should(it.SameAs(x, y))

Matches Order and Ranges

it.Ok(t).
  Should(it.Less(x, 10)).
  Should(it.LessOrEqual(x, 3)).
  Should(it.Greater(x, 1)).
  Should(it.GreaterOrEqual(x, 3)).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Be

func Be(f func() bool) error

Be assert logical predicated to the truth

it.Should(it.Be(myPredicate))

func Equal

func Equal[T comparable](x, y T) error

Equal check equality (x = y) of two scalar variables

it.Should(it.Equal(x, y))

func Equiv

func Equiv[T any](x, y T) error

Equiv check equality (x ≈ y) of two non scalar variables

it.Should(it.Equiv(x, y))

func Greater

func Greater[T Orderable](x, y T) error

Greater compares (x > y) of two scalar variables

it.Should(it.Greater(x, y))

func GreaterOrEqual

func GreaterOrEqual[T Orderable](x, y T) error

Greater compares (x >= y) of two scalar variables

it.Should(it.GreaterOrEqual(x, y))

func Less

func Less[T Orderable](x, y T) error

Less compares (x < y) two scalar variables

it.Should(it.Less(x, y))

func LessOrEqual

func LessOrEqual[T Orderable](x, y T) error

Less compares (x <= y) two scalar variables

it.Should(it.LessOrEqual(x, y))

func Like added in v2.1.0

func Like[T any](x any, y T) error

Equiv check equality (x ≈ y) of two non scalar variables

it.Should(it.Like(x, y))

func Nil

func Nil(x interface{}) error

Nil asserts the variable for the nil value

it.Should(it.Nil(x))

func SameAs

func SameAs[T any](x, y T) error

SameAs matches type of x, y

it.Should(it.SameAs(x, y))

func True

func True(x bool) error

True assert results of logical predicated to be true

it.Should(it.True( cnt > 10 ))

func TypeOf added in v2.1.0

func TypeOf[T any](x any) error

Matches TypeOf of value

Types

type Callable

type Callable interface {
	~func() error | ~func()
}

Callable type constraint for scope of Intercepts

type Check

type Check struct {
	// contains filtered or unexported fields
}

Check type is constructor of imperative testing expressions.

it.Then(t).Should( ... )

func Ok

func Ok(t *testing.T) *Check

Ok alias to Then

func Then

func Then(t *testing.T) *Check

Then creates assertion expression, it takes a reference to standard *testing.T interface to setup the evaluation context.

func (*Check) May

func (check *Check) May(errs ...error) *Check

May is an optional imperative constrain. Its violation do not impact on testing flow in anyway. The informative warning message is produced to console if assert is failed. Error message will be printed only if the test fails or the -test.v

func (*Check) MayNot

func (check *Check) MayNot(errs ...error) *Check

MayNot is an optional imperative constrain. Its violation do not impact on testing flow in anyway. The informative warning message is produced to console if assert is not failed. Error message will be printed only if the test fails or the -test.v

func (*Check) Must

func (check *Check) Must(errs ...error) *Check

Must is imperative keyword. The assert definition is an absolute requirement. It terminates execution of tests if assert is failed.

func (*Check) MustNot

func (check *Check) MustNot(errs ...error) *Check

MustNot is imperative keyword. The definition is an absolute prohibition It terminates execution of tests if assert is not failed.

func (*Check) Should

func (check *Check) Should(errs ...error) *Check

Should is imperative keyword. The assert definition is a strongly recommended requirement. However it's violation do not block continuation of testing. The test fails if assert is failed.

func (*Check) ShouldNot

func (check *Check) ShouldNot(errs ...error) *Check

ShouldNot is imperative keyword. The assert definition is a strongly recommended prohibition. However it's violation do not block continuation of testing. The test fails if assert is not failed.

func (*Check) Skip

func (check *Check) Skip(errs ...error) *Check

Skip is imperative keyword It ignores results of assert

type FailIt

type FailIt struct {
	// contains filtered or unexported fields
}

FailIt extend Fail assert

func Error

func Error[A any](x A, err error) FailIt

Error checks return values of function on the error cases

it.Should(it.Error(refToCodeBlock()))

func Fail

func Fail[T Callable](f T) FailIt

Fail catches any errors caused by the function under the test.

it.Should(it.Fail(refToCodeBlock))

func (FailIt) As

func (x FailIt) As(target any) bool

func (FailIt) Contain

func (x FailIt) Contain(y string) error

Contain asserts error string for expected term

it.Should(it.Fail(refToCodeBlock).Contain("not found"))

func (FailIt) Error

func (x FailIt) Error() string

func (FailIt) With

func (x FailIt) With(y any) error

With asserts failure to the expected error

it.Should(it.Fail(refToCodeBlock).With(&notFound))

type JsonOf added in v2.2.0

type JsonOf[A any] struct {
	// contains filtered or unexported fields
}

func Json added in v2.2.0

func Json[A any](obj A) JsonOf[A]

func (JsonOf[A]) Equiv added in v2.2.0

func (obj JsonOf[A]) Equiv(shapes ...string) error

type MapOf

type MapOf[K comparable, V any] map[K]V

func Map

func Map[K comparable, V any](val map[K]V) MapOf[K, V]

func (MapOf[K, V]) Have

func (xs MapOf[K, V]) Have(key K, y V) error

type Orderable

type Orderable interface {
	~string |
		~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
		~float32 | ~float64
}

Orderable type constraint

type SeqContainIt

type SeqContainIt[A any] struct {
	// contains filtered or unexported fields
}

FailIt extend Fail assert

func (SeqContainIt[A]) AllOf

func (x SeqContainIt[A]) AllOf(ys ...A) error

func (SeqContainIt[A]) As

func (x SeqContainIt[A]) As(target any) bool

func (SeqContainIt[A]) Error

func (x SeqContainIt[A]) Error() string

func (SeqContainIt[A]) OneOf

func (x SeqContainIt[A]) OneOf(ys ...A) error

type SeqOf

type SeqOf[A any] []A

func Seq

func Seq[A any](seq []A) SeqOf[A]

func (SeqOf[A]) BeEmpty

func (xs SeqOf[A]) BeEmpty() error

func (SeqOf[A]) Contain

func (xs SeqOf[A]) Contain(ys ...A) SeqContainIt[A]

func (SeqOf[A]) Equal

func (xs SeqOf[A]) Equal(ys ...A) error

type String

type String string

func (String) Contain

func (x String) Contain(y string) error

func (String) HavePrefix

func (x String) HavePrefix(y string) error

func (String) HaveSuffix

func (x String) HaveSuffix(y string) error

Jump to

Keyboard shortcuts

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