{"id":13413860,"url":"https://github.com/earthboundkid/be","last_synced_at":"2025-03-17T11:30:40.622Z","repository":{"id":39036424,"uuid":"477320511","full_name":"earthboundkid/be","owner":"earthboundkid","description":"The Go test helper for minimalists","archived":false,"fork":false,"pushed_at":"2023-10-19T21:01:23.000Z","size":43,"stargazers_count":90,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-05-02T05:13:56.251Z","etag":null,"topics":["generic","go","golang","golden-file","testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"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/earthboundkid.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":"carlmjohnson"}},"created_at":"2022-04-03T11:27:49.000Z","updated_at":"2024-04-28T10:23:29.000Z","dependencies_parsed_at":"2023-10-19T23:30:50.293Z","dependency_job_id":null,"html_url":"https://github.com/earthboundkid/be","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"ddd0784afda455396223070b552617b416c64ba5"},"previous_names":["earthboundkid/be","carlmjohnson/be"],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthboundkid%2Fbe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthboundkid%2Fbe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthboundkid%2Fbe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/earthboundkid%2Fbe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/earthboundkid","download_url":"https://codeload.github.com/earthboundkid/be/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243858056,"owners_count":20359271,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["generic","go","golang","golden-file","testing"],"created_at":"2024-07-30T20:01:51.399Z","updated_at":"2025-03-17T11:30:39.891Z","avatar_url":"https://github.com/earthboundkid.png","language":"Go","funding_links":["https://github.com/sponsors/carlmjohnson"],"categories":["Testing"],"sub_categories":["Testing Frameworks"],"readme":"# Be [![Go Reference](https://pkg.go.dev/badge/github.com/carlmjohnson/be.svg)](https://pkg.go.dev/github.com/carlmjohnson/be) [![Go Report Card](https://goreportcard.com/badge/github.com/carlmjohnson/be)](https://goreportcard.com/report/github.com/carlmjohnson/be) [![Coverage Status](https://coveralls.io/repos/github/carlmjohnson/be/badge.svg)](https://coveralls.io/github/carlmjohnson/be) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\nPackage be is the minimalist testing helper for Go.\n\nInspired by [Mat Ryer](https://github.com/matryer/is) and [Alex Edwards](https://www.alexedwards.net/blog/easy-test-assertions-with-go-generics).\n\n## Features\n\n- Simple and readable test assertions using generics\n- Built-in helpers for common cases like `be.NilErr` and `be.In`\n- Fail fast by default but easily switch to relaxed with `be.Relaxed(t)`\n- Helpers for testing against golden files with the testfile subpackage\n- No dependencies: just uses standard library\n\n## Example usage\n\nTest for simple equality using generics:\n\n```go\n// Test two unequal strings\nbe.Equal(t, \"hello\", \"world\")     // bad\n// t.Fatal(\"want: hello; got: world\")\n// Test two equal strings\nbe.Equal(t, \"goodbye\", \"goodbye\") // good\n// Test equal integers, etc.\nbe.Equal(t, 200, resp.StatusCode)\nbe.Equal(t, tc.wantPtr, gotPtr)\n\n// Test for inequality\nbe.Unequal(t, \"hello\", \"world\")     // good\nbe.Unequal(t, \"goodbye\", \"goodbye\") // bad\n// t.Fatal(\"got: goodbye\")\n```\n\nTest for equality of slices:\n\n```go\ns := []int{1, 2, 3}\nbe.AllEqual(t, []int{1, 2, 3}, s) // good\nbe.AllEqual(t, []int{3, 2, 1}, s) // bad\n// t.Fatal(\"want: [3 2 1]; got: [1 2 3]\")\n```\n\nHandle errors:\n\n```go\nvar err error\nbe.NilErr(t, err)   // good\nbe.Nonzero(t, err) // bad\n// t.Fatal(\"got: \u003cnil\u003e\")\nerr = errors.New(\"(O_o)\")\nbe.NilErr(t, err)   // bad\n// t.Fatal(\"got: (O_o)\")\nbe.Nonzero(t, err) // good\n```\n\nCheck substring containment:\n\n```go\nbe.In(t, \"world\", \"hello, world\") // good\nbe.In(t, \"World\", \"hello, world\") // bad\n// t.Fatal(\"World\" not in \"hello, world\")\nbe.NotIn(t, \"\\x01\", []byte(\"\\a\\b\\x00\\r\\t\")) // good\nbe.NotIn(t, \"\\x00\", []byte(\"\\a\\b\\x00\\r\\t\")) // bad\n// t.Fatal(\"\\x00\" in \"\\a\\b\\x00\\r\\t\")\n```\n\nTest anything else:\n\n```go\nbe.True(t, o.IsValid())\nbe.True(t, len(pages) \u003e= 20)\n```\n\nTest using goldenfiles:\n\n```go\n// Start a sub-test for each .txt file\ntestfile.Run(t, \"testdata/*.txt\", func(t *testing.T, path string) {\n\t// Read the file\n\tinput := testfile.Read(t, path)\n\n\t// Do some conversion on it\n\ttype myStruct struct{ Whatever string }\n\tgot := myStruct{strings.ToUpper(input)}\n\n\t// See if the struct is equivalent to a .json file\n\twantFile := strings.TrimSuffix(path, \".txt\") + \".json\"\n\ttestfile.EqualJSON(t, wantFile, got)\n\n\t// If it's not equivalent,\n\t// the got struct will be dumped\n\t// to a file named testdata/-failed-test-name.json\n})\n```\n\n## Philosophy\nTests usually should not fail. When they do fail, the failure should be repeatable. Therefore, it doesn't make sense to spend a lot of time writing good test messages. (This is unlike error messages, which should happen fairly often, and in production, irrepeatably.) Package be is designed to simply fail a test quickly and quietly if a condition is not met with a reference to the line number of the failing test. If the reason for having the test is not immediately clear from context, you can write a comment, just like in normal code. If you do need more extensive reporting to figure out why a test is failing, use `be.DebugLog` or `be.Debug` to capture more information.\n\nMost tests just need simple equality testing, which is handled by `be.Equal` (for comparable types), `be.AllEqual` (for slices of comparable types), and `be.DeepEqual` (which relies on `reflect.DeepEqual`). Another common test is that a string or byte slice should contain or not some substring, which is handled by `be.In` and `be.NotIn`. Rather than package be providing every possible test helper, you are encouraged to write your own advanced helpers for use with `be.True`, while package be takes away the drudgery of writing yet another simple `func nilErr(t *testing.T, err) { ... }`.\n\nThe testfile subpackage has functions that make it easy to write file-based tests that ensure that the output of some transformation matches a [golden file](https://softwareengineering.stackexchange.com/questions/358786/what-are-golden-files). Subtests can automatically be run for all files matching a glob pattern, such as `testfile.Run(t, \"testdata/*/input.txt\", ...)`. If the test fails, the failure output will be written to a file, such as \"testdata/basic-test/-failed-output.txt\", and then the output can be examined via diff testing with standard tools. Set the environmental variable `TESTFILE_UPDATE` to update the golden file.\n\nEvery tool in the be module requires a `testing.TB` as its first argument. There are various [clever ways to get the testing.TB implicitly](https://dave.cheney.net/2019/12/08/dynamically-scoped-variables-in-go), but package be is designed to be simple and explicit, so it's easiest to just always pass in a testing.TB the boring way.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthboundkid%2Fbe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fearthboundkid%2Fbe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fearthboundkid%2Fbe/lists"}