Other test runners
Guara can e executed with many test frameworks other than pytest, for example unitest and testify. Here are the command examples and their outputs.
unittest
python -m unittest -v
Output
test_add_returns_3_when_adding_1_and_2 (examples.unit_test.calculator.test_calculator.TestCalculatorTestCase.test_add_returns_3_when_adding_1_and_2) ... 2025-01-15 23:11:52.585 INFO Transaction 'operations.Add'
2025-01-15 23:11:52.585 INFO a: 1
2025-01-15 23:11:52.585 INFO b: 2
2025-01-15 23:11:52.585 INFO Assertion 'IsEqualTo'
2025-01-15 23:11:52.585 INFO actual: '3'
2025-01-15 23:11:52.585 INFO expected: '3'
ok
test_list_tasks_many_assertions (examples.unit_test.todo_list.test_todo.TestToTestCase.test_list_tasks_many_assertions) ... 2025-01-15 23:11:52.585 INFO Transaction 'operations.Add'
2025-01-15 23:11:52.585 INFO task: buy cheese
2025-01-15 23:11:52.585 INFO Transaction 'operations.Add'
2025-01-15 23:11:52.585 INFO task: buy apple
2025-01-15 23:11:52.586 INFO Transaction 'operations.Add'
2025-01-15 23:11:52.586 INFO task: buy orange
2025-01-15 23:11:52.586 INFO Transaction 'operations.ListTasks'
2025-01-15 23:11:52.586 INFO Assertion 'HasSubset'
2025-01-15 23:11:52.586 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-15 23:11:52.586 INFO expected: '['buy cheese', 'buy orange']'
2025-01-15 23:11:52.586 INFO Assertion 'IsSortedAs'
2025-01-15 23:11:52.586 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-15 23:11:52.586 INFO expected: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-15 23:11:52.586 INFO Transaction 'operations.PrintDict'
2025-01-15 23:11:52.586 INFO Assertion 'HasKeyValue'
2025-01-15 23:11:52.586 INFO actual: '{'1': 'buy cheese', '2': 'buy apple', '3': 'buy orange'}'
2025-01-15 23:11:52.586 INFO expected: '{'1': 'buy cheese'}'
2025-01-15 23:11:52.586 INFO Transaction 'operations.Add'
2025-01-15 23:11:52.586 INFO task: buy watermelon
2025-01-15 23:11:52.586 INFO Transaction 'operations.GetBy'
2025-01-15 23:11:52.586 INFO index: 3
2025-01-15 23:11:52.586 INFO Assertion 'MatchesRegex'
2025-01-15 23:11:52.587 INFO actual: 'buy watermelon'
2025-01-15 23:11:52.587 INFO expected: '(.*)melon'
ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
Testify
testify examples/unit_test/calculator/test_calculator.py -v
Output
examples.unit_test.calculator.test_calculator TestifiedTestCalculatorTestCase.test_add_returns_3_when_adding_1_and_2 ... 2025-01-15 23:34:17.251 INFO Transaction 'operations.Add'
2025-01-15 23:34:17.251 INFO a: 1
2025-01-15 23:34:17.251 INFO b: 2
2025-01-15 23:34:17.251 INFO Assertion 'IsEqualTo'
2025-01-15 23:34:17.251 INFO actual: '3'
2025-01-15 23:34:17.251 INFO expected: '3'
ok in 0.00s
examples.unit_test.calculator.test_calculator TestCalculatorTestify.test_add_returns_3_when_adding_1_and_2 ... 2025-01-15 23:34:17.252 INFO Transaction 'operations.Add'
2025-01-15 23:34:17.252 INFO a: 1
2025-01-15 23:34:17.252 INFO b: 2
2025-01-15 23:34:17.252 INFO Assertion 'IsEqualTo'
2025-01-15 23:34:17.252 INFO actual: '3'
2025-01-15 23:34:17.252 INFO expected: '3'
ok in 0.00s
PASSED. 2 tests / 2 cases: 2 passed, 0 failed. (Total test time 0.00s)
Nose
Not working as there is an associated issue in Nose with Python 3.10+
stestr
Example of .stestr.config. Add to the root folder
[DEFAULT]
test_path=./examples
Running it
stestr run -v
Output
initialize_app
prepare_to_run_command Run
2025-01-16 00:26:33.648 INFO Transaction 'operations.Add'
2025-01-16 00:26:33.648 INFO a: 1
2025-01-16 00:26:33.648 INFO b: 2
2025-01-16 00:26:33.648 INFO Assertion 'IsEqualTo'
2025-01-16 00:26:33.648 INFO actual: '3'
2025-01-16 00:26:33.648 INFO expected: '3'
{1} examples.unit_test.calculator.test_calculator.TestCalculatorTestCase.test_add_returns_3_when_adding_1_and_2 [0.000655s] ... ok
2025-01-16 00:26:33.651 INFO Transaction 'operations.Add'
2025-01-16 00:26:33.651 INFO task: buy cheese
2025-01-16 00:26:33.651 INFO Transaction 'operations.Add'
2025-01-16 00:26:33.651 INFO task: buy apple
2025-01-16 00:26:33.651 INFO Transaction 'operations.Add'
2025-01-16 00:26:33.652 INFO task: buy orange
2025-01-16 00:26:33.652 INFO Transaction 'operations.ListTasks'
2025-01-16 00:26:33.652 INFO Assertion 'HasSubset'
2025-01-16 00:26:33.652 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:26:33.652 INFO expected: '['buy cheese', 'buy orange']'
2025-01-16 00:26:33.652 INFO Assertion 'IsSortedAs'
2025-01-16 00:26:33.652 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:26:33.652 INFO expected: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:26:33.652 INFO Transaction 'operations.PrintDict'
2025-01-16 00:26:33.652 INFO Assertion 'HasKeyValue'
2025-01-16 00:26:33.652 INFO actual: '{'1': 'buy cheese', '2': 'buy apple', '3': 'buy orange'}'
2025-01-16 00:26:33.652 INFO expected: '{'1': 'buy cheese'}'
2025-01-16 00:26:33.652 INFO Transaction 'operations.Add'
2025-01-16 00:26:33.652 INFO task: buy watermelon
2025-01-16 00:26:33.652 INFO Transaction 'operations.GetBy'
2025-01-16 00:26:33.652 INFO index: 3
2025-01-16 00:26:33.652 INFO Assertion 'MatchesRegex'
2025-01-16 00:26:33.653 INFO actual: 'buy watermelon'
2025-01-16 00:26:33.653 INFO expected: '(.*)melon'
{0} examples.unit_test.todo_list.test_todo.TestToTestCase.test_list_tasks_many_assertions [0.001642s] ... ok
======
Totals
======
Ran: 2 tests in 0.0050 sec.
- Passed: 2
- Skipped: 0
- Expected Fail: 0
- Unexpected Success: 0
- Failed: 0
Sum of execute time for each test: 0.0023 sec.
==============
Worker Balance
==============
- Worker 0 (1 tests) => 0:00:00.001642
- Worker 1 (1 tests) => 0:00:00.000655
clean_up Run
Green
green -vvv
Output
Green 4.0.2, Coverage 7.6.10, Python 3.11.9
examples.unit_test.calculator.test_calculator
TestCalculatorTestCase
test_add_returns_3_when_adding_1_and_22025-01-16 00:33:45.281 INFO Transaction 'operations.Add'
2025-01-16 00:33:45.282 INFO a: 1
2025-01-16 00:33:45.282 INFO b: 2
2025-01-16 00:33:45.282 INFO Assertion 'IsEqualTo'
2025-01-16 00:33:45.282 INFO actual: '3'
2025-01-16 00:33:45.282 INFO expected: '3'
2025-01-16 00:33:45.283 INFO Transaction 'operations.Add'
2025-01-16 00:33:45.283 INFO task: buy cheese
. test_add_returns_3_when_adding_1_and_2
2025-01-16 00:33:45.283 INFO Transaction 'operations.Add'
2025-01-16 00:33:45.283 INFO task: buy apple
2025-01-16 00:33:45.283 INFO Transaction 'operations.Add'
2025-01-16 00:33:45.284 INFO task: buy orange
examples.unit_test.todo_list.test_todo
TestToTestCase
test_list_tasks_many_assertions2025-01-16 00:33:45.284 INFO Transaction 'operations.ListTasks'
2025-01-16 00:33:45.284 INFO Assertion 'HasSubset'
2025-01-16 00:33:45.284 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:33:45.284 INFO expected: '['buy cheese', 'buy orange']'
2025-01-16 00:33:45.284 INFO Assertion 'IsSortedAs'
2025-01-16 00:33:45.284 INFO actual: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:33:45.284 INFO expected: '['buy cheese', 'buy apple', 'buy orange']'
2025-01-16 00:33:45.284 INFO Transaction 'operations.PrintDict'
2025-01-16 00:33:45.284 INFO Assertion 'HasKeyValue'
2025-01-16 00:33:45.284 INFO actual: '{'1': 'buy cheese', '2': 'buy apple', '3': 'buy orange'}'
2025-01-16 00:33:45.285 INFO expected: '{'1': 'buy cheese'}'
2025-01-16 00:33:45.285 INFO Transaction 'operations.Add'
2025-01-16 00:33:45.285 INFO task: buy watermelon
2025-01-16 00:33:45.285 INFO Transaction 'operations.GetBy'
2025-01-16 00:33:45.285 INFO index: 3
2025-01-16 00:33:45.285 INFO Assertion 'MatchesRegex'
2025-01-16 00:33:45.285 INFO actual: 'buy watermelon'
2025-01-16 00:33:45.285 INFO expected: '(.*)melon'
. test_list_tasks_many_assertions
Ran 2 tests in 0.059s using 4 processes
OK (passes=2)
Coverage
python -m coverage run -m pytest -k test_calculator.py
Output
~/guara/venv/lib/python3.11/site-packages/pytest_asyncio/plugin.py:207: PytestDeprecationWarning: The configuration option "asyncio_default_fixture_loop_scope" is unset.
The event loop scope for asynchronous fixtures will default to the fixture caching scope. Future versions of pytest-asyncio will default the loop scope for asynchronous fixtures to function scope. Set the default fixture loop scope explicitly in order to avoid unexpected behavior in the future. Valid fixture loop scopes are: "function", "class", "module", "package", "session"
warnings.warn(PytestDeprecationWarning(_DEFAULT_FIXTURE_LOOP_SCOPE_UNSET))
============================================================ test session starts =============================================================
platform linux -- Python 3.11.9, pytest-8.3.4, pluggy-1.5.0
rootdir: ~/guara
configfile: pytest.ini
plugins: playwright-0.6.2, base-url-2.1.0, asyncio-0.25.1, xdist-3.6.1
asyncio: mode=Mode.STRICT, asyncio_default_fixture_loop_scope=None
collected 40 items / 36 deselected / 4 selected
examples/unit_test/calculator/test_calculator.py ....
Generate HTML
coverage html
Output
Wrote HTML report to htmlcov/index.html
