Collecting Tests¶
To run tests, they must be collected in a Tests
instance. There are many ways this can be achieved, allowing flexibility
and separation.
- Register individual functions with the
Tests.test()
decorator. - Register other collections with
Tests.register()
or as arguments to the constructor. A collection according to Attest is an iterable yielding test callables, this includes:- Lists of lambdas and function references.
Tests
instances.- Instances of subclasses of
TestBase
. - Classes are instantiated and returned, allowing
Tests.register()
to be used as a class decorator in Python 2.6 or later.
Using Functions¶
-
class
Tests
(tests=(), contexts=None, replace_tests=False, replace_contexts=False)[source]¶ Collection of test functions.
Parameters: - tests – String, or iterable of values, suitable as argument(s) to
register()
. - contexts – Iterable of callables that take no arguments and return a context manager.
- replace_tests – If true,
test()
returns the wrapper function rather than the original. This option is available for backwards-compatibility. - replace_contexts – If true,
context()
returns the context manager rather than the original generator function. Provided for backwards-compatibility.
New in version 0.6: Pass a single string to tests without wrapping it in an iterable.
New in version 0.6: The replace_tests and replace_contexts parameters. The decorator methods now default to simply registering functions and leaving the original in place. This allows functions to be decorated and registered with multiple collections easily.
-
run
(reporter=auto_reporter)[source]¶ Run all tests in this collection.
Parameters: - reporter – An instance of
AbstractReporter
or a callable returning something implementing that API (not enforced). - full_tracebacks – Control if the call stack of Attest is hidden in tracebacks.
- fail_fast – Stop after the first failure.
- debugger – Enter PDB when tests fail.
- keyboard_interrupt – Let KeyboardInterrupt exceptions (CTRL+C) propagate.
Changed in version 0.6: Added full_tracebacks and fail_fast.
- reporter – An instance of
-
main
(argv=sys.argv)[source]¶ Interface to
run()
with command-line options.-h
,--help
- Show a help message
-r NAME
,--reporter NAME
- Select reporter by name with
get_reporter_by_name()
--full-tracebacks
- Show complete tracebacks without hiding Attest’s own call stack
-l
,--list-reporters
- List the names of all installed reporters
-p FILENAME
,--profile FILENAME
- Run the tests in cProfile and store the results in FILENAME
Remaining arguments are passed to the reporter.
New in version 0.2.
Changed in version 0.4:
--list-reporters
was added.Changed in version 0.6:
--full-tracebacks
was added.
-
context
(func)[source]¶ Decorate a function as a
contextmanager()
for running the tests in this collection in. Corresponds to setup and teardown in other testing libraries.db = Tests() @db.context def connect(): con = connect_db() try: yield con finally: con.disconnect() @db.test def using_connection(con): assert con is not None
The above corresponds to:
db = Tests() @contextmanager def connect(): con = connect_db() try: yield con finally: con.disconnect() @db.test def using_connection(): with connect() as con: assert con is not None
The difference is that this decorator applies the context to all tests defined in its collection, so it’s less repetitive.
Yielding
None
or nothing passes no arguments to the test, yielding a single value other than a tuple passes that value as the sole argument to the test, yielding a tuple splats the tuple as the arguments to the test. If you want to yield a tuple as the sole argument, wrap it in a one-tuple or unsplat the args in the test.You can have more than one context, which will be run in order using
contextlib.nested()
, and their yields will be passed in order to the test functions.New in version 0.2: Nested contexts.
Changed in version 0.5: Tests will gets as many arguments as they ask for.
-
register
(tests)[source]¶ Merge in other tests.
Parameters: tests – - A class, which is then instantiated and return allowing it to be
used as a decorator for
TestBase
classes. - A string, representing the dotted name to one of:
- a module or package, which is recursively scanned for
Tests
instances that are not private - an iterable yielding tests
- a module or package, which is recursively scanned for
- Otherwise any iterable object is assumed to yield tests.
Any of these can be passed in a list to the
Tests
constructor.New in version 0.2: Refer to collections by import path as a string
New in version 0.6: Recursive scanning of modules and packages
Changed in version 0.6: Tests are only added if not already added
- A class, which is then instantiated and return allowing it to be
used as a decorator for
-
register_if
(condition)[source]¶ Returns
register()
if the condition isTrue
.New in version 0.4.
-
test_case
()[source]¶ Create a
unittest.TestCase
class from this collection.Tests in the collection are added as instance methods on the
TestCase
. Method names are prefixed withtest_
if they’re not already. Duplicate method names are given a_#
suffix.Example:
>>> suite = Tests() >>> @suite.test ... def simple(): ... pass ... >>> @suite.test ... def simple(): ... pass ... >>> TestCase = suite.test_case() >>> assert TestCase.test_simple >>> assert TestCase.test_simple_2
-
test_suite
()[source]¶ Create a
unittest.TestSuite
instance from this collection.
- tests – String, or iterable of values, suitable as argument(s) to
Using Classes¶
-
class
TestBase
[source]¶ Base for test classes. Decorate test methods with
test()
. Needs to be registered with aTests
collection to be run. For setup and teardown, override__context__()
like acontextmanager()
(without the decorator).class Math(TestBase): def __context__(self): self.two = 1 + 1 yield del self.two @test def arithmetics(self): assert self.two == 2 suite = Tests([Math()]) suite.run()