Exact Enforcement

Testix enforces function calls which are specified in a Scenario. It enforces

  1. the order in which calls are made

  2. the exact arguments, positional and keyword, which are used

  3. unexpected calls are considered a failure

Wrong Arguments

So, e.g. if we have a test like this:

 1from testix import *
 2import my_code
 3
 4def test_my_code():
 5    with Scenario() as s:
 6        s.source.get_names('all', order='lexicographic', ascending=True) >> ['some', 'names']
 7        s.destination.put_names(['some', 'names'])
 8
 9        my_code.go(Fake('source'), Fake('destination'))
10

The code must be some variation of

names = name_source.get_names('all', order='lexicographic', ascending=True)
# and at some point later...
name_destination.put_names(names)

any of these will cause a failure:

name_source.get_names('all', 'lexicographic', True)       # lexicographic should be a keyword argument
name_source.get_names('all', True, order='lexicographic') # ascending should be a keyworkd argument
name_source.get_names(spec='all', order='lexicographic', ascending=True) # spec is unexpected

Unexpected Calls

This code will also make the test fail:

def go(source, destination):
    names = source.get_names('all', order='lexicographic', ascending=True)
    destination.put_names(names)
    destination.something_else()

and Testix will report

E       Failed:
E       testix: ExpectationException
E       testix details:
E       === Scenario (no title) ===
E       unexpected call: destination.something_else()
E       Expected nothing

That is, the Scenario’s various expectations were met, but then the code “surprised” Testix with another call on a Fake object.

As we said before, the right way to specify Testix Scenarios as to specify what you want exactly - no more, no less.

Ways Around Exactness

Sometimes, this exactness is too much - Testix supports ways around this, but most of the time, it is good to be exact. These features are out of the scope of this tutorial, and are documented separately.