{"id":19900608,"url":"https://github.com/gobuffalo/suite","last_synced_at":"2025-04-05T12:07:14.019Z","repository":{"id":37405730,"uuid":"81987121","full_name":"gobuffalo/suite","owner":"gobuffalo","description":"A test suite for Buffalo applications","archived":false,"fork":false,"pushed_at":"2024-12-17T13:49:55.000Z","size":422,"stargazers_count":26,"open_issues_count":0,"forks_count":23,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-29T11:09:28.921Z","etag":null,"topics":["buffalo","go","gobuffalo","golang","testing"],"latest_commit_sha":null,"homepage":null,"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/gobuffalo.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-02-14T20:42:12.000Z","updated_at":"2024-12-17T13:49:56.000Z","dependencies_parsed_at":"2024-01-23T23:36:44.809Z","dependency_job_id":"09c84428-6e77-495b-913b-2f68689fcfea","html_url":"https://github.com/gobuffalo/suite","commit_stats":{"total_commits":149,"total_committers":19,"mean_commits":7.842105263157895,"dds":0.6375838926174497,"last_synced_commit":"f67dda488d212d5ce7ff262ec61533f8d494671e"},"previous_names":[],"tags_count":31,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gobuffalo%2Fsuite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gobuffalo%2Fsuite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gobuffalo%2Fsuite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gobuffalo%2Fsuite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gobuffalo","download_url":"https://codeload.github.com/gobuffalo/suite/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332609,"owners_count":20921853,"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":["buffalo","go","gobuffalo","golang","testing"],"created_at":"2024-11-12T20:12:45.311Z","updated_at":"2025-04-05T12:07:13.988Z","avatar_url":"https://github.com/gobuffalo.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Suite\n\n[![Standard Test](https://github.com/gobuffalo/suite/actions/workflows/standard-go-test.yml/badge.svg)](https://github.com/gobuffalo/suite/actions/workflows/standard-go-test.yml)\n[![Go Reference](https://pkg.go.dev/badge/github.com/gobuffalo/suite/v4.svg)](https://pkg.go.dev/github.com/gobuffalo/suite/v4)\n\nSuite is a package meant to make testing [gobuffalo.io](http://gobuffalo.io) applications easier.\n\n## Setup\n\nThis is the entry point into your unit testing suite. The `Test_ActionSuite(t *testing.T)` function is\ncompatible with the `go test` command, and it should:\n\n- Create and configure your new test suite instance (`ActionSuite` in this case)\n- Call `suite.Run` with the `*testing.T` passed by the Go testing system, and your new `ActionSuite` instance\n\n```go\npackage actions_test\n\nimport (\n    \"testing\"\n\n    \"github.com/gobuffalo/suite/v4\"\n    \"github.com/gobuffalo/toodo/actions\"\n)\n\ntype ActionSuite struct {\n    *suite.Action\n}\n\nfunc Test_ActionSuite(t *testing.T) {\n    as := \u0026ActionSuite{suite.NewAction(actions.App())}\n    suite.Run(t, as)\n}\n```\n\n## Usage\n\nThis is where you write your actual test logic. The rules for test names are similar, but not the same, as with `go test`:\n\n- Each test is a method on your `*ActionSuite`\n- Test method names should start with `Test` (note the upper case `T`)\n- Test methods should have no arguments\n\nA few additional notes:\n\n- To avoid race conditions on the testing database, always use the `ActionSuite` variable called `DB` to access the database (not your production app's database)\n- You can access the raw `*testing.T` value if needed with `as.T()`\n- `ActionSuite` has support for [`testify`](https://github.com/stretchr/testify)'s [`require` package](https://godoc.org/github.com/stretchr/testify/require) and [`assert` package](https://godoc.org/github.com/stretchr/testify/assert)\n- ... So try to use one of those instead packages of using the raw methods on the `*testing.T`\n- The default database that `suite` will connect to is called `testing` in your [database.yml](https://github.com/markbates/pop#connecting-to-databases)\n\n```go\npackage actions_test\n\nimport (\n    \"fmt\"\n\n    \"github.com/gobuffalo/toodo/models\"\n)\n\nfunc (as *ActionSuite) Test_TodosResource_List() {\n    todos := models.Todos{\n        {Title: \"buy milk\"},\n        {Title: \"read a good book\"},\n    }\n    for _, t := range todos {\n        err := as.DB.Create(\u0026t)\n        as.NoError(err)\n    }\n\n    res := as.HTML(\"/todos\").Get()\n    body := res.Body.String()\n    for _, t := range todos {\n        as.Contains(body, fmt.Sprintf(\"\u003ch2\u003e%s\u003c/h2\u003e\", t.Title))\n    }\n}\n\nfunc (as *ActionSuite) Test_TodosResource_New() {\n    res := as.HTML(\"/todos/new\").Get()\n    as.Contains(res.Body.String(), \"\u003ch1\u003eNew Todo\u003c/h1\u003e\")\n}\n\nfunc (as *ActionSuite) Test_TodosResource_Create() {\n    todo := \u0026models.Todo{Title: \"Learn Go\"}\n    res := as.HTML(\"/todos\").Post(todo)\n    as.Equal(301, res.Code)\n    as.Equal(\"/todos\", res.Location())\n\n    err := as.DB.First(todo)\n    as.NoError(err)\n    as.NotZero(todo.ID)\n    as.NotZero(todo.CreatedAt)\n    as.Equal(\"Learn Go\", todo.Title)\n}\n\nfunc (as *ActionSuite) Test_TodosResource_Create_Errors() {\n    todo := \u0026models.Todo{}\n    res := as.HTML(\"/todos\").Post(todo)\n    as.Equal(422, res.Code)\n    as.Contains(res.Body.String(), \"Title can not be blank.\")\n\n    c, err := as.DB.Count(todo)\n    as.NoError(err)\n    as.Equal(0, c)\n}\n\nfunc (as *ActionSuite) Test_TodosResource_Update() {\n    todo := \u0026models.Todo{Title: \"Lern Go\"}\n    verrs, err := as.DB.ValidateAndCreate(todo)\n    as.NoError(err)\n    as.False(verrs.HasAny())\n\n    res := as.HTML(\"/todos/%s\", todo.ID).Put(\u0026models.Todo{ID: todo.ID, Title: \"Learn Go\"})\n    as.Equal(200, res.Code)\n\n    err = as.DB.Reload(todo)\n    as.NoError(err)\n    as.Equal(\"Learn Go\", todo.Title)\n}\n```\n\n## Fixtures (Test Data)\n\nOften it is useful to load a series of data into the database at the start of the test to make testing easier. For example, you need to have a user in the database to log a person into the application, or you need some data in the database to test destroying that data. Fixtures let us solve these problems easily.\n\n### Using Fixtures\n\nFirst you need to setup your test suite to use fixtures. You can do this by using `suite.NewActionWithFixtures` or `suite.NewModelWithFixtures` methods to create new test suites that take an `fs.FS` pointing to where the files for this suite live.\n\n```go\npackage actions\n\nimport (\n    \"os\"\n    \"testing\"\n\n    \"github.com/gobuffalo/suite/v4\"\n)\n\ntype ActionSuite struct {\n    *suite.Action\n}\n\nfunc Test_ActionSuite(t *testing.T) {\n    action, err := suite.NewActionWithFixtures(App(), os.DirFS(\"../fixtures\"))\n    if err != nil {\n        t.Fatal(err)\n    }\n\n    as := \u0026ActionSuite{\n        Action: action,\n    }\n    suite.Run(t, as)\n}\n```\n\nOnce your suite is set up, you can create `N` numbers of `*.toml` files in the directory you've chosen for your fixtures, in this example, `../fixtures`.\n\n### Example Fixture File\n\n```toml\n[[scenario]]\nname = \"lots of widgets\"\n\n  [[scenario.table]]\n    name = \"widgets\"\n\n    [[scenario.table.row]]\n      id = \"\u003c%= uuidNamed(\"widget\") %\u003e\"\n      name = \"This is widget #1\"\n      body = \"some widget body\"\n      created_at = \"\u003c%= now() %\u003e\"\n      updated_at = \"\u003c%= now() %\u003e\"\n\n    [[scenario.table.row]]\n      id = \"\u003c%= uuid() %\u003e\"\n      name = \"This is widget #2\"\n      body = \"some widget body\"\n      created_at = \"\u003c%= now() %\u003e\"\n      updated_at = \"\u003c%= now() %\u003e\"\n\n  [[scenario.table]]\n    name = \"users\"\n\n    [[scenario.table.row]]\n      id = \"\u003c%= uuid() %\u003e\"\n      name = \"Mark Bates\"\n      admin = true\n      price = 19.99\n      widget_id = \"\u003c%= uuidNamed(\"widget\") %\u003e\"\n      created_at = \"\u003c%= now() %\u003e\"\n      updated_at = \"\u003c%= now() %\u003e\"\n```\n\n#### Helper Methods\n\nThe `*.toml` files all get run through [https://github.com/gobuffalo/plush](https://github.com/gobuffalo/plush) before they're decoded, so you can make use of the helpful helper methods that ship with Plush.\n\nWe've also add a couple of useful helpers for you as well:\n\n- `uuid()` - returns a new `github.com/gobuffalo/uuid.UUID`\n- `now()` - returns `time.Now()`\n- `nowAdd(s)` and `nowSub(s)` - similar to `now()` but `s` amount of seconds is added or substracted, respectively, from the return value\n- `uuidNamed(name)` - will attempt to return a previously declared UUID with that name, useful, for relations/associations. If there was one that wasn't defined with that name, a new one will be created.\n- `hash(string, opts)` - will create the hashed value of the string (useful for creating a password), you can define the cost as an opts (the default is `bcrypt.DefaultCost`)\n\n### Using in Tests\n\nIn your suite tests you need to call the `LoadFixture` method giving it the name of the fixtures you would like to use for this test.\n\n```go\nfunc (as *ActionSuite) Test_WidgetsResource_List() {\n    as.LoadFixture(\"lots of widgets\")\n    res := as.HTML(\"/widgets\").Get()\n\n    body := res.Body.String()\n    as.Contains(body, \"widget #1\")\n    as.Contains(body, \"widget #2\")\n}\n```\n\n### FAQs\n\n- _Can I call `LoadFixture` more than once in a test?_ - Absolutely! Call it as many times as you want!\n- _Can I load multiple rows into a table in one scenario?_ - Absolutely!\n- _Can I load data into multiple tables in one scenario?_ - Absolutely!\n- _Will it load all my fixtures?_ - No, you have to load specific scenarios, so don't be afraid to create lots of scenarios and only call the ones you need per test.\n- _Will this pollute my database, and how do I clear data between tests?_ - No need to worry, the suite will truncate any data in your database between test runs, so you never have to worry about it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgobuffalo%2Fsuite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgobuffalo%2Fsuite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgobuffalo%2Fsuite/lists"}