This is a quick post about the end_test cocotb function. It terminates the test when called from any coroutine. The main observation is that it respects xfail, as the documentation mentions.
end_test Link to heading
From src/cocotb/_test_manager.py, the doc pretty much sums it up as follows:
def end_test(msg: str | None = None) -> NoReturn:
"""End a test.
The test will end after this function is called as if it passed.
However, any :deco:`cocotb.xfail` decorators
or ``expect_error`` and ``expect_fail`` arguments to :func:`cocotb.test` will be respected.
Meaning, if they are used, the test will fail, as a failure was expected.
Args:
msg: The message to display when the test ends.
"""
raise EndTest(msg)
@cocotb.test()
async def test_end_test(dut):
""" Finished with end_test() """
cocotb.log.info("Starting test")
cocotb.start_soon(coroutine_assert())
await Timer(40, unit="ns")
cocotb.log.info("Finished waiting for 40 ns")
end_test()
cocotb.log.info("Test completed")
@cocotb.test()
@cocotb.xfail(reason="unsupport feature")
async def test_end_test_xfail(dut):
""" Finished with end_test() """
cocotb.log.info("Starting test")
cocotb.start_soon(coroutine_assert())
await Timer(40, unit="ns")
cocotb.log.info("Finished waiting for 100 ns")
end_test()
cocotb.log.info("Test completed")
For these tests, the first one passes as expected, but the second one fails due to xfail.
620.00ns INFO cocotb.regression running tests.test_end_test (5/17)
Finished with end_test()
620.00ns INFO test Starting test
630.00ns INFO test Monitoring... 0
640.00ns INFO test Monitoring... 1
650.00ns INFO test Monitoring... 2
660.00ns INFO test Finished waiting for 40 ns
660.00ns INFO cocotb.task.Test test_end_test Test stopped early by this task
660.00ns INFO cocotb.regression tests.test_end_test passed
660.00ns INFO cocotb.regression running tests.test_end_test_xfail (6/17)
Finished with end_test()
660.00ns INFO test Starting test
670.00ns INFO test Monitoring... 0
680.00ns INFO test Monitoring... 1
690.00ns INFO test Monitoring... 2
700.00ns INFO test Finished waiting for 100 ns
700.00ns INFO ..tb.task.Test test_end_test_xfail Test stopped early by this task
700.00ns WARNING cocotb.regression tests.test_end_test_xfail failed: passed but we expected a failure
pass_test Link to heading
pass_test was deprecated as it’s not a good idea to force a test to pass. It is mentioned here for completeness.
def pass_test(msg: str | None = None) -> NoReturn:
"""Force a test to pass.
The test will end after this function is called.
The outcome of the test will be forced to pass,
even if a :deco:`cocotb.xfail` decorator is used,
or ``expect_error`` and ``expect_fail`` arguments to :deco:`cocotb.test` are passed.
Args:
msg: The message to display when the test passes.
.. versionadded:: 2.0
.. deprecated:: 2.1
Forcing a test to pass is considered bad practice.
Use :func:`cocotb.skip` if you want to end the test immediately and force the outcome to 'skipped'.
Or use :func:`cocotb.end_test` if you want to end the test immediately while respecting expected failures.