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.
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(/* ... */))
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.
- Use
go get
to retrieve the library and add it as dependency to your application.
go get -u github.com/fogfish/it
- Import it in your unit tests
import (
"github.com/fogfish/it"
)
See the go doc for api spec.
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.
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))
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"))
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),
)
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))
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)).
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))
it.Then(t).
// Map X should have key K with value Y
Should(it.Map(X).Have(k, y))
The library is MIT licensed and accepts contributions via GitHub pull requests:
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - 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
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.
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.