pypa/warehouse — pull request #316 by dstufft (2014-05-05 05:50:43+00:00)
Title: Using the Database in our tests: Database Fixtures!

This PR sets up a database fixture system, and then converts one test to use this system, it is designed primarily to implement/settle on a fixture system which can then be used throughout the other tests.

The system implemented in this PR is based on a library called charlatan, it has been slightly modified (via subclassing) to support ORM-less execution.

The system supports:
* Named fixtures that can be loaded independently of one another.
* Fixtures can depend on other fixtures
* Helper utilities for handling date times within fixtures
* Other things, but I'm not sure if they are relevant for us.

Using the fixtures looks like:

```yaml
# Single
# This will be named "my-fixture-with-model"
my-fixture-with-model:
model: warehouse.packaging.tables:packages
fields:
name: my-package
normalized_name: my-package

# This will be named "my-fixture-without-model"
my-fixture-without-model:
fields:
name: my-other-package
normalized_name: my-other-package

# Collections
my-fixture-collection:
model: warehouse.packaging.tables:releases

# These will by the default fields
fields:
name: my-package

objects:
# This will be named "my-fixture-collection.release-1-0"
release-1-0:
version: "1.0"

# This will be named "my-fixture-collection.release-2-0"
release-2-0:
version: "2.0"
```

And then:

```python
# Using the ``db_fixtures`` pytest fixture directly
def test_my_thing(db_fixtures):
# Inserts the fixture into the database, and returns a dictionary of
# fields
thing1 = db_fixtures.install_fixture("my-fixture-with-models")

# Doesn't insert the fixture into the database, but returns the
# dictionary of fields
thing2 = db_fixtures.get_fixture("my-fixture-collection.release-1-0")

# Doesn't insert the fixture into the database, because it has no model
# attribute, but will return the dictionary of fields
thing3 = db_fixtures.install_fixture("my-fixture-without-model")

# Using the ``tests.lib.db.db_fixtures`` decorator
from tests.lib.db import db_fixtures

@db_fixtures(
"my-fixture-with-models",
"my-fixture-collection.release-1-0",
# This last one doesn't make much sense, since there is no model
"my-fixture-without-model",
)
def test_my_other_thing(db_fixtures): # The pytest fixture is still needed
# All of the above fixtures will already have had install_fixture
# called for them
pass
```