{"id":13413906,"url":"https://github.com/go-testfixtures/testfixtures","last_synced_at":"2025-05-12T13:24:48.970Z","repository":{"id":37728715,"uuid":"55502590","full_name":"go-testfixtures/testfixtures","owner":"go-testfixtures","description":"Ruby on Rails like test fixtures for Go. Write tests against a real database","archived":false,"fork":false,"pushed_at":"2025-05-11T14:21:54.000Z","size":735,"stargazers_count":1152,"open_issues_count":18,"forks_count":82,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-05-11T15:28:29.850Z","etag":null,"topics":["database","fixtures","go","testing"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/github.com/go-testfixtures/testfixtures/v3?tab=doc","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/go-testfixtures.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"andreynering","ko_fi":"andreynering","custom":"https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=GSVDU63RKG45A\u0026currency_code=USD\u0026source=url"}},"created_at":"2016-04-05T11:33:28.000Z","updated_at":"2025-05-11T14:21:58.000Z","dependencies_parsed_at":"2024-06-18T12:09:01.864Z","dependency_job_id":"0c5418f5-d288-4457-bcfc-08c17130ab9f","html_url":"https://github.com/go-testfixtures/testfixtures","commit_stats":{"total_commits":340,"total_committers":46,"mean_commits":7.391304347826087,"dds":"0.40588235294117647","last_synced_commit":"b1fe75b2f31f9af027da52787e7c2892f9703c47"},"previous_names":[],"tags_count":51,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-testfixtures%2Ftestfixtures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-testfixtures%2Ftestfixtures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-testfixtures%2Ftestfixtures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/go-testfixtures%2Ftestfixtures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/go-testfixtures","download_url":"https://codeload.github.com/go-testfixtures/testfixtures/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253745947,"owners_count":21957474,"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":["database","fixtures","go","testing"],"created_at":"2024-07-30T20:01:52.469Z","updated_at":"2025-05-12T13:24:48.904Z","avatar_url":"https://github.com/go-testfixtures.png","language":"Go","funding_links":["https://github.com/sponsors/andreynering","https://ko-fi.com/andreynering","https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=GSVDU63RKG45A\u0026currency_code=USD\u0026source=url"],"categories":["Template Engines","Go","Testing","测试","测试相关`测试库和测试数据集生成库`","Testing Frameworks","测试相关","Repositories","\u003cspan id=\"测试-testing\"\u003e测试 Testing\u003c/span\u003e"],"sub_categories":["Testing Frameworks","HTTP Clients","HTTP客户端","Advanced Console UIs","查询语","交流","\u003cspan id=\"高级控制台用户界面-advanced-console-uis\"\u003e高级控制台用户界面 Advanced Console UIs\u003c/span\u003e"],"readme":"# testfixtures\n\n[![PkgGoDev](https://pkg.go.dev/badge/github.com/go-testfixtures/testfixtures/v3?tab=doc)](https://pkg.go.dev/github.com/go-testfixtures/testfixtures/v3?tab=doc)\n\n\u003e ***Warning***: this package will wipe the database data before loading the\nfixtures! It is supposed to be used on a test database. Please, double check\nif you are running it against the correct database.\n\n\u003e **TIP**: There are options not described in this README page. It's\n\u003e recommended that you also check [the documentation][doc].\n\nWriting tests is hard, even more when you have to deal with an SQL database.\nThis package aims to make writing functional tests for web apps written in\nGo easier.\n\nBasically this package mimics the [\"Ruby on Rails' way\"][railstests] of writing tests\nfor database applications, where sample data is kept in fixtures files. Before\nthe execution of every test, the test database is cleaned and the fixture data\nis loaded into the database.\n\nThe idea is running tests against a real database, instead of relying in mocks,\nwhich is boring to setup and may lead to production bugs not being caught in\nthe tests.\n\n## Installation\n\nFirst, import it like this:\n\n```go\nimport (\n        \"github.com/go-testfixtures/testfixtures/v3\"\n)\n```\n\n## Usage\n\nCreate a folder for the fixture files. Each file should contain data for a\nsingle table and have the name `\u003ctable_name\u003e.yml`:\n\n```\nmyapp/\n  myapp.go\n  myapp_test.go\n  ...\n  fixtures/\n    posts.yml\n    comments.yml\n    tags.yml\n    posts_tags.yml\n    ...\n```\n\nThe file would look like this (it can have as many record you want):\n\n```yml\n# comments.yml\n- id: 1\n  post_id: 1\n  content: A comment...\n  author_name: John Doe\n  author_email: john@doe.com\n  created_at: 2020-12-31 23:59:59\n  updated_at: 2020-12-31 23:59:59\n\n- id: 2\n  post_id: 2\n  content: Another comment...\n  author_name: John Doe\n  author_email: john@doe.com\n  created_at: 2020-12-31 23:59:59\n  updated_at: 2020-12-31 23:59:59\n\n# ...\n```\n\nAn YAML object or array will be converted to JSON. It will be stored on a native\nJSON type like JSONB on PostgreSQL \u0026 CockroachDB or as a TEXT or VARCHAR column on other\ndatabases.\n\n```yml\n- id: 1\n  post_attributes:\n    author: John Due\n    author_email: john@due.com\n    title: \"...\"\n    tags:\n      - programming\n      - go\n      - testing\n    post: \"...\"\n```\n\nBinary columns can be represented as hexadecimal strings (should start with `0x`):\n\n```yaml\n- id: 1\n  binary_column: 0x1234567890abcdef\n```\n\nIf you need to write raw SQL, probably to call a function, prefix the value\nof the column with `RAW=`:\n\n```yml\n- id: 1\n  uuid_column: RAW=uuid_generate_v4()\n  postgis_type_column: RAW=ST_GeomFromText('params...')\n  created_at: RAW=NOW()\n  updated_at: RAW=NOW()\n```\n\nYour tests would look like this:\n\n```go\npackage myapp\n\nimport (\n        \"database/sql\"\n\n        _ \"github.com/lib/pq\"\n        \"github.com/go-testfixtures/testfixtures/v3\"\n)\n\nvar (\n        db *sql.DB\n        fixtures *testfixtures.Loader\n)\n\nfunc TestMain(m *testing.M) {\n        var err error\n\n        // Open connection to the test database.\n        // Do NOT import fixtures in a production database!\n        // Existing data would be deleted.\n        db, err = sql.Open(\"postgres\", \"dbname=myapp_test\")\n        if err != nil {\n                ...\n        }\n\n        fixtures, err = testfixtures.New(\n                testfixtures.Database(db), // You database connection\n                testfixtures.Dialect(\"postgres\"), // Available: \"postgresql\", \"timescaledb\", \"mysql\", \"mariadb\", \"sqlite\" and \"sqlserver\"\n                testfixtures.Directory(\"testdata/fixtures\"), // The directory containing the YAML files\n        )\n        if err != nil {\n                ...\n        }\n\n        os.Exit(m.Run())\n}\n\nfunc prepareTestDatabase() {\n        if err := fixtures.Load(); err != nil {\n                ...\n        }\n}\n\nfunc TestX(t *testing.T) {\n        prepareTestDatabase()\n\n        // Your test here ...\n}\n\nfunc TestY(t *testing.T) {\n        prepareTestDatabase()\n\n        // Your test here ...\n}\n\nfunc TestZ(t *testing.T) {\n        prepareTestDatabase()\n\n        // Your test here ...\n}\n```\n\nAlternatively, you can use the `Files` option, to specify which\nfiles you want to load into the database:\n\n```go\nfixtures, err := testfixtures.New(\n        testfixtures.Database(db),\n        testfixtures.Dialect(\"postgres\"),\n        testfixtures.Files(\n                \"fixtures/orders.yml\",\n                \"fixtures/customers.yml\",\n        ),\n)\nif err != nil {\n        ...\n}\n```\n\nWith `Paths` option, you can specify the paths that fixtures will load\nfrom. Path can be directory or file. If directory, we will search YAML files\nin it.\n\n```go\nfixtures, err := testfixtures.New(\n        testfixtures.Database(db),\n        testfixtures.Dialect(\"postgres\"),\n        testfixtures.Paths(\n                \"fixtures/orders.yml\",\n                \"fixtures/customers.yml\",\n                \"common_fixtures/users\"\n        ),\n)\nif err != nil {\n        ...\n}\n```\n\n## \u003ca name=\"singleFileOnMultipleTables\"\u003e\u003c/a\u003e Single file on multiple tables\n\nYou can use the `FilesMultiTables` option, to specify which\nfiles you want to load into the database with support multiple tables\n(file name does not affect table names):\n\n```go\nfixtures, err := testfixtures.New(\n        testfixtures.Database(db),\n        testfixtures.Dialect(\"postgres\"),\n        testfixtures.FilesMultiTables(\n                \"fixtures/test_case1.yml\",\n                \"fixtures/test_case2.yml\",\n                \"fixtures/posts_comments.yml\",\n        ),\n)\nif err != nil {\n        ...\n}\n```\n\nThe file would look like this (it can have as many tables and records you want):\n\n```yml\n# test_case1.yml\nposts:\n  - id: 1\n    post_id: 1\n    content: A comment...\n    author_name: John Doe\n    author_email: john@doe.com\n    created_at: 2020-12-31 23:59:59\n    updated_at: 2020-12-31 23:59:59\n\n  - id: 2\n    post_id: 2\n    content: Another comment...\n    author_name: John Doe\n    author_email: john@doe.com\n    created_at: 2020-12-31 23:59:59\n    updated_at: 2020-12-31 23:59:59\n\ncomments:\n  - id: 1\n    post_id: 1\n    content: Post 1 comment 1\n    author_name: John Doe\n    author_email: john@doe.com\n    created_at: 2016-01-01 12:30:12\n    updated_at: 2016-01-01 12:30:12\n# ...\n```\n\n## Security check\n\nIn order to prevent you from accidentally wiping the wrong database, this\npackage will refuse to load fixtures if the database name (or database\nfilename for SQLite) doesn't contains \"test\". If you want to disable this\ncheck, use:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.DangerousSkipTestDatabaseCheck(),\n)\n```\n\n## Disable cleanup\n\nIf you want to disable cleanup, you can also do like below.\nThis is usually not recommended, and should be used mostly for debugging.\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.DangerousSkipCleanupFixtureTables(),\n)\n```\n\n## Disable checksum computation\n\nChecksums of each table in a database are computed at the end of each `Load()`,\nso subsequent calls to `Load()` do not reload the same data again, if nothing\nhas changed in between.\n\nThe drawback is that it can be slow for database with many tables. Also, it does not\nmake sense to compute checksum, if you run `Load()` only once.\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.SkipTableChecksumComputation(),\n)\n```\n\n## Sequences\n\nFor PostgreSQL and MySQL/MariaDB, this package also resets all\nsequences to a high number to prevent duplicated primary keys while\nrunning the tests.\nThe default is 10000, but you can change that with:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.ResetSequencesTo(10000),\n)\n```\n\nOr, if you want to skip the reset of sequences entirely:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.SkipResetSequences(),\n)\n```\n\n## Force `DELETE FROM ...` on ClickHouse\n\nBy default, when using ClickHouse, this library will use `TRUNCATE ...` to\nclean the database. If you want to force the use of `DELETE FROM ...` you can\ndo it by doing:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.ClickhouseUseDeleteFrom(),\n)\n```\n\n## Compatible databases\n\n### PostgreSQL / TimescaleDB / CockroachDB\n\nThis package has three approaches to disable foreign keys while importing fixtures\nfor PostgreSQL databases:\n\n#### With `DISABLE TRIGGER`\n\nThis is the default approach. For that use:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"postgres\"), // or \"timescaledb\"\n)\n```\n\nWith the above snippet this package will use `DISABLE TRIGGER` to temporarily\ndisabling foreign key constraints while loading fixtures. This work with any\nversion of PostgreSQL, but it is **required** to be connected in the database\nas a SUPERUSER. You can make a PostgreSQL user a SUPERUSER with:\n\n```sql\nALTER USER your_user SUPERUSER;\n```\n\n#### With `ALTER CONSTRAINT`\n\nThis approach don't require to be connected as a SUPERUSER, but only work with\nPostgreSQL versions \u003e= 9.4. Try this if you are getting foreign key violation\nerrors with the previous approach. It is as simple as using:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"postgres\"),\n        testfixtures.UseAlterConstraint(),\n)\n```\n\n#### With `DROP CONSTRAINT`\n\nThis approach is implemented to support databases that do not support above\nmethods (namely CockroachDB).\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"postgres\"),\n        testfixtures.UseDropConstraint(),\n)\n```\n\nTested using the [github.com/lib/pq](https://github.com/lib/pq) and\n[github.com/jackc/pgx](https://github.com/jackc/pgx) drivers.\n\n### MySQL / MariaDB\n\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"mysql\"), // or \"mariadb\"\n)\n```\n\nTested using the [github.com/go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) driver.\n\n#### Multistatements parameter\n\nYou can use [the multistatement parameter](https://github.com/go-sql-driver/mysql#multistatements) in the connection\nstring to execute some of the setup statements in one query (instead of one query per statement) for a faster execution.\n\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"mysql\"), // or \"mariadb\"\n        testfixtures.AllowMultipleStatementsInOneQuery(),\n)\n```\n\n### SQLite\n\nSQLite is also supported. It is recommended to create foreign keys as\n`DEFERRABLE` (the default) to prevent problems. See more\n[on the SQLite documentation](https://www.sqlite.org/foreignkeys.html#fk_deferred).\n(Foreign key constraints are no-op by default on SQLite, but enabling it is\nrecommended).\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"sqlite\"),\n)\n```\n\nTested using the [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) driver.\n\n### Microsoft SQL Server\n\nSQL Server support requires SQL Server \u003e= 2008. Inserting on `IDENTITY` columns\nare handled as well. Just make sure you are logged in with a user with\n`ALTER TABLE` permission.\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"sqlserver\"),\n)\n```\n\nTested using the `mssql` and `sqlserver` drivers from the\n[github.com/denisenkom/go-mssqldb](https://github.com/denisenkom/go-mssqldb) lib.\n\n### ClickHouse\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"clickhouse\"),\n)\n```\n\n### Spanner with GoogleSQL Dialect\n\nIt's impossible to get Spanner database name to determine whether it's a test database or not. You need to make sure that you're actually using test database and use `testfixtures.DangerousSkipTestDatabaseCheck()` to skip the check.\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Dialect(\"spanner\"),\n        testfixtures.DangerousSkipTestDatabaseCheck(),\n)\n```\n\n## Templating\n\nTestfixtures supports templating, but it's disabled by default. Most people\nwon't need it, but it may be useful to dynamically generate data.\n\nEnable it by doing:\n\n```go\ntestfixtures.New(\n        ...\n        testfixtures.Template(),\n\n        // the above options are optional\n        TemplateFuncs(...),\n        TemplateDelims(\"{{\", \"}}\"),\n        TemplateOptions(\"missingkey=zero\"),\n        TemplateData(...),\n)\n```\n\nThe YAML file could look like this:\n\n```yaml\n# It's possible generate values...\n- id: {{sha256 \"my-awesome-post}}\n  title: My Awesome Post\n  text: {{randomText}}\n\n# ... or records\n{{range $post := $.Posts}}\n- id: {{$post.Id}}\n  title: {{$post.Title}}\n  text: {{$post.Text}}\n{{end}}\n```\n\n## Generating fixtures for a existing database\n\nThe following code will generate a YAML file for each table of the database\ninto a given folder. It may be useful to boostrap a test scenario from a sample\ndatabase of your app.\n\n```go\ndumper, err := testfixtures.NewDumper(\n        testfixtures.DumpDatabase(db),\n        testfixtures.DumpDialect(\"postgres\"), // or your database of choice\n        testfixtures.DumpDirectory(\"tmp/fixtures\"),\n        testfixtures.DumpTables( // optional, will dump all table if not given\n          \"posts\",\n          \"comments\",\n          \"tags\",\n        ),\n)\nif err != nil {\n        ...\n}\nif err := dumper.Dump(); err != nil {\n        ...\n}\n```\n\n\u003e This was intended to run in small sample databases. It will likely break\nif run in a production/big database.\n\n## Gotchas\n\n### Parallel testing\n\nThis library doesn't yet support running tests in parallel! Running tests\nin parallel can result in random data being present in the database, which\nwill likely cause tests to randomly/intermittently fail.\n\nThis is specially tricky since it's not immediately clear that `go test ./...`\nrun tests for each package in parallel. If more than one package use this\nlibrary, you can face this issue. Please, use `go test -p 1 ./...` or run tests\nfor each package in separated commands to fix this issue.\n\nIf you're looking into being able to run tests in parallel you can try using\ntestfixtures together with the [txdb][gotxdb] package, which allows wrapping\neach test run in a transaction.\n\n## CLI\n\nWe also have a CLI to load fixtures in a given database.\n\nGrab it from the [releases page](https://github.com/go-testfixtures/testfixtures/releases)\nor install with Homebrew:\n\n```bash\nbrew install go-testfixtures/tap/testfixtures\n```\n\nUsage is like this:\n\n```bash\n# load\ntestfixtures -d postgres -c \"postgres://user:password@localhost/database\" -D testdata/fixtures\n```\n\n```bash\n# dump\ntestfixtures --dump -d postgres -c \"postgres://user:password@localhost/database\" -D testdata/fixtures\n```\n\nThe connection string changes for each database driver.\n\nUse `testfixtures --help` for all flags.\n\n## Contributing\n\nWe recommend you to [install Task](https://taskfile.dev/installation/) and\nDocker before contributing to this package, since some stuff is automated\nusing these tools.\n\nIt's recommended to use Docker Compose to run tests, since it runs tests for\nall supported databases once. To do that you just need to run:\n\n```bash\ntask docker\n```\n\nBut if you want to run tests locally, copy the `.sample.env` file as `.env`\nand edit it according to your database setup. You'll need to create a database\n(likely names `testfixtures_test`) before continuing. Then run the command\nfor the database you want to run tests against:\n\n```bash\ntask test:pg # PostgreSQL\ntask test:crdb # CockroachDB\ntask test:mysql # MySQL\ntask test:sqlite # SQLite\ntask test:sqlserver # Microsoft SQL Server\n```\n\nGitHub Actions (CI) runs the same Docker setup available locally.\n\n## Alternatives\n\nIf you don't think using fixtures is a good idea, you can try one of these\npackages instead:\n\n- [factory-go][factorygo]: Factory for Go. Inspired by Python's Factory Boy\nand Ruby's Factory Girl\n- [fixtory][fixtory]: go generate based type-safe, DRY, flexible test fixture factory\n- [go-txdb (Single transaction SQL driver for Go)][gotxdb]: Use a single\ndatabase transaction for each functional test, so you can rollback to\nprevious state between tests to have the same database state in all tests\n- [go-sqlmock][gosqlmock]: A mock for the sql.DB interface. This allow you to\nunit test database code without having to connect to a real database\n- [dbcleaner][dbcleaner] - Clean database for testing, inspired by\ndatabase_cleaner for Ruby\n\n[doc]: https://pkg.go.dev/github.com/go-testfixtures/testfixtures/v3?tab=doc\n[railstests]: http://guides.rubyonrails.org/testing.html#the-test-database\n[gotxdb]: https://github.com/DATA-DOG/go-txdb\n[gosqlmock]: https://github.com/DATA-DOG/go-sqlmock\n[factorygo]: https://github.com/bluele/factory-go\n[fixtory]: https://github.com/k-yomo/fixtory\n[dbcleaner]: https://github.com/khaiql/dbcleaner\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-testfixtures%2Ftestfixtures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgo-testfixtures%2Ftestfixtures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgo-testfixtures%2Ftestfixtures/lists"}