go-gitea/vendor/gopkg.in/testfixtures.v2
2016-12-31 10:17:45 +01:00
..
deprecated.go
helper.go
LICENSE
mysql.go
options.go
oracle.go
postgresql.go
README.md
sqlite.go
sqlserver.go
testfixtures.go
time.go

Go Test Fixtures

license Join the chat at https://gitter.im/go-testfixtures/testfixtures GoDoc Build Status Go Report Card

Warning: this package will wipe the database data before loading the fixtures! It is supposed to be used on a test database. Please, double check if you are running it against the correct database.

Writing tests is hard, even more when you have to deal with an SQL database. This package aims to make writing functional tests for web apps written in Go easier.

Basically this package mimics the "Rails' way" of writing tests for database applications, where sample data is kept in fixtures files. Before the execution of every test, the test database is cleaned and the fixture data is loaded into the database.

The idea is running tests against a real database, instead of relying in mocks, which is boring to setup and may lead to production bugs not to being catch in the tests.

Installation

First, get it:

go get -u gopkg.in/testfixtures.v2

Usage

Create a folder for the fixture files. Each file should contain data for a single table and have the name <table-name>.yml:

myapp
  - myapp.go
  - myapp_test.go
  - ...
  - fixtures:
    - posts.yml
    - comments.yml
    - tags.yml
    - posts_tags.yml
    - ...

The file would look like this (it can have as many record you want):

# comments.yml
-
    id: 1
    post_id: 1
    content: This post is awesome!
    author_name: John Doe
    author_email: john@doe.com
    created_at: 2016-01-01 12:30:12
    updated_at: 2016-01-01 12:30:12

-
    id: 2
    post_id: 2
    content: Are you kidding me?
    author_name: John Doe
    author_email: john@doe.com
    created_at: 2016-01-01 12:30:12
    updated_at: 2016-01-01 12:30:12

# ...

Your tests would look like this:

package myapp

import (
    "database/sql"
    "log"

    _ "github.com/lib/pq"
    "gopkg.in/testfixtures.v2"
)

var (
    db *sql.DB
	fixtures *testfixtures.Context
)

func TestMain(m *testing.M) {
    var err error

    // Open connection with the test database.
    // Do NOT import fixtures in a production database!
    // Existing data would be deleted
    db, err = sql.Open("postgres", "dbname=myapp_test")
    if err != nil {
        log.Fatal(err)
    }

    // creating the context that hold the fixtures
    // see about all compatible databases in this page below
    c, err = testfixtures.NewFolder(db, &testfixtures.PostgreSQL{}, "testdata/fixtures")
    if err != nil {
        log.Fatal(err)
	}

    os.Exit(m.Run())
}

func prepareTestDatabase() {
    if err := fixtures.Load(); err != nil {
        log.Fatal(err)
    }
}

func TestX(t *testing.T) {
    prepareTestDatabase()
    // your test here ...
}

func TestY(t *testing.T) {
    prepareTestDatabase()
    // your test here ...
}

func TestZ(t *testing.T) {
    prepareTestDatabase()
    // your test here ...
}

Alternatively, you can use the NewFiles function, to specify which files you want to load into the database:

fixtures, err := testfixtures.NewFiles(db, &testfixtures.PostgreSQL{},
    "fixtures/orders.yml",
    "fixtures/customers.yml",
    // add as many files you want
)
if err != nil {
	log.Fatal(err)
}

Security check

In order to prevent you from accidentally wiping the wrong database, this package will refuse to load fixtures if the database name (or database filename for SQLite) doesn't contains "test". If you want to disable this check, use:

testfixtures.SkipDatabaseNameCheck(true)

Sequences

For PostgreSQL or Oracle, this package also resets all sequences to a high number to prevent duplicated primary keys while running the tests. The default is 10000, but you can change that with:

testfixtures.ResetSequencesTo(10000)

Compatible databases

PostgreSQL

This package has two approaches to disable foreign keys while importing fixtures in PostgreSQL databases:

With DISABLE TRIGGER

This is the default approach. For that use:

&testfixtures.PostgreSQL{}

With the above snippet this package will use DISABLE TRIGGER to temporarily disabling foreign key constraints while loading fixtures. This work with any version of PostgreSQL, but it is required to be connected in the database as a SUPERUSER. You can make a PostgreSQL user a SUPERUSER with:

ALTER USER your_user SUPERUSER;

With ALTER CONSTRAINT

This approach don't require to be connected as a SUPERUSER, but only work with PostgreSQL versions >= 9.4. Try this if you are getting foreign key violation errors with the previous approach. It is as simple as using:

&testfixtures.PostgreSQL{UseAlterConstraint: true}

MySQL

Just make sure the connection string have the multistatement parameter set to true, and use:

&testfixtures.MySQL{}

SQLite

SQLite is also supported. It is recommended to create foreign keys as DEFERRABLE (the default) to prevent problems. See more on the SQLite documentation. (Foreign key constraints are no-op by default on SQLite, but enabling it is recommended).

&testfixtures.SQLite{}

Microsoft SQL Server

SQL Server support requires SQL Server >= 2008. Inserting on IDENTITY columns are handled as well. Just make sure you are logged in with a user with ALTER TABLE permission.

&testfixtures.SQLServer{}

Oracle

Oracle is supported as well. Use:

&testfixtures.Oracle{}

Contributing

Tests were written to ensure everything work as expected. You can run the tests with:

# running tests for PostgreSQL
go test -tags postgresql

# running test for MySQL
go test -tags mysql

# running tests for SQLite
go test -tags sqlite

# running tests for SQL Server
go test -tags sqlserver

# running tests for Oracle
go test -tags oracle

# running test for multiple databases at once
go test -tags 'sqlite postgresql mysql'

# running tests + benchmark
go test -v -bench=. -tags postgresql

Travis runs tests for PostgreSQL, MySQL and SQLite.

To set the connection string of tests for each database, edit the .env file, but do not include the changes a in pull request.

Changes in v2

A context was created to allow cache of some SQL statements. See in the documentation above how to use it.

The helpers were renamed to have a smaller name:

PostgreSQLHelper{} -> PostgreSQL{}
MySQLHelper{}      -> MySQL{}
SQLiteHelper{}     -> SQLite{}
SQLServerHelper{}  -> SQLServer{}
OracleHelper{}     -> Oracle{}

The old functions and helpers are still available for backward compatibility. See the file deprecated.go

Alternatives

If you don't think using fixtures is a good idea, you can try one of these packages instead:

  • factory-go: Factory for Go. Inspired by Python's Factory Boy and Ruby's Factory Girl
  • go-txdb (Single transaction SQL driver for Go): Use a single database transaction for each functional test, so you can rollback to previous state between tests to have the same database state in all tests
  • go-sqlmock: A mock for the sql.DB interface. This allow you to unit test database code without having to connect to a real database

There's also these other implementations of test fixtures for Go: