{"id":13694168,"url":"https://github.com/frankban/quicktest","last_synced_at":"2025-05-14T23:06:29.597Z","repository":{"id":25527522,"uuid":"103532225","full_name":"frankban/quicktest","owner":"frankban","description":"Quick helpers for testing Go applications","archived":false,"fork":false,"pushed_at":"2024-03-01T18:34:33.000Z","size":329,"stargazers_count":530,"open_issues_count":16,"forks_count":26,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-05-14T23:06:15.823Z","etag":null,"topics":["assertions","go","golang","library","testing"],"latest_commit_sha":null,"homepage":"","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/frankban.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,"publiccode":null,"codemeta":null}},"created_at":"2017-09-14T12:56:14.000Z","updated_at":"2025-05-06T04:14:49.000Z","dependencies_parsed_at":"2023-01-14T02:53:47.080Z","dependency_job_id":"629adefc-75c0-4a0b-bbde-bb88047ab261","html_url":"https://github.com/frankban/quicktest","commit_stats":{"total_commits":197,"total_committers":18,"mean_commits":"10.944444444444445","dds":"0.47715736040609136","last_synced_commit":"e80fb9027c34d19f58a5f687f1dd18a2c9b7df0e"},"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankban%2Fquicktest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankban%2Fquicktest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankban%2Fquicktest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frankban%2Fquicktest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frankban","download_url":"https://codeload.github.com/frankban/quicktest/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254243360,"owners_count":22038046,"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":["assertions","go","golang","library","testing"],"created_at":"2024-08-02T17:01:25.858Z","updated_at":"2025-05-14T23:06:24.576Z","avatar_url":"https://github.com/frankban.png","language":"Go","readme":"[![Go Reference](https://pkg.go.dev/badge/github.com/frankban/quicktest.svg)](https://pkg.go.dev/github.com/frankban/quicktest#section-documentation)\n[![Build Status](https://github.com/frankban/quicktest/actions/workflows/ci.yaml/badge.svg)](https://github.com/frankban/quicktest/actions/workflows/ci.yaml)\n\n[//]: # (Generated with: godocdown -template=.godocdown.template -o README.md)\n\n### quicktest\n\n`go get github.com/frankban/quicktest@latest`\n\nPackage quicktest provides a collection of Go helpers for writing tests.\n\nQuicktest helpers can be easily integrated inside regular Go tests, for\ninstance:\n\n    import qt \"github.com/frankban/quicktest\"\n\n    func TestFoo(t *testing.T) {\n        t.Run(\"numbers\", func(t *testing.T) {\n            c := qt.New(t)\n            numbers, err := somepackage.Numbers()\n            c.Assert(err, qt.IsNil)\n            c.Assert(numbers, qt.DeepEquals, []int{42, 47})\n        })\n        t.Run(\"bad wolf error\", func(t *testing.T) {\n            c := qt.New(t)\n            numbers, err := somepackage.Numbers()\n            c.Assert(err, qt.ErrorMatches, \"bad wolf\")\n        })\n        t.Run(\"nil\", func(t *testing.T) {\n            c := qt.New(t)\n            got := somepackage.MaybeNil()\n            c.Assert(got, qt.IsNil, qt.Commentf(\"value: %v\", somepackage.Value))\n        })\n    }\n\n### Assertions\n\nAn assertion looks like this, where qt.Equals could be replaced by any available\nchecker. If the assertion fails, the underlying Fatal method is called to\ndescribe the error and abort the test.\n\n    c := qt.New(t)\n    c.Assert(someValue, qt.Equals, wantValue)\n\nIf you don’t want to abort on failure, use Check instead, which calls Error\ninstead of Fatal:\n\n    c.Check(someValue, qt.Equals, wantValue)\n\nFor really short tests, the extra line for instantiating *qt.C can be avoided:\n\n    qt.Assert(t, someValue, qt.Equals, wantValue)\n    qt.Check(t, someValue, qt.Equals, wantValue)\n\nThe library provides some base checkers like Equals, DeepEquals, Matches,\nErrorMatches, IsNil and others. More can be added by implementing the Checker\ninterface. Below, we list the checkers implemented by the package in\nalphabetical order.\n\n### All\n\nAll returns a Checker that uses the given checker to check elements of slice or\narray or the values of a map. It succeeds if all elements pass the check. On\nfailure it prints the error from the first index that failed.\n\nFor example:\n\n    c.Assert([]int{3, 5, 8}, qt.All(qt.Not(qt.Equals)), 0)\n    c.Assert([][]string{{\"a\", \"b\"}, {\"a\", \"b\"}}, qt.All(qt.DeepEquals), []string{\"c\", \"d\"})\n\nSee also Any and Contains.\n\n### Any\n\nAny returns a Checker that uses the given checker to check elements of a slice\nor array or the values from a map. It succeeds if any element passes the check.\n\nFor example:\n\n    c.Assert([]int{3,5,7,99}, qt.Any(qt.Equals), 7)\n    c.Assert([][]string{{\"a\", \"b\"}, {\"c\", \"d\"}}, qt.Any(qt.DeepEquals), []string{\"c\", \"d\"})\n\nSee also All and Contains.\n\n### CmpEquals\n\nCmpEquals checks equality of two arbitrary values according to the provided\ncompare options. DeepEquals is more commonly used when no compare options are\nrequired.\n\nExample calls:\n\n    c.Assert(list, qt.CmpEquals(cmpopts.SortSlices), []int{42, 47})\n    c.Assert(got, qt.CmpEquals(), []int{42, 47}) // Same as qt.DeepEquals.\n\n### CodecEquals\n\nCodecEquals returns a checker that checks for codec value equivalence.\n\n    func CodecEquals(\n        marshal func(interface{}) ([]byte, error),\n        unmarshal func([]byte, interface{}) error,\n        opts ...cmp.Option,\n    ) Checker\n\nIt expects two arguments: a byte slice or a string containing some\ncodec-marshaled data, and a Go value.\n\nIt uses unmarshal to unmarshal the data into an interface{} value. It marshals\nthe Go value using marshal, then unmarshals the result into an interface{}\nvalue.\n\nIt then checks that the two interface{} values are deep-equal to one another,\nusing CmpEquals(opts) to perform the check.\n\nSee JSONEquals for an example of this in use.\n\n### Contains\n\nContains checks that a map, slice, array or string contains a value. It's the\nsame as using Any(Equals), except that it has a special case for strings - if\nthe first argument is a string, the second argument must also be a string and\nstrings.Contains will be used.\n\nFor example:\n\n    c.Assert(\"hello world\", qt.Contains, \"world\")\n    c.Assert([]int{3,5,7,99}, qt.Contains, 7)\n\n### ContentEquals\n\nContentEquals is is like DeepEquals but any slices in the compared values will\nbe sorted before being compared.\n\nFor example:\n\n    c.Assert([]string{\"c\", \"a\", \"b\"}, qt.ContentEquals, []string{\"a\", \"b\", \"c\"})\n\n### DeepEquals\n\nDeepEquals checks that two arbitrary values are deeply equal. The comparison is\ndone using the github.com/google/go-cmp/cmp package. When comparing structs, by\ndefault no exported fields are allowed. If a more sophisticated comparison is\nrequired, use CmpEquals (see below).\n\nExample call:\n\n    c.Assert(got, qt.DeepEquals, []int{42, 47})\n\n### Equals\n\nEquals checks that two values are equal, as compared with Go's == operator.\n\nFor instance:\n\n    c.Assert(answer, qt.Equals, 42)\n\nNote that the following will fail:\n\n    c.Assert((*sometype)(nil), qt.Equals, nil)\n\nUse the IsNil checker below for this kind of nil check.\n\n### ErrorAs\n\nErrorAs checks that the error is or wraps a specific error type. If so, it\nassigns it to the provided pointer. This is analogous to calling errors.As.\n\nFor instance:\n\n    // Checking for a specific error type\n    c.Assert(err, qt.ErrorAs, new(*os.PathError))\n\n    // Checking fields on a specific error type\n    var pathError *os.PathError\n    if c.Check(err, qt.ErrorAs, \u0026pathError) {\n        c.Assert(pathError.Path, Equals, \"some_path\")\n    }\n\n### ErrorIs\n\nErrorIs checks that the error is or wraps a specific error value. This is\nanalogous to calling errors.Is.\n\nFor instance:\n\n    c.Assert(err, qt.ErrorIs, os.ErrNotExist)\n\n### ErrorMatches\n\nErrorMatches checks that the provided value is an error whose message matches\nthe provided regular expression.\n\nFor instance:\n\n    c.Assert(err, qt.ErrorMatches, `bad wolf .*`)\n\n### HasLen\n\nHasLen checks that the provided value has the given length.\n\nFor instance:\n\n    c.Assert([]int{42, 47}, qt.HasLen, 2)\n    c.Assert(myMap, qt.HasLen, 42)\n\n### Implements\n\nImplements checks that the provided value implements an interface. The interface\nis specified with a pointer to an interface variable.\n\nFor instance:\n\n    var rc io.ReadCloser\n    c.Assert(myReader, qt.Implements, \u0026rc)\n\n### IsFalse\n\nIsFalse checks that the provided value is false. The value must have a boolean\nunderlying type.\n\nFor instance:\n\n    c.Assert(false, qt.IsFalse)\n    c.Assert(IsValid(), qt.IsFalse)\n\n### IsNil\n\nIsNil checks that the provided value is nil.\n\nFor instance:\n\n    c.Assert(got, qt.IsNil)\n\nAs a special case, if the value is nil but implements the error interface, it is\nstill considered to be non-nil. This means that IsNil will fail on an error\nvalue that happens to have an underlying nil value, because that's invariably a\nmistake. See https://golang.org/doc/faq#nil_error.\n\nSo it's just fine to check an error like this:\n\n    c.Assert(err, qt.IsNil)\n\n### IsNotNil\n\nIsNotNil is a Checker checking that the provided value is not nil. IsNotNil is\nthe equivalent of qt.Not(qt.IsNil)\n\nFor instance:\n\n    c.Assert(got, qt.IsNotNil)\n\n### IsTrue\n\nIsTrue checks that the provided value is true. The value must have a boolean\nunderlying type.\n\nFor instance:\n\n    c.Assert(true, qt.IsTrue)\n    c.Assert(myBoolean(false), qt.IsTrue)\n\n### JSONEquals\n\nJSONEquals checks whether a byte slice or string is JSON-equivalent to a Go\nvalue. See CodecEquals for more information.\n\nIt uses DeepEquals to do the comparison. If a more sophisticated comparison is\nrequired, use CodecEquals directly.\n\nFor instance:\n\n    c.Assert(`{\"First\": 47.11}`, qt.JSONEquals, \u0026MyStruct{First: 47.11})\n\n### Matches\n\nMatches checks that a string or result of calling the String method (if the\nvalue implements fmt.Stringer) matches the provided regular expression.\n\nFor instance:\n\n    c.Assert(\"these are the voyages\", qt.Matches, `these are .*`)\n    c.Assert(net.ParseIP(\"1.2.3.4\"), qt.Matches, `1.*`)\n\n### Not\n\nNot returns a Checker negating the given Checker.\n\nFor instance:\n\n    c.Assert(got, qt.Not(qt.IsNil))\n    c.Assert(answer, qt.Not(qt.Equals), 42)\n\n### PanicMatches\n\nPanicMatches checks that the provided function panics with a message matching\nthe provided regular expression.\n\nFor instance:\n\n    c.Assert(func() {panic(\"bad wolf ...\")}, qt.PanicMatches, `bad wolf .*`)\n\n### Satisfies\n\nSatisfies checks that the provided value, when used as argument of the provided\npredicate function, causes the function to return true. The function must be of\ntype func(T) bool, having got assignable to T.\n\nFor instance:\n\n    // Check that an error from os.Open satisfies os.IsNotExist.\n    c.Assert(err, qt.Satisfies, os.IsNotExist)\n\n    // Check that a floating point number is a not-a-number.\n    c.Assert(f, qt.Satisfies, math.IsNaN)\n\n### Deferred Execution\n\nThe testing.TB.Cleanup helper provides the ability to defer the execution of\nfunctions that will be run when the test completes. This is often useful for\ncreating OS-level resources such as temporary directories (see c.Mkdir).\n\nWhen targeting Go versions that don't have Cleanup (\u003c 1.14), the same can be\nachieved using c.Defer. In this case, to trigger the deferred behavior, calling\nc.Done is required. For instance, if you create a *C instance at the top level,\nyou’ll have to add a defer to trigger the cleanups at the end of the test:\n\n    defer c.Done()\n\nHowever, if you use quicktest to create a subtest, Done will be called\nautomatically at the end of that subtest. For example:\n\n    func TestFoo(t *testing.T) {\n        c := qt.New(t)\n        c.Run(\"subtest\", func(c *qt.C) {\n            c.Setenv(\"HOME\", c.Mkdir())\n            // Here $HOME is set the path to a newly created directory.\n            // At the end of the test the directory will be removed\n            // and HOME set back to its original value.\n        })\n    }\n\nThe c.Patch, c.Setenv, c.Unsetenv and c.Mkdir helpers use t.Cleanup for cleaning\nup resources when available, and fall back to Defer otherwise.\n\nFor a complete API reference, see the\n[package documentation](https://pkg.go.dev/github.com/frankban/quicktest#section-documentation).\n","funding_links":[],"categories":["开源类库","Open source library","Go","testing"],"sub_categories":["测试","Test"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrankban%2Fquicktest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrankban%2Fquicktest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrankban%2Fquicktest/lists"}