charlatan only supports YAML at time of writing.
Fixtures are defined in a YAML file. Here is its general structure:
toaster:
fields:
brand: Flying
number_of_toasts: 2
toasts: [!rel toast1, !rel toast2]
bought: !now -1y
model: Toaster
toaster_already_in_db:
id: 10
model: Toaster
toast1:
fields:
bread: brioche
model: .toast:Toast
toast2:
fields:
bread: campagne
model: .toast:Toast
user:
fields:
name: Michel Audiard
toaster: !rel toaster
model: toaster.models.user:User
post_creation:
has_used_toaster: true
In this example:
A fixture has an identifier (in the example above, toaster is one of the fixture identifiers), as well as the following configuration:
Fixtures can inherit from other fixtures.
first:
fields:
foo: bar
# Everything is inherited from first.
second:
inherit_from: first
# You can overwrite fields.
third:
inherit_from: first
fields:
toaster: toasted
# You can also overwrite the model.
fourth:
inherit_from: first
model: collections:Counter
# You can also overwrite both.
fifth:
inherit_from: second
fields:
toaster: toasted
model: collections:Counter
>>> from charlatan import FixturesManager
>>> manager = FixturesManager()
>>> manager.load("docs/examples/fixtures_inheritance.yaml")
>>> manager.get_fixture("first")
{'foo': 'bar'}
>>> manager.get_fixture("second")
{'foo': 'bar'}
>>> manager.get_fixture("third")
{'foo': 'bar', 'toaster': 'toasted'}
>>> fourth = manager.get_fixture("fourth")
>>> fourth
Counter({'foo': 'bar'})
>>> fourth.__class__.__name__
'Counter'
>>> fifth = manager.get_fixture("fifth")
>>> fifth
Counter({'toaster': 'toasted', 'foo': 'bar'})
>>> fifth.__class__.__name__
'Counter'
New in version 0.2.4: Fixtures can now inherits from other fixtures.
If you don’t specify the model, the content of fields will be returned as is. This is useful if you want to enter a dictionary or a list directly.
fixture_name:
fields:
foo: bar
fixture_list:
fields:
- "foo"
- "bar"
>>> manager = FixturesManager()
>>> manager.load("docs/examples/fixtures_dict.yaml")
>>> manager.get_fixture("fixture_name")
{'foo': 'bar'}
>>> manager.get_fixture("fixture_list")
['foo', 'bar']
New in version 0.2.4: Empty models are allowed so that dict ands lists can be used as fixtures.
You can also get a fixture directly from the database (it uses sqlalchemy): in this case, you just need to specify the model and an id.
toaster_already_in_db:
id: 10
model: Toaster
If a fixture depends on some side effect of another fixture, you can mark that dependency (and, necessarily, ordering) by using the depend_on section.
fixture1:
fields:
- name: "foo"
fixture2:
depend_on:
- fixture1
fields:
- name: "bar"
post_creation:
- some_descriptor_that_depend_on_fixture1: true
New in version 0.2.7.
Example:
user:
fields:
name: Michel Audiard
model: User
post_creation:
has_used_toaster: true
# Note that rel are allowed in post_creation
new_toaster: !rel blue_toaster
For a given fixture, post_creation lets you change some attributes after instantiation. Here’s the pseudo-code:
instance = ObjectClass(**fields)
for k, v in post_creation:
setattr(instance, k, v)
New in version 0.2.0: It is now possible to use rel in post_creation.
Example:
user:
fields:
name: Michel Audiard
favorite_toaster: !rel red_toaster
toaster_id: !rel toaster.id
model: User
To link to another object defined in the configuration file, use !rel. You can link to another objet (e.g. !rel red_toaster) or to another object’s attribute (e.g. !rel toaster.id).
New in version 0.2.0: It is now possible to link to another object’ attribute.
Example:
characters
model: Character
objects:
-
name: Rick Deckard
favorite_toaster: !rel red_toaster
-
name: Roy Batty
favorite_toaster: !rel green_toaster
movie:
model: Movie
fields:
characters: !rel characters
A collection of models can be defined by simply providing the objects key. The whole list can be installed by the fixture name ('characters' in the example). Alternatively, single items can be retrieved from the list by appending an _<index> to the end of the collection name. So to get Rick Deckard, the fixture name is 'characters_0'.
Like any fixture, this collection can be linked to in a relationship using the !rel keyword. In the example, installing the 'movie' fixture gives a model that has an characters attribute that is a list containing Rick and Roy.
New in version 0.2.8: It is now possible to retrieve lists of fixtures and link to them with !rel
Use !now:
For Unix timestamps (seconds since the epoch) you can use !epoch_now:
All the same time deltas work.
New in version 0.2.9: It is now possible to use times in seconds since the epoch