Skip to main content

mongo_bakery

codecov mongo-bakery-ci GitHub issues GitHub stars GitHub top language GPLv3 license

Inspired by model-bakery, this project aims to simplify the process of creating MongoDB documents for testing purposes. The goal is to deliver a maintainable, intuitive, and developer-friendly API specifically designed for MongoDB. By streamlining the generation of test data, this tool will empower developers to efficiently create realistic document structures, enhancing the testing workflow for applications that rely on MongoDB as their primary database.

Motivation

  • To have the conveniences of model_bakery (from the Django world) in Flask with MongoEngine.
  • We want more context within the test itself (instead of having fixtures in conftest where we don't know which fields are populated).
  • We don't want to create a Factory for every Document in the application.

Installation

uv add mongo-bakery

Usage

mongo_bakery fills in a MongoEngine Document (or EmbeddedDocument) with realistic fake data so you don't have to hand-write every field in every test. All the examples below assume:

from mongoengine import BooleanField, Document, IntField, StringField

from mongo_bakery import baker


class Customer(Document):
    name = StringField(required=True)
    email = StringField(required=True)
    company = StringField(required=True)
    phone_number = StringField(required=True)
    loyalty_points = IntField(required=True)
    notes = StringField(required=False)
    newsletter_opt_in = BooleanField(required=False)

Creating a basic Document

baker.make instantiates and saves the document, automatically generating values for every required field:

customer = baker.make(Customer)

Creating multiple instances with _quantity

Pass _quantity to create and save several instances at once. baker.make returns a list when _quantity > 1:

customers = baker.make(Customer, _quantity=5)
len(customers)  # 5

Not-required (optional) fields

Optional fields (required=False) are not filled in automatically — baker.make only generates data for required fields, leaving optional ones at their MongoEngine default (e.g. None). Pass any field, required or not, as a keyword argument to set it explicitly:

customer = baker.make(Customer, notes="VIP client", newsletter_opt_in=True)

Keyword arguments always win over generated data, so this also works to override a required field with a specific value.

Fields with realistic values

For StringFields, mongo_bakery checks whether Faker has a provider method whose name matches the field's name, and uses it when available. That's why, on the Customer example above, email, company and phone_number come out looking like real data instead of a random word:

customer = baker.make(Customer)
customer.email         # e.g. "jean23@example.com" instead of a random word
customer.company       # e.g. "Smith, Doe and Partners"
customer.phone_number  # e.g. "+1-555-019-2837"

Name your fields after a Faker provider (address, city, job, url, ...) to get more meaningful fake data for free. Fields without a matching provider fall back to a random word.

Fields restricted with choices

When a field declares choices, baker.make always picks one of the allowed values, so the generated document passes MongoEngine's validation:

class Order(Document):
    status = StringField(required=True, choices=["pending", "shipped", "delivered"])


order = baker.make(Order)
order.status in ["pending", "shipped", "delivered"]  # always True

Unique/incrementing values with baker.seq

Pass baker.seq(value) as a kwarg to get a different, incrementing value on each instance instead of the same value repeated across _quantity instances. It supports str, int, float, date and datetime base values:

customers = baker.make(Customer, name=baker.seq("Chad"), _quantity=3)
[customer.name for customer in customers]  # ["Chad1", "Chad2", "Chad3"]

Use increment_by to control the step (a timedelta for date/datetime values) and start to control the first value of the sequence (defaults to increment_by):

customers = baker.make(Customer, loyalty_points=baker.seq(0, increment_by=10, start=100), _quantity=3)
[customer.loyalty_points for customer in customers]  # [100, 110, 120]

Reproducible data with baker.seed

Call baker.seed(value) to seed Faker's random generator, so baker.make produces the same mock data across runs — useful for debugging a flaky test or reproducing a specific failure:

baker.seed(1234)
customer = baker.make(Customer)  # always the same field values for this seed

Embedded and referenced Documents

EmbeddedDocumentField and ReferenceField are resolved recursively with baker.make, so nested documents are created for you as well.

Cleaning up

baker.make keeps track of every instance it saved. Call baker.cleanup() (e.g. in a test teardown/fixture) to delete them all:

baker.cleanup()

mongo_bakery also ships as a pytest plugin, registered automatically once it's installed. Use the baker fixture instead to get this cleanup for free after every test:

def test_something(baker):
    customer = baker.make(Customer)
    ...
# cleanup() is called automatically once the test finishes

See the API Reference for the full Baker interface.

Alternatives

Draft Solution

Contributing

We welcome contributions to the mongo_bakery project! Here are the steps to get started:

  1. Fork the Repository: Fork the mongo_bakery repository on GitHub.

  2. Clone Your Fork: Clone your forked repository to your local machine.

    git clone https://github.com/your-username/mongo_bakery.git
    cd mongo_bakery
    
  3. Create a Branch: Create a new branch for your feature or bugfix.

    git checkout -b branch-name
    
  4. Install Dependencies: Install the required dependencies. We use the uv tool to manage our prject dependencies and vitualenv. So it is a prerequisite to the project.

    uv sync
    

    This command will create the Python virtual environment with the Python version of the project and install all dependencies.

  5. Make Changes: Implement your feature or bugfix.

  6. Run Tests and Lint: Ensure all tests and lint pass before submitting your changes.

    uv run task test
    

    This command runs ruff check as a lint, pytest to run all tests, and coverage html to generate an html report of test coverage. This html report is for the development side only. On our CI with Github Actions, it runs pytest --cov=mongo_bakery --cov-report=xml to generate a report that is send to codecov.io

  7. Commit Changes: Commit your changes with a descriptive commit message. Use Conventional Commits to write your commit messages.

    git add .
    git commit -m "feat(issue4): Description of your changes"
    
  8. Push to GitHub: Push your changes to your forked repository.

    git push origin branch-name
    
  9. Create a Pull Request: Open a pull request on the original repository. Provide a clear description of your changes and any relevant information.

  10. Review Process: Your pull request will be reviewed by the maintainers. Be prepared to make any necessary changes based on feedback.

Contributors

Made with contrib.rocks.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mongo_bakery-0.3.0.tar.gz (22.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mongo_bakery-0.3.0-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file mongo_bakery-0.3.0.tar.gz.

File metadata

  • Download URL: mongo_bakery-0.3.0.tar.gz
  • Upload date:
  • Size: 22.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mongo_bakery-0.3.0.tar.gz
Algorithm Hash digest
SHA256 8614646aadbbdfcb0b48535818154f55da3753f8062e23a094fdf084533d424f
MD5 d58129cf05c76d735e7e5c0adfa4bd3f
BLAKE2b-256 447cb4543c6e01a20f86815485bf1f10b95f372e467906e765ffa458de56934d

See more details on using hashes here.

File details

Details for the file mongo_bakery-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mongo_bakery-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 22.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.12.3 {"installer":{"name":"uv","version":"0.12.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mongo_bakery-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 54a6bf578688cec9157e81a7a5fc2b60039e02e28d55fa56b6dbf2d0aaf267e4
MD5 9c63b4bb06ddf19e7733941bf11f7602
BLAKE2b-256 1d759ab703c18df82a3bc270c848f60090e90ed261651114dbf2c26f8742e0a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page