Skip to content
This repository has been archived by the owner on Mar 8, 2021. It is now read-only.

Latest commit

 

History

History
286 lines (206 loc) · 8.13 KB

file-format.rst

File metadata and controls

286 lines (206 loc) · 8.13 KB

File format

from charlatan import FixturesManager

charlatan only supports YAML at time of writing.

Fixtures are defined in a YAML file. Here is its general structure:

examples/fixtures.yaml

In this example:

  • toaster, toast1 and toast2 are the fixture keys.
  • model is where to get the model. Both relative and absolute addressing are supported
  • fields are provided as argument when instantiating the class: Toaster(**fields).
  • !rel lets you create relationships by pointing to another fixture key.
  • !now lets you enter timestamps. It supports basic operations (adding/subtracting days, months, years). Note that !now is evaluated when the fixture file is read, not when the test is run.

Defining a fixture

A fixture has an identifier (in the example above, toaster is one of the fixture identifiers), as well as the following configuration:

  • fields: a dictionary for which keys are attribute, and values are their values
  • model gives information about how to retrieve the model
  • post_creation lets you have some attribute values be assigned after instantiation.

Inheritance

Fixtures can inherit from other fixtures.

examples/fixtures_inheritance.yaml

>>> import pprint >>> 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'} >>> pprint.pprint(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'

0.2.4 Fixtures can now inherits from other fixtures.

Having dictionaries as 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.

examples/fixtures_dict.yaml

>>> manager = FixturesManager() >>> manager.load("docs/examples/fixtures_dict.yaml") >>> manager.get_fixture("fixture_name") {'foo': 'bar'} >>> manager.get_fixture("fixture_list") ['foo', 'bar']

0.2.4 Empty models are allowed so that dict ands lists can be used as fixtures.

Getting an already existing fixture from the database

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.

examples/fixtures_id.yaml

Dependencies

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.

examples/dependencies.yaml

0.2.7

Post creation

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)

0.2.0 It is now possible to use rel in post_creation.

Linking to other objects

Example:

examples/relationships.yaml

To link to another object defined in the configuration file, use !rel. You can link to another objet (e.g. !rel toaster) or to another object's attribute (e.g. !rel toaster.color).

>>> manager = FixturesManager() >>> manager.load("docs/examples/relationships.yaml", ... models_package="charlatan.tests.fixtures.simple_models") >>> manager.get_fixture("user").toasters [<Toaster 'red'>] >>> manager.get_fixture("toaster_colors") {'color': 'red'}

You can also link to specific attributes of collection's item (see collection for more information about collections).

examples/relationships.yaml

>>> manager.get_fixture("toaster_from_collection") <Toaster 'red'>

0.2.0 It is now possible to link to another object' attribute.

Collections of Fixtures

Charlatan also provides more efficient way to define variations of fixtures. The basic idea is to define the model and the default fields, then use the objects key to define related fixtures. There's two ways to define those fixtures in the objects key:

  • Use a list. You will then be able to access those fixtures via their index, e.g. toaster.0 for the first item.
  • Use a dict. The key will be the name of the fixture, the value a dict of fields. You can access them via their namespace: e.g. toaster.blue.

You can also install all of them by installing the name of the collection.

examples/collection.yaml

Here's how you would use this fixture file to access specific fixtures:

>>> manager = FixturesManager() >>> manager.load("docs/examples/collection.yaml") >>> manager.get_fixture("toasters.green") <Toaster 'green'> >>> manager.get_fixture("anonymous_toasters.0") <Toaster 'yellow'>

You can also access the whole collection:

>>> pprint.pprint(manager.get_fixture("toasters")) {'blue': <Toaster 'blue'>, 'green': <Toaster 'green'>} >>> manager.get_fixture("anonymous_toasters") [<Toaster 'yellow'>, <Toaster 'black'>]

Like any fixture, this collection can be linked to in a relationship using the !rel keyword in an intuitive way.

examples/collection.yaml

>>> pprint.pprint(manager.get_fixture("collection")) {'things': {'blue': <Toaster 'blue'>, 'green': <Toaster 'green'>}} >>> user1 = manager.get_fixture("users.1") >>> user1.toasters [<Toaster 'blue'>, <Toaster 'green'>] >>> user2 = manager.get_fixture("users.2") >>> user2.toasters [<Toaster 'yellow'>, <Toaster 'black'>] >>> manager.get_fixture("users.3").toasters [<Toaster 'green'>] >>> manager.get_fixture("users.4").toasters [<Toaster 'yellow'>]

0.3.4 Access to unnamed fixture by using a .{index} notation instead of _{index}.

0.3.4 You can now have list of named fixtures.

0.2.8 It is now possible to retrieve lists of fixtures and link to them with !rel

Relative timestamps

Use !now:

  • !now +1y returns the current datetime plus one year
  • !now +5m returns the current datetime plus five months
  • !now -10d returns the current datetime minus ten days
  • !now +15M (note the case) returns the current datetime plus 15 minutes
  • !now -30s returns the current datetime minus 30 seconds

For Unix timestamps (seconds since the epoch) you can use !epoch_now:

  • !epoch_now +1d returns the current datetime plus one year in seconds since the epoch

All the same time deltas work.

0.2.9 It is now possible to use times in seconds since the epoch

Unicode Strings

0.3.5

In python 2 strings are not, by default, loaded as unicode. To load all the strings from the yaml files as unicode strings, pass the option unicode_output as True when you instantiate your fixture manager.