Testing Peewee Applications

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

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

  • Database.bind_ctx(), which returns a context-manager that will bindthe given models to the database instance for the duration of the wrappedblock.
  • Model.bind_ctx(), which likewise returns a context-manager thatbinds the model (and optionally its dependencies) to the given database forthe 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 theexamples 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.  
  5. MODELS = [User, Tweet, EventLog, Relationship]
  6.  
  7. # use an in-memory SQLite for tests.
  8. test_db = SqliteDatabase(':memory:')
  9.  
  10. class BaseTestCase(unittest.TestCase):
  11. def setUp(self):
  12. # Bind model classes to test db. Since we have a complete list of
  13. # all models, we do not need to recursively bind dependencies.
  14. test_db.bind(MODELS, bind_refs=False, bind_backrefs=False)
  15.  
  16. test_db.connect()
  17. test_db.create_tables(MODELS)
  18.  
  19. def tearDown(self):
  20. # Not strictly necessary since SQLite in-memory databases only live
  21. # for the duration of the connection, and in the next step we close
  22. # the connection...but a good practice all the same.
  23. test_db.drop_tables(MODELS)
  24.  
  25. # Close connection to db.
  26. test_db.close()
  27.  
  28. # If we wanted, we could re-bind the models to their original
  29. # database here. But for tests this is probably not necessary.

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

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