Testing Peewee Applications

When writing tests for an application that uses Peewee, it may be desirable to use a special database for tests. Another common practice is to run tests against a clean database, which means ensuring tables are empty at the start of each test.

To bind your models to a database at run-time, you can use the following methods:

  • Database.bind_ctx(), which returns a context-manager that will bind the given models to the database instance for the duration of the wrapped block.
  • Model.bind_ctx(), which likewise returns a context-manager that binds the model (and optionally its dependencies) to the given database for the duration of the wrapped block.
  • Database.bind(), which is a one-time operation that binds the models (and optionally its dependencies) to the given database.
  • Model.bind(), which is a one-time operation that binds the model (and optionally its dependencies) to the given database.

Depending on your use-case, one of these options may make more sense. For the examples below, I will use Model.bind().

Example test-case setup:

  1. # tests.py
  2. import unittest
  3. from my_app.models import EventLog, Relationship, Tweet, User
  4. MODELS = [User, Tweet, EventLog, Relationship]
  5. # use an in-memory SQLite for tests.
  6. test_db = SqliteDatabase(':memory:')
  7. class BaseTestCase(unittest.TestCase):
  8. def setUp(self):
  9. # Bind model classes to test db. Since we have a complete list of
  10. # all models, we do not need to recursively bind dependencies.
  11. for model in MODELS:
  12. model.bind(test_db, bind_refs=False, bind_backrefs=False)
  13. test_db.connect()
  14. test_db.create_tables(MODELS)
  15. def tearDown(self):
  16. # Not strictly necessary since SQLite in-memory databases only live
  17. # for the duration of the connection, and in the next step we close
  18. # the connection...but a good practice all the same.
  19. test_db.drop_tables(MODELS)
  20. # Close connection to db.
  21. test_db.close()
  22. # If we wanted, we could re-bind the models to their original
  23. # database here. But for tests this is probably not necessary.

As an aside, and speaking from experience, I recommend testing your application using the same database backend you use in production, so as to avoid any potential compatibility issues.

If you’d like to see some more examples of how to run tests using Peewee, check out Peewee’s own test-suite.