Helpers for unittest¶
AnyBlok provides base test classes to help creating fixtures.
Blok developers will be mostly interested in BlokTestCase
.
Base classes for unit/integration tests with anyblok.
This module provides BlokTestCase
, which is the main one meant for
blok tests, and DBTestCase
, whose primary purpose is to test anyblok
itself, in so-called “framework tests”.
TestCase¶
from anyblok.tests.testcase import TestCase
-
class
anyblok.tests.testcase.
TestCase
(methodName='runTest') Bases:
unittest.case.TestCase
Common helpers, not meant to be used directly.
-
Configuration
(**values) Add Configuration value only in the contextmanager
with TestCase.Configuration(db_name='a db name'): self.assertEqual(Configuration.get('db_name'), 'a db name')
Parameters: **values – values to update
-
classmethod
additional_setting
()
-
callCleanUp
()
-
cleanUp
()
-
classmethod
createdb
(keep_existing=False) Create the database specified in configuration.
cls.init_configuration_manager() cls.createdb()
Parameters: keep_existing – If false drop the previous db before create it
-
classmethod
dropdb
() Drop the database specified in configuration.
cls.init_configuration_manager() cls.dropdb()
-
classmethod
getRegistry
() Return the registry for the test database.
This assumes the database is created, and the registry has already been initialized:
registry = self.getRegistry()
Return type: registry instance
-
classmethod
init_configuration_manager
(**env) Initialise the configuration manager with environ variable to launch the test
Warning
For the moment we not use the environ variable juste constante
Parameters: - prefix – prefix the database name
- env – add another dict to merge with environ variable
-
setUp
()
-
tearDown
() Roll back the session
-
DBTestCase¶
Warning
this testcase destroys the test database for each unittest
-
class
anyblok.tests.testcase.
DBTestCase
(methodName='runTest') Bases:
anyblok.tests.testcase.TestCase
Base class for tests that need to work on an empty database.
Warning
The database is created and dropped with each unit test
For instance, this is the one used for Field, Column, RelationShip, and more generally core framework tests.
The drawback of using this base class is that tests will be slow. The advantage is ultimate test isolation.
Sample usage:
from anyblok.tests.testcase import DBTestCase def simple_column(ColumnType=None, **kwargs): @Declarations.register(Declarations.Model) class Test: id = Declarations.Column.Integer(primary_key=True) col = ColumnType(**kwargs) class TestColumns(DBTestCase): def test_integer(self): Integer = Declarations.Column.Integer registry = self.init_registry(simple_column, ColumnType=Integer) test = registry.Test.insert(col=1) self.assertEqual(test.col, 1)
-
blok_entry_points
= ('bloks',) setuptools entry points to load blok
-
init_registry
(function, **kwargs) call a function to filled the blok manager with new model
Parameters: - function – function to call
- kwargs – kwargs for the function
Return type: registry instance
-
setUp
() Create a database and load the blok manager
-
classmethod
setUpClass
() Intialialise the configuration manager
-
tearDown
() Clear the registry, unload the blok manager and drop the database
-
BlokTestCase¶
-
class
anyblok.tests.testcase.
BlokTestCase
(methodName='runTest') Bases:
unittest.case.TestCase
Base class for tests meant to run on a preinstalled database.
The tests written with this class don’t need to start afresh on a new database, and therefore run much faster than those inheriting
DBTestCase
. Instead, they expect the tested bloks to be already installed and up to date.The session gets rollbacked after each test.
Such tests are appropriate for a typical blok developper workflow:
- create and install the bloks once
- run the tests of the blok under development repeatedly
- upgrade the bloks in database when needed (schema change, update of dependencies)
They are also appropriate for on the fly testing while installing the bloks: the tests of each blok get run on the database state they expect, before dependent (downstream) bloks, that could. e.g., alter the database schema, get themselves installed. This is useful to test a whole stack at once using only one database (typically in CI bots).
Sample usage:
from anyblok.tests.testcase import BlokTestCase class MyBlokTest(BlokTestCase): def test_1(self): # access to the registry by ``self.registry`` ...
-
classmethod
additional_setting
()
-
callCleanUp
()
-
cleanUp
()
-
registry
= None The instance of
anyblok.registry.Registry`
to use in tests.The
session_commit()
method is disabled to avoid side effects from one test to the other.
-
setUp
()
-
classmethod
setUpClass
() Initialize the registry.
-
tearDown
() Roll back the session
LogCapture¶
-
class
anyblok.tests.testcase.
LogCapture
(names=None, install=True, level=1, propagate=None) Bases:
testfixtures.logcapture.LogCapture
Overwrite
testfixtures.LogCapture
to add some helper methods-
acquire
() Acquire the I/O thread lock.
-
actual
()
-
addFilter
(filter) Add the specified filter to this handler.
-
atexit
()
-
atexit_setup
= False
-
check
(*expected) This will compare the captured entries with the expected entries provided and raise an
AssertionError
if they do not match.Parameters: expected – A sequence of 3-tuples containing the expected log entries. Each tuple should be of the form (logger_name, string_level, message)
-
clear
() Clear any entries that have been captured.
-
close
() Tidy up any resources used by the handler.
This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods.
-
createLock
() Acquire a thread lock for serializing access to the underlying I/O.
-
emit
(record)
-
filter
(record) Determine if a record is loggable by consulting all the filters.
The default is to allow the record to be logged; any filter can veto this and the record is then dropped. Returns a zero value if a record is to be dropped, else non-zero.
-
flush
() Ensure all logging output has been flushed.
This version does nothing and is intended to be implemented by subclasses.
-
format
(record) Format the specified record.
If a formatter is set, use it. Otherwise, use the default formatter for the module.
-
get_critical_messages
() Return only the logging.CRITICAL messages
-
get_debug_messages
() Return only the logging.DEBUG messages
-
get_error_messages
() Return only the logging.ERROR messages
-
get_info_messages
() Return only the logging.INFO messages
-
get_messages
(*levels) Return the captured messages
with LogCapture() as logs: messages = logs.get_messages(INFO, WARNING)
Parameters: *levels – list of logging.level Return type: list of formated message
-
get_name
()
-
get_warning_messages
() Return only the logging.WARNING messages
-
handle
(record) Conditionally emit the specified logging record.
Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock. Returns whether the filter passed the record for emission.
-
handleError
(record) Handle errors which occur during an emit() call.
This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method.
-
install
() Install this
LogHandler
into the Python logging framework for the named loggers.This will remove any existing handlers for those loggers and drop their level to 1 in order to capture all logging.
-
installed
= False
-
instances
= set()
-
name
-
release
() Release the I/O thread lock.
-
removeFilter
(filter) Remove the specified filter from this handler.
-
setFormatter
(fmt) Set the formatter for this handler.
-
setLevel
(level) Set the logging level of this handler. level must be an int or a str.
-
set_name
(name)
-
uninstall
() Un-install this
LogHandler
from the Python logging framework for the named loggers.This will re-instate any existing handlers for those loggers that were removed during installation and retore their level that prior to installation.
-
uninstall_all
() This will uninstall all existing
LogHandler
objects.
-