Fork me on GitHub

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 attest.collectors.Tests(tests=(), contexts=None)[source]

Collection of test functions.

Parameters:
  • tests – Iterable of other test collections to register with this one.
  • contexts – Iterable of callables that take no arguments and return a context manager.
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).
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()
-l, --list-reporters
List the names of all installed reporters

Remaining arguments are passed to the reporter.

New in version 0.2.

Changed in version 0.4: --list-reporters was added.

test(func)[source]

Decorate a function as a test belonging to this collection.

test_if(condition)[source]

Returns test() if the condition is True.

New in version 0.4.

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 another test collection.

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 import path to an iterable yielding tests, in the form of 'package.module.object'.
  • 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

register_if(condition)[source]

Returns register() if the condition is True.

New in version 0.4.

test_suite()[source]

Create a unittest.TestSuite from this collection.

Using classes

class attest.collectors.TestBase[source]

Base for test classes. Decorate test methods with test(). Needs to be registered with a Tests collection to be run. For setup and teardown, override __context__() like a contextmanager() (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()
attest.collectors.test(meth)[source]

Mark a TestBase method as a test and wrap it to run in the TestBase.__context__() of the subclass.

attest.collectors.test_if(condition)[source]

Returns test() if the condition is True.

New in version 0.4.