Overview¶
Why Use Contextional?¶
Short answer
- fast and easy to use
- works with
unittest
,unittest2
,nose
, andpytest
- deterministic fixture and test order without being tied to a class
- might significantly improve functional test suite run time
- much better test output organization and readability (doesn’t even need to be used for functional tests)
Long answer
If you use the standard unittest
/unittest2
libraries to write
functional tests, you’re likely to have a very complicated test suite, as the
only thing you should have in each test method should be a single assert, your
test classes should each only pertain to one specific scenario, and the setups
and teardowns for each test class should be completely isolated from and
independant of all the other test classes.
The more complex the thing you’re testing is, the more scenarios you’ll have to cover, which means more test classes that you’ll have to write. A properly made functional test suite for a decently complex product can easily take a very long time to run, as each test class will have to run every bit of setup required for it to run and then completely tear it all down once it’s finished running all its tests.
It’s not a best practice to have a test class try and rely on any previously run classes when writing tests in the traditional fashion, as the order they run in isn’t deterministic.
That’s where Contextional comes in.
Contextional uses a combination of with
statements and decorators to let
you quickly and easily define fixtures and tests with easy-to-read descriptions
for each context and test. This is done to make sure each fixture and test
happens in a logical and deterministic order and that the test output is
organized and more idiomatic.
Quick Example¶
Code:
from contextional import GroupContextManager as GCM
with GCM("Main Group") as MG:
@GCM.add_setup
def setUp():
GCM.value = 1
@GCM.add_test("value is 1")
def test(case):
case.assertEqual(GCM.value, 1)
with GCM.add_group("Child Group"):
@GCM.add_setup
def setUp():
GCM.value += 1
@GCM.add_test("value is now 2")
def test(case):
case.assertEqual(GCM.value, 2)
MG.create_tests()
Test output:
Main Group
value is 1 ... ok
Child Group
value is now 2 ... ok