Metadata-Version: 2.4
Name: cocotest
Version: 0.1.0
Summary: Lightweight, opinionated test orchestration framework for cocotb.
Author: Pierre-Louis Nordmann
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Topic :: Software Development :: Testing
Requires-Dist: cocotb~=2.0.1
Requires-Dist: psutil>=7.2.2
Requires-Python: >=3.11
Project-URL: Homepage, https://github.com/p-nordmann/cocotest
Project-URL: Repository, https://github.com/p-nordmann/cocotest
Project-URL: Issues, https://github.com/p-nordmann/cocotest/issues
Description-Content-Type: text/markdown

# cocotest

Lightweight, opinionated test orchestration framework for cocotb.

## Quickstart

Cocotest is intended to work in similar fashion to pytest.
We do not intend to provide as many features as pytest, far from it, but we take a lot of inspiration from it.
Cocotest should feel familiar for developers with experience in the Python ecosystem.

### Installation

You can install cocotest using pip or uv:

```sh
pip install cocotest

# Or with uv:
uv add cocotest
```

### Getting started

Once cocotest is installed, you can run your tests with the following command:

```sh
cocotest /path/to/tests

# Or with uv:
uv run cocotest /path/to/tests
```

Of course, you need to write your tests in such a way that cocotest knows what to do with them:

```Python
from cocotb.handle import HierarchyObject

from cocotest import DUTSpec

dut = DUTSpec(
    simulator="ghdl",
    sources=["testbench/heartbeat/heartbeat.vhd"],
    hdl_toplevel="heartbeat",
    lang="vhdl",
    build_args=["--std=08"],
    test_args=["--std=08"],
)


async def test_heartbeat_pass(dut: HierarchyObject):
    print("Inside test: test_heartbeat_pass")
    pass
```

Here there are two important things:

- `dut = DUTSpec(...)`: this is where we tell cocotest about the DUT that we will use, so it knows how to launch cocotb;
- `async def test_heartbeat_pass(dut: HierarchyObject)`: here we declare a test.

There are 3 conditions for our test to be detected by cocotest:

- `async def`: the test function must be asynchronous, as it will be run inside cocotb and manipulate the DUT;
- `test_...`: its name must start with "test\_" so cocotest knows how to find it;
- `dut`: its DUT argument for the cocotb test must have the same name as some `DUTSpec` instance present in the scope. This way, cocotest will know what cocotb test to launch with which DUT.

And... that's it! Just use the `cocotest` command and your test will run.
No need for fancy makefiles, no need for `@cocotb.test`; you can now define various DUTs to use in various test cases which will be automatically run by cocotest. :)

## Contributing

Before contributing, read [CONTRIBUTING.md](./CONTRIBUTING.md).

Note: contributions are closed for the moment.

## Testing cocotest

Cocotest is made for running cocotb tests, but it must itself be tested so we know it works.
For this, we rely on good old pytest.

### A word about test dependencies

Most of the tests can be run with the dev dependencies from the uv project.
However, some tests will try to spawn a cocotest subprocess.
With this cocotest call, they will try to run ghdl.
For that reason, you need to install ghdl if you want to be able to run all of the tests.

### Running the tests

Once you have all the dependencies installed, you can run the tests using pytest:

```sh
pytest tests

# Or with uv:
uv run pytest tests
```

## License

This work is distributed under the MIT license, see the LICENSE file for more information.
