Go testing in the browser. Integrates with `go test`. Write behavioral tests in Go.

GoConvey is awesome Go testing

Build Status GoDoc

Welcome to GoConvey, a yummy Go testing tool for gophers. Works with go test. Use it in the terminal or browser according to your viewing pleasure. View full feature tour.

Features:

  • Directly integrates with go test
  • Fully-automatic web UI (works with native Go tests, too)
  • Huge suite of regression tests
  • Shows test coverage (Go 1.2+)
  • Readable, colorized console output (understandable by any manager, IT or not)
  • Test code generator
  • Desktop notifications (optional)
  • Immediately open problem lines in Sublime Text (some assembly required)

You can ask questions about how to use GoConvey on StackOverflow. Use the tags go and goconvey.

Menu:

Installation

$ go get github.com/smartystreets/goconvey

Quick start

Make a test, for example:

package package_name

import (
    "testing"
    . "github.com/smartystreets/goconvey/convey"
)

func TestSpec(t *testing.T) {

	// Only pass t into top-level Convey calls
	Convey("Given some integer with a starting value", t, func() {
		x := 1

		Convey("When the integer is incremented", func() {
			x++

			Convey("The value should be greater by one", func() {
				So(x, ShouldEqual, 2)
			})
		})
	})
}

In the browser

Start up the GoConvey web server at your project's path:

$ $GOPATH/bin/goconvey

Then watch the test results display in your browser at:

http://localhost:8080

If the browser doesn't open automatically, please click http://localhost:8080 to open manually.

There you have it. As long as GoConvey is running, test results will automatically update in your browser window.

The design is responsive, so you can squish the browser real tight if you need to put it beside your code.

The web UI supports traditional Go tests, so use it even if you're not using GoConvey tests.

In the terminal

Just do what you do best:

$ go test

Or if you want the output to include the story:

$ go test -v

Documentation

Check out the

  • GoConvey wiki,
  • GoDoc
  • and the *_test.go files scattered throughout this project.

Screenshots

For web UI and terminal screenshots, check out the full feature tour.

Contributors

GoConvey is brought to you by SmartyStreets and several contributors (Thanks!).

Owner
SmartyStreets
World champion of location data intelligence 🏅 Our APIs verify, validate, enrich, standardize, geocode, and auto-complete addresses at blazing speed.
SmartyStreets
Comments
  • If an assertion fails, it should stop further assertions in the same test (fail fast)

    If an assertion fails, it should stop further assertions in the same test (fail fast)

    The problem that if you assert if an array has items in it, to be able to assert the data in the items, and if the array is empty a panic will occur in Goconvey. This is not the case if running just go test. The default behaviour of other test suites is that if an assertion fails it stop and don't assert any further in that test case.

  • Ignore folders when searching for tests

    Ignore folders when searching for tests

    I noticed that running goconvey also navigates my /examples folder for tests and tries to build go files found inside them. In my project, this causes a build failure as some of these examples require a specific setup (e.g. appengine).

    My suggestion is the have a .goconvey file containing folder names to skip (similar to .gitignore).

  • Fix #4 by introducing optional test randomization

    Fix #4 by introducing optional test randomization

    So... that wasn't too bad either :) However, the test output (both story and json) are basically garbled junk :(.

    What's the right thing to do with reporting? I could:

    1. buffer everything till the end and emit it in a stable sort order
    2. stream the output (but emit stories multiple times)
    3. ???

    1 is pretty explanatory

    2 would be something like:

    Convey("A", t, func() {
      Convey("B", func() {
        Convey("C", nil)
        Convey("D", nil)
      })  
      Convey("F", func() {
        Convey("G", nil)
      })
    })
    

    Could emit:

    A
      B
        C
      F
        G
      B
        D
    

    (assuming that's how they randomized).

    Or is there another idea?

  • Test coverage becomes 0

    Test coverage becomes 0

    [19:59:38.121] Compiling package statistics
    [19:59:38.133]     Assertions: 47
    [19:59:38.134]         Passed: 47
    [19:59:38.134]        Skipped: 0
    [19:59:38.135]       Failures: 0
    [19:59:38.135]         Panics: 0
    [19:59:38.135] Build Failures: 0
    [19:59:38.136]       Coverage: 0%
    

    I just tried out the new UI, it is awesome! But I got 0% test coverage :(

  • ATTENTION: GoConvey maintainers wanted!

    ATTENTION: GoConvey maintainers wanted!

    We'd like to open the project up to additional maintainers who want to move the project forward in a meaningful way.

    We've spent significant time at SmartyStreets building GoConvey and it has perfectly met (and exceeded) all of our initial design specifications. We've used it to great effect. Being so well-matched to our development workflows at SmartyStreets, we haven't had a need to hack on it lately. This had been frustrating to many in the community who have ideas for the project and would like to see new features released (and some old bugs fixed). The release of Go 1.5 and the new vendoring experiment has been a source of confusion and hassle for those who have already upgraded and find that GoConvey needs to be brought up to speed.

    Comment below if you're interested. Preference will be given to those that have already contributed to the project. Checkout the issues listing if you need some ideas for contributing.

    GoConvey is a popular 2-pronged, open-source github project (1,600+ stargazers, 100+ forks):

    • A package you import in your test code that allows you to write BDD-style tests.
    • An executable that runs a local web server which displays auto-updating test results in a web browser.

    http://goconvey.co/ https://github.com/smartystreets/goconvey https://github.com/smartystreets/goconvey/wiki

    I should mention that the assertions package imported by the convey package is used by other projects at SmartyStreets and so we will be continuing to maintain that project internally.

    We hope to hear from you soon. Thanks!

  • Top-level calls to Convey for Go1.12

    Top-level calls to Convey for Go1.12

    --- FAIL: TestGetAccount (0.00s) panic: Top-level calls to Convey(...) need a reference to the testing.T. Hint: Convey("description here", t, func() { / notice that the second argument was the *testing.T (t)! */ }) [recovered] panic: Top-level calls to Convey(...) need a reference to the testing.T. Hint: Convey("description here", t, func() { / notice that the second argument was the *testing.T (t)! */ }) [recovered] panic: Top-level calls to Convey(...) need a reference to the testing.T. Hint: Convey("description here", t, func() { / notice that the second argument was the *testing.T (t)! */ })

    ` func TestGetAccount(t *testing.T) {

    Convey("test1", t, func() {
    	Convey("test1-1", func() {
    		 //...
    	})
    })
    

    }`

  • What are your suggestions for the web interface?

    What are your suggestions for the web interface?

    I'm collecting some ideas for a major upgrade to the graphical interface for GoConvey, so long as my free time permits. (Free time? What's that.)

    What would you like to see new or improved? How's the layout? Is everything intuitive? What about it drives you crazy that you'd like changed? (Or what do you really like that you want to make sure never goes away?)

    I will consider all suggestions but I will also accept them at my own discretion... and I'm not promising any timeline.

    Not guaranteed, but on the list already (depending on feasibility):

    • [ ] ~~Preserve package "ignore" settings across server instances~~
    • [x] Preserve collapsed packages across test runs
    • [x] Full coverage report from the cover tool by clicking on package name (requires server changes)
    • [ ] ~~Open browser window to localhost:8080 when GoConvey server starts up~~ (not for now)
    • [x] Light and dark theme
    • [x] Custom themes
    • [x] Test history
    • [x] Pause auto-execution of tests
    • [x] Keyboard shortcuts (issue #102)
    • [x] Better of use of space, depending if tests pass/fail/etc.
    • [x] Resources are locally stored (can work offline)
    • [ ] ~~Basic delta between tests~~ (not for now)
    • [x] Better coverage stats (aggregated results, etc.)
    • [x] Toggle debug output that appears alongside test cases
    • [x] Tests skipped with t.Skip() should be marked as skip, not failure (issue #115)

    Feel free to +1 any already mentioned that you really want.

  • Add feature to ignore packages

    Add feature to ignore packages

    From the web UI, we should be able to specify fully qualified package names to ignore in case large dependencies (or broken dependencies) start to get in the way or slow things down.

  • This code should produce 10 assertions, not 1.

    This code should produce 10 assertions, not 1.

    package tutorial
    
    import (
        "fmt"
        . "github.com/smartystreets/goconvey/convey"
        "testing"
    )
    
    func TestFizzBuzz(t *testing.T) {
        cases := map[int]string{
            1:  "1",
            2:  "2",
            3:  "fizz",
            4:  "4",
            5:  "buzz",
            6:  "fizz",
            7:  "7",
            8:  "8",
            9:  "fizz",
            10: "buzz",
            15: "fizzbuzz",
        }
    
        Convey("Given a bunch of test cases", t, func() {
            for input, expected := range cases {
                Convey(fmt.Sprintf("Fizzbuzz for %d should equal '%s'", input, expected), func() {
                    So(fizzbuzz(input), ShouldEqual, expected)
                })
            }
        })
    }
    
    ===================
    
    
    $ go test -v
    === RUN TestFizzBuzz
    
      Given a bunch of test cases 
        Fizzbuzz for 1 should equal '1' ✔
    
    1 assertion thus far
    
    --- PASS: TestFizzBuzz (0.00 seconds)
    PASS
    ok      github.com/smartystreets/tutorial   0.022s
    
    
  • Nested scope

    Nested scope

    Fix #81 for real this time, Closes #261.

    Includes:

    • New tree-based state in Convey execution, using jtolds/gls for goroutine-local storage
    • New (optional) explicit context passing when you need to bridge a goroutine invocation
    • Minimal fixes for the reporting package to ensure they work with the tree-based state
  • Consider not remove leading space and not wrapping in test failure output

    Consider not remove leading space and not wrapping in test failure output

    I have test output that looks like this:

    --- FAIL: TestParseErr (0.00 seconds)
            parse_test.go:317: Parse error case: conditional arg  1:
                     Got: "/err_test/path:1: expected [\"(\", \"<TYP_SINGLE_QUOTED_STR>\", \"<TYP_DOUBLE_QUOTED_STR>\"]; found: \"a1\""
                    Want: "/err_test/path:1: expected [\"<TYP_SINGLE_QUOTED_STR>\", \"<TYP_DOUBLE_QUOTED_STR>\"]; found: \"a1\""
    FAIL
    exit status 1
    

    Notice the single extra space before the word "Got" that causes it to align with the word "Want". Also, notice the horizontal scrollbar that appears when github displays the message (i.e. no wrapping). Together these two properties make it easy for me to compare the two lines visually.

    It would be nice if the "FAILURES" or "STORIES" sections could be configured to display their output in this way. It's not too big a deal if they don't since I can always copy the output into a text editor and format it accordingly. Those are just extra steps that would be nice to be able to skip.

  • CVE-2022-24785: Moment.js Path Traversal < 2.29.2

    CVE-2022-24785: Moment.js Path Traversal < 2.29.2

    https://nvd.nist.gov/vuln/detail/cve-2022-24785

    Severity: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N -- 7.5 High

    Current version in head branch: https://github.com/smartystreets/goconvey/blob/883c12515e6101b79f430987b4fd0ee50841bfe6/web/client/resources/js/lib/moment.js#L1-L2

  • SoMsg didn't print out msg in test report

    SoMsg didn't print out msg in test report

    I'm personally using Goland, code snippet is like below

    SoMsg(testCase.desc, runFunc(flow), ShouldEqual, testCase.expectedRes)

    Test report is like following in IDE: Line 70: Expected: 'true' Actual: 'false' (Should be equal)

    Didn't see any msg from test case

  • convey.So bug report: errors.New() compares with nil return wrong result

    convey.So bug report: errors.New() compares with nil return wrong result

    Version: v1.7.2 ApplyFunc use github.com/agiledragon/gomonkey/v2 v2.1.0

    Code:

    func Test(t *testing.T) {
    	Convey("Test", t, func() {
    		defer ApplyFunc(json.Marshal, func(v interface{}) ([]byte, error) {
    			return nil, errors.New("test shouldNotEqual")
    		}).Reset()
    
    		_, err := json.Marshal("")
    		So(err, ShouldNotEqual, nil)
    	})
    }
    

    Result:

    Failures:
      Line 97:
      Expected     'test shouldNotEqual'
      to NOT equal '<nil>'
      (but it did)!
    
    
    1 total assertion
    
    --- FAIL: Test (0.00s)
    
    FAIL
    
  • ShouldResemble failing for identical values in GitHub action

    ShouldResemble failing for identical values in GitHub action

    Using go 1.19 (also happened with go 1.18) and goconvey v1.7.2 both locally and in a GitHub action, my tests pass locally but fail in GitHub:

    https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true

    Failures:
    [144](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:145)
    
    [145](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:146)
      * /home/runner/work/wrstat/wrstat/server/server_test.go 
    [146](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:147)
      Line 450:
    [147](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:148)
      Expected: '[]*server.DirSummary{(*server.DirSummary){Dir:"/a", Count:15, Size:86, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"adm", "docker", "root"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b", Count:9, Size:80, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b/d", Count:7, Size:70, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"cram"}}, (*server.DirSummary){Dir:"/a/b/e/h", Count:2, Size:10, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "temporary"}}, (*server.DirSummary){Dir:"/a/c/d", Count:5, Size:5, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root"}, Groups:[]string{"adm"}, FileTypes:[]string{"cram"}}}'
    [148](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:149)
      Actual:   '[]*server.DirSummary{(*server.DirSummary){Dir:"/a", Count:15, Size:86, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"adm", "docker", "root"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b", Count:9, Size:80, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b/d", Count:7, Size:70, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"cram"}}, (*server.DirSummary){Dir:"/a/b/e/h", Count:2, Size:10, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "temporary"}}, (*server.DirSummary){Dir:"/a/c/d", Count:5, Size:5, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root"}, Groups:[]string{"adm"}, FileTypes:[]string{"cram"}}}'
    [149](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:150)
      (Should resemble)!
    [150](https://github.com/wtsi-ssg/wrstat/runs/7804713143?check_suite_focus=true#step:4:151)
      Diff:     '[]*server.DirSummary{(*server.DirSummary){Dir:"/a", Count:15, Size:86, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"adm", "docker", "root"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b", Count:9, Size:80, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "cram", "temporary"}}, (*server.DirSummary){Dir:"/a/b/d", Count:7, Size:70, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root", "runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"cram"}}, (*server.DirSummary){Dir:"/a/b/e/h", Count:2, Size:10, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"runner"}, Groups:[]string{"docker"}, FileTypes:[]string{"bam", "temporary"}}, (*server.DirSummary){Dir:"/a/c/d", Count:5, Size:5, Atime:time.Time{1970-01-01 00:00:50 +0000 UTC}, Users:[]string{"root"}, Groups:[]string{"adm"}, FileTypes:[]string{"cram"}}}'
    

    You will note that the "Expected" and "Actual" strings that it prints out are actually identical.

    Why would this be happening, and what can I do about it?

  • ShouldResemble for proto messages

    ShouldResemble for proto messages

    Comparison of proto Messages performed using ShouldResemble is unreliable.

    Consider this code:

    package main
    
    import (
    	. "github.com/smartystreets/goconvey/convey"
    	"google.golang.org/protobuf/types/known/wrapperspb"
    	"log"
    	"testing"
    )
    
    func TestConveyBug(t *testing.T) {
    	Convey("Given something", t, func() {
    		var x = &wrapperspb.BoolValue{Value: false}
    		var y = &wrapperspb.BoolValue{Value: false}
    		log.Printf("Receive type %v", x)
    
    		So(x, ShouldResemble, y)
    	})
    }
    

    The call to Printf causes x.String() to be called. This in turn initializes the state and its atomicMessageInfo field on the proto message. Therefore x has the atomicMessageInfo set, while y doesn't. This causes reflect.DeepEqual to return false.

    Another problem stems from the rendering of the diff (#660).

    Could a ShouldResembleProto be added for expliciting comparing proto messages? It should call proto.Equal.

Ruby on Rails like test fixtures for Go. Write tests against a real database

testfixtures Warning: this package will wipe the database data before loading the fixtures! It is supposed to be used on a test database. Please, doub

Jan 8, 2023
A next-generation testing tool. Orion provides a powerful DSL to write and automate your acceptance tests

Orion is born to change the way we implement our acceptance tests. It takes advantage of HCL from Hashicorp t o provide a simple DSL to write the acceptance tests.

Aug 31, 2022
Rr-e2e-tests - Roadrunner end-to-end tests repository
Rr-e2e-tests - Roadrunner end-to-end tests repository

RoadRunner end-to-end plugins tests License: The MIT License (MIT). Please see L

Dec 15, 2022
Terratest is a Go library that makes it easier to write automated tests for your infrastructure code.

Terratest is a Go library that makes it easier to write automated tests for your infrastructure code. It provides a variety of helper functions and patterns for common infrastructure testing tasks,

Dec 30, 2022
A tool that integrates SQL, HTTP,interface,Redis mock

Mockit 目标:将mock变得简单,让代码维护变得容易 分支介绍 main 主分支,覆盖了单元测试 light 轻分支,去除了单元测试,简化了依赖项,方便其他团队使用 常见Mock难点 不同中间件,mock库设计模式不一致,学习代价高,差异化明显 mock方案强依赖服务端,无法灵活解耦 单元测试

Sep 22, 2022
Extremely flexible golang deep comparison, extends the go testing package and tests HTTP APIs
Extremely flexible golang deep comparison, extends the go testing package and tests HTTP APIs

go-testdeep Extremely flexible golang deep comparison, extends the go testing package. Latest news Synopsis Description Installation Functions Availab

Dec 22, 2022
Testing framework for Go. Allows writing self-documenting tests/specifications, and executes them concurrently and safely isolated. [UNMAINTAINED]

GoSpec GoSpec is a BDD-style testing framework for the Go programming language. It allows writing self-documenting tests/specs, and executes them in p

Nov 28, 2022
go-test-trace is like go test but it also generates distributed traces.
go-test-trace is like go test but it also generates distributed traces.

go-test-trace go-test-trace is like go test but it also generates distributed traces. Generated traces are exported in OTLP to a OpenTelemetry collect

Jan 5, 2023
Flugel Test Documentation for steps to run and test the automatio
Flugel Test Documentation for steps to run and test the automatio

Flugel Test Documentation Documentation for steps to run and test the automation #Test-01 1 - Local Test Using Terratest (End To End) 1- By runing " t

Nov 13, 2022
Test-assignment - Test assignment with golang
Test-assignment - Test assignment with golang

test-assignment We have a two steam of data and we need to save it in the map: I

Jan 19, 2022
This repository includes consumer driven contract test for provider, unit test and counter api.

This repository includes consumer driven contract test for provider, unit test and counter api.

Feb 1, 2022
Full-featured test framework for Go! Assertions, mocking, input testing, output capturing, and much more! 🍕
Full-featured test framework for Go! Assertions, mocking, input testing, output capturing, and much more! 🍕

testza ?? Testza is like pizza for Go - you could life without it, but why should you? Get The Module | Documentation | Contributing | Code of Conduct

Dec 10, 2022
Testy is a Go test running framework designed for Gametime's API testing needs.

template_library import "github.com/gametimesf/template_library" Overview Index Overview Package template_library is a template repository for buildin

Jun 21, 2022
This testing tool surrounds go-ethereum with cannon to catch the blocks of retesteth going into go-ethereum and test cannon with them

Siege This testing tool surrounds go-ethereum with cannon to catch the blocks of retesteth going into go-ethereum and test cannon with them. Usage Sta

Mar 15, 2022
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.
siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

siusiu (suite-suite harmonics) a suite used to manage the suite, designed to free penetration testing engineers from learning and using various security tools, reducing the time and effort spent by penetration testing engineers on installing tools, remembering how to use tools.

Dec 12, 2022
A yaml data-driven testing format together with golang testing library

Specimen Yaml-based data-driven testing Specimen is a yaml data format for data-driven testing. This enforces separation between feature being tested

Nov 24, 2022
Package for comparing Go values in tests

Package for equality of Go values This package is intended to be a more powerful and safer alternative to reflect.DeepEqual for comparing whether two

Dec 29, 2022
Record and replay your HTTP interactions for fast, deterministic and accurate tests

go-vcr go-vcr simplifies testing by recording your HTTP interactions and replaying them in future runs in order to provide fast, deterministic and acc

Dec 25, 2022
Automatically update your Go tests

autogold - automatically update your Go tests autogold makes go test -update automatically update your Go tests (golden files and Go values in e.g. fo

Dec 25, 2022