{"id":47167937,"url":"https://github.com/slavsan/gospec","last_synced_at":"2026-03-13T04:39:29.616Z","repository":{"id":174598898,"uuid":"651214467","full_name":"slavsan/gospec","owner":"slavsan","description":"A BDD testing library for the Go programming language, inspired by rspec and Cucumber.","archived":false,"fork":false,"pushed_at":"2024-03-08T06:05:06.000Z","size":137,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-14T14:43:04.144Z","etag":null,"topics":["bdd","cucumber","go","test","testing"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/slavsan/gospec","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/slavsan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-06-08T19:00:32.000Z","updated_at":"2024-01-20T16:16:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"e6595c5d-09f1-4e7d-b0d9-7c41e2ef3c4e","html_url":"https://github.com/slavsan/gospec","commit_stats":null,"previous_names":["slavsan/gospec"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/slavsan/gospec","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavsan%2Fgospec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavsan%2Fgospec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavsan%2Fgospec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavsan%2Fgospec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/slavsan","download_url":"https://codeload.github.com/slavsan/gospec/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/slavsan%2Fgospec/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30458003,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-13T03:55:51.346Z","status":"ssl_error","status_checked_at":"2026-03-13T03:55:33.055Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","cucumber","go","test","testing"],"created_at":"2026-03-13T04:39:29.342Z","updated_at":"2026-03-13T04:39:29.592Z","avatar_url":"https://github.com/slavsan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gospec\n\nGospec is a BDD testing library for the Go programming language.\n\nIt's influenced by rspec/mocha and other similar libraries, and also the Cucumber testing library. Gospec provides a similar and familiar developer experience.\n\nThe library is a fairly thin layer on top of the standard Go tests. The goal of the project is to use the underlying testing mechanism set by the Go standard library and only provide a means to define tests (specs and features) for a better BDD testing experience.\n\nGospec has zero dependencies and the intention is for this to not change.\n\n## Usage\n\nThe intended usage is to have the standard Go tests, defined like so `func TestMyFeature(t *testing.T) {`, then use the gospec library to initialize a `Suite` or `FeatureSuite` depending on which API is preferred.\n\n\u003cdetails\u003e\n    \u003csummary\u003eTest suite example\u003c/summary\u003e\n\n```go\nimport (\n\t\"testing\"\n\n\t\"github.com/slavsan/gospec\"\n)\n\nfunc TestCartSpec(t *testing.T) {\n\tgospec.WithSpecSuite(t, func(s *gospec.SpecSuite) {\n\t\tdescribe, beforeEach, it := s.API()\n\t\t\n\t\tdescribe(\"Cart\", func() {\n\t\t\tvar cart []string\n\n\t\t\tbeforeEach(func() {\n\t\t\t\tcart = []string{\n\t\t\t\t\t\"Gopher Toy\",\n\t\t\t\t\t\"Crab Toy\",\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tdescribe(\"cart updates\", func() {\n\t\t\t\tdescribe(\"given a new item has already been added\", func() {\n\t\t\t\t\tbeforeEach(func(t *testing.T) {\n\t\t\t\t\t\tcart = append(cart, \"Lizard toy\")\n\t\t\t\t\t})\n\n\t\t\t\t\tdescribe(\"when we remove the second item\", func() {\n\t\t\t\t\t\tbeforeEach(func(t *testing.T) {\n\t\t\t\t\t\t\tcart = []string{cart[0], cart[2]}\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tit(\"then the cart should contain the correct two items\", func(t *testing.T) {\n\t\t\t\t\t\t\tassert.Equal(t, []string{\"Gopher Toy\", \"Lizard toy\"}, cart)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tdescribe(\"removing items from the cart\", func() {\n\t\t\t\tdescribe(\"given the second item has already been removed\", func() {\n\t\t\t\t\tbeforeEach(func(t *testing.T) {\n\t\t\t\t\t\tcart = cart[:1]\n\t\t\t\t\t})\n\n\t\t\t\t\tdescribe(\"when we remove the first item\", func() {\n\t\t\t\t\t\tbeforeEach(func(t *testing.T) {\n\t\t\t\t\t\t\tcart = cart[:0]\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tit(\"then the cart should contain 0 items\", func(t *testing.T) {\n\t\t\t\t\t\t\tassert.Equal(t, []string{}, cart)\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eTest suite example with parallel execution\u003c/summary\u003e\n\n```go\nimport (\n\t\"testing\"\n\n\t\"github.com/slavsan/gospec\"\n)\n\nfunc TestCartSpec(t *testing.T) {\n\tgospec.WithSpecSuite(t, func(s *gospec.SpecSuite) {\n\t\tdescribe, beforeEach, it := s.ParallelAPI()\n\n\t\tdescribe(\"Cart\", func() {\n\t\t\tbeforeEach(func(t *testing.T, w *gospec.World) {\n\t\t\t\tw.Set(\"cart\", []string{\n\t\t\t\t\t\"Gopher Toy\",\n\t\t\t\t\t\"Crab Toy\",\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tdescribe(\"cart updates\", func() {\n\t\t\t\tdescribe(\"given a new item has already been added\", func() {\n\t\t\t\t\tbeforeEach(func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return append(cart.([]string), \"Lizard toy\") })\n\t\t\t\t\t})\n\n\t\t\t\t\tdescribe(\"when we remove the second item\", func() {\n\t\t\t\t\t\tbeforeEach(func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { c := cart.([]string); return []string{c[0], c[2]} })\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tit(\"then the cart should contain the correct two items\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\t\tassert.Equal(w.T, []string{\"Gopher Toy\", \"Lizard toy\"}, w.Get(\"cart\"))\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tdescribe(\"removing items from the cart\", func() {\n\t\t\t\tdescribe(\"given the second item has already been removed\", func() {\n\t\t\t\t\tbeforeEach(func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return cart.([]string)[:1] })\n\t\t\t\t\t})\n\n\t\t\t\t\tdescribe(\"when we remove the first item\", func() {\n\t\t\t\t\t\tbeforeEach(func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return cart.([]string)[:0] })\n\t\t\t\t\t\t})\n\n\t\t\t\t\t\tit(\"then the cart should contain 0 items\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\t\t\tassert.Equal(w.T, []string{}, w.Get(\"cart\"))\n\t\t\t\t\t\t})\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eFeature Test suite example\u003c/summary\u003e\n\n```go\nimport (\n\t\"testing\"\n\n\t\"github.com/slavsan/gospec\"\n)\n\nfunc TestCartFeature(t *testing.T) {\n\tgospec.WithFeatureSuite(t, func(s *gospec.FeatureSuite) {\n\t\tfeature, background, scenario, given, when, then, _ := s.API()\n\n\t\tfeature(\"Cart\", func() {\n\t\t\tvar cart []string\n\n\t\t\tbackground(func() {\n\t\t\t\tgiven(\"there is a cart with three items\", func(t *testing.T) {\n\t\t\t\t\tcart = []string{\n\t\t\t\t\t\t\"Gopher Toy\",\n\t\t\t\t\t\t\"Crab Toy\",\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tscenario(\"cart updates\", func() {\n\t\t\t\tgiven(\"a new item has already been added\", func(t *testing.T) {\n\t\t\t\t\tcart = append(cart, \"Lizard toy\")\n\t\t\t\t})\n\t\t\t\twhen(\"we remove the second item\", func(t *testing.T) {\n\t\t\t\t\tcart = []string{cart[0], cart[2]}\n\t\t\t\t})\n\t\t\t\tthen(\"the cart should contain the correct two items\", func(t *testing.T) {\n\t\t\t\t\tassert.Equal(t, []string{\"Gopher Toy\", \"Lizard toy\"}, cart)\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tscenario(\"removing items from the cart\", func() {\n\t\t\t\tgiven(\"the second item has already been removed\", func(t *testing.T) {\n\t\t\t\t\tcart = cart[:1]\n\t\t\t\t})\n\t\t\t\twhen(\"we remove the first item\", func(t *testing.T) {\n\t\t\t\t\tcart = cart[:0]\n\t\t\t\t})\n\t\t\t\tthen(\"the cart should contain 0 items\", func(t *testing.T) {\n\t\t\t\t\tassert.Equal(t, []string{}, cart)\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n}\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n    \u003csummary\u003eFeature Test suite example with parallel execution\u003c/summary\u003e\n\n```go\nimport (\n\t\"testing\"\n\t\n\t\"github.com/slavsan/gospec\"\n)\n\nfunc TestCartFeature(t *testing.T) {\n\tgospec.WithFeatureSuite(t, func(s *gospec.FeatureSuite) {\n\t\tfeature, background, scenario, given, when, then := s.ParallelAPI()\n\n\t\tfeature(\"Cart\", func() {\n\t\t\tbackground(func() {\n\t\t\t\tgiven(\"there is a cart with three items\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tw.Set(\"cart\", []string{\n\t\t\t\t\t\t\"Gopher Toy\",\n\t\t\t\t\t\t\"Crab Toy\",\n\t\t\t\t\t})\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tscenario(\"cart updates\", func() {\n\t\t\t\tgiven(\"a new item has already been added\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return append(cart.([]string), \"Lizard toy\") })\n\t\t\t\t})\n\t\t\t\twhen(\"we remove the second item\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { c := cart.([]string); return []string{c[0], c[2]} })\n\t\t\t\t})\n\t\t\t\tthen(\"the cart should contain the correct two items\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tassert.Equal(w.T, []string{\"Gopher Toy\", \"Lizard toy\"}, w.Get(\"cart\"))\n\t\t\t\t})\n\t\t\t})\n\n\t\t\tscenario(\"removing items from the cart\", func() {\n\t\t\t\tgiven(\"the second item has already been removed\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return cart.([]string)[:1] })\n\t\t\t\t})\n\t\t\t\twhen(\"we remove the first item\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tw.Swap(\"cart\", func(cart any) any { return cart.([]string)[:0] })\n\t\t\t\t})\n\t\t\t\tthen(\"the cart should contain 0 items\", func(t *testing.T, w *gospec.World) {\n\t\t\t\t\tassert.Equal(w.T, []string{}, w.Get(\"cart\"))\n\t\t\t\t})\n\t\t\t})\n\t\t})\n\t})\n}\n```\n\u003c/details\u003e\n\n## Options\n\nWhen initializing `SpecSuite` or `FeatureSuite` instances, there are several options to enhance the developer experience.\n\n- `Output` for specifying one, or multiple, custom output writers. The `Output` option also supports several useful sub-options:\n    - `Colorful`\n    - `Durations`\n    - `PrintFilenames`\n    - `IndentTwoSpaces`\n    - `IndentFourSpaces`\n    - `IndentOneTab`\n\n### Parallel execution\n\nGospec supports parallel execution of tests.\n\nOne important caveat is that in order to do that, your tests would need to use the `ParallelAPI` (instead of the `API`) method, and will need to utilize the `World` struct which gets passed to all of your test functions, e.g. `beforeEach`, `it`, etc., or `given`, `when`, `then` in the case of `FeatureSpec` suites.\n\nThis is necessary since the way `gospec` works, it needs to store any contextual data used in one suite separate from the scope of other tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslavsan%2Fgospec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fslavsan%2Fgospec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fslavsan%2Fgospec/lists"}