# Supported Framework

## Supported Frameworks

Use this page to run your Python tests under the SeaLights agent so test execution and per-test coverage are reported to SeaLights. The agent wraps your existing test framework — **no test code changes are required**.

This page covers the three frameworks most teams integrate in 2026: **pytest**, **unittest**, and **behave**.

{% hint style="info" %}
If you are looking for how to instrument the **Application Under Test (AUT)** so it reports coverage at runtime (e.g., Flask, FastAPI, Django, uWSGI, Gunicorn), see Running Backend Server Using SeaLights Agent. For functional / integration / E2E tests, you will use both pages.&#x20;
{% endhint %}

### How the Python agent fits in

The Python agent plays one of two roles depending on the test type, mapping to the two SeaLights Agent Usage Modes:

| Scenario                           | What you instrument                                                  | Coverage source         | Test execution source   |
| ---------------------------------- | -------------------------------------------------------------------- | ----------------------- | ----------------------- |
| **Unit / in-process tests**        | The test framework (this page)                                       | The test process itself | The test process itself |
| **Functional / integration / E2E** | The test framework (this page) **and** the AUT (backend-server page) | The running AUT         | The test framework      |

In SeaLights terminology, `sl-python <framework>` runs the Python agent in **Test Runner Mode**. For functional tests, the AUT runs separately in **Coverage Listener Mode,** and the two share a Lab ID so SeaLights can correlate test events with coverage footprints.

***

### Prerequisites

Before running the commands below, ensure you have:

1. **An agent token.** See Generating an Agent Token. Treat the token as a secret — the snippets on this page read it from a `SL_TOKEN` environment variable rather than checking it in.
2. **A Lab ID** for the environment under test. Lab IDs are how SeaLights groups a test run with the build under test. The snippets read it from a `SL_LABID` environment variable so the same pipeline can target multiple environments.
3. **A scanned build** for the code under test. See Scanning a Build.
4. **The agent installed** in the Python environment that runs your tests: `pip install sealights-python-agent`.
5. **For functional / integration / E2E tests only:** the AUT is already running and instrumented. See Running Backend Server Using SeaLights Agent.

### Per-framework usage

Frameworks are listed in order of common usage in 2026. New integrations should default to **pytest** unless an existing test suite dictates otherwise.

{% hint style="info" %}
**Legacy frameworks (unittest2, nose).** `sl-python` retains subcommands for `unit2` (unittest2) and `nose` for backward compatibility. Both upstream projects are no longer actively maintained, and we recommend migrating to pytest or unittest. For exact usage of the legacy subcommands, run `sl-python --help` or `sl-python <unit2|nose> --help`.&#x20;
{% endhint %}

#### pytest

The de facto standard for Python testing. Use for unit tests, API tests, and most automated test suites.

{% hint style="danger" %}
The SeaLights agent conflicts with pytest's `--cov` option. Remove `--cov` from your command line and from any `pytest.ini` / `pyproject.toml` / `setup.cfg` when running under `sl-python`.&#x20;
{% endhint %}

{% hint style="warning" %}
If `pytest-cov` is in your project at a version older than the one `sl-python` requires, coverage collection will fail. Remove `pytest-cov` from your dependencies — `sl-python` installs a compatible version automatically.
{% endhint %}

{% tabs %}
{% tab title="Bash" %}

```bash
export SL_TOKEN="<your-sealights-agent-token>"
export SL_LABID="my_app_env"

sl-python pytest \
  --token "$SL_TOKEN" \
  --labid "$SL_LABID" \
  --teststage "Unit Tests" \
  --cov-report ./reports/coverage.xml \
  tests/
```

{% endtab %}

{% tab title="GitHub Actions" %}

```yaml
- name: Run pytest with SeaLights
  shell: bash
  env:
    SL_TOKEN: ${{ secrets.SEALIGHTS_AGENT_TOKEN }}
    SL_LABID: ${{ vars.SEALIGHTS_LAB_ID }}
  run: |
    pip install sealights-python-agent
    sl-python pytest \
      --token "$SL_TOKEN" \
      --labid "$SL_LABID" \
      --teststage "Unit Tests" \
      --cov-report ./reports/coverage.xml \
      tests/
```

{% endtab %}

{% tab title="PowerShell" %}

```powershell
$env:SL_TOKEN = "<your-sealights-agent-token>"
$env:SL_LABID = "my_app_env"

sl-python pytest `
  --token $env:SL_TOKEN `
  --labid $env:SL_LABID `
  --teststage "Unit Tests" `
  --cov-report .\reports\coverage.xml `
  tests\
```

{% endtab %}
{% endtabs %}

#### unittest

Python's built-in testing framework. Use when stdlib-only constraints apply, or for legacy suites not yet migrated to pytest.

{% tabs %}
{% tab title="Bash" %}

```bash
export SL_TOKEN="<your-sealights-agent-token>"
export SL_LABID="my_app_env"

sl-python unittest \
  --token "$SL_TOKEN" \
  --labid "$SL_LABID" \
  --teststage "Unit Tests" \
  --cov-report ./reports/coverage.xml \
  discover -s tests
```

{% endtab %}

{% tab title="GitHub Actions" %}

```yaml
- name: Run unittest with SeaLights
  shell: bash
  env:
    SL_TOKEN: ${{ secrets.SEALIGHTS_AGENT_TOKEN }}
    SL_LABID: ${{ vars.SEALIGHTS_LAB_ID }}
  run: |
    pip install sealights-python-agent
    sl-python unittest \
      --token "$SL_TOKEN" \
      --labid "$SL_LABID" \
      --teststage "Unit Tests" \
      --cov-report ./reports/coverage.xml \
      discover -s tests
```

{% endtab %}

{% tab title="PowerShell" %}

```powershell
$env:SL_TOKEN = "<your-sealights-agent-token>"
$env:SL_LABID = "my_app_env"

sl-python unittest `
  --token $env:SL_TOKEN `
  --labid $env:SL_LABID `
  --teststage "Unit Tests" `
  --cov-report .\reports\coverage.xml `
  discover -s tests
```

{% endtab %}
{% endtabs %}

#### behave

BDD framework for Python, used for functional and acceptance tests written in Gherkin and typically paired with a separately instrumented AUT.

{% hint style="info" %}
For Behave, the AUT is almost always a separate running service. Make sure it is already instrumented per the backend-server page, and that both sides use the **same** `--labid`.&#x20;
{% endhint %}

{% tabs %}
{% tab title="Bash" %}

```bash
export SL_TOKEN="<your-sealights-agent-token>"
export SL_LABID="my_app_env"

sl-python behave \
  --token "$SL_TOKEN" \
  --labid "$SL_LABID" \
  --teststage "Functional Tests" \
  features/
```

{% endtab %}

{% tab title="GitHub Actions" %}

```yaml
- name: Run Behave with SeaLights
  shell: bash
  env:
    SL_TOKEN: ${{ secrets.SEALIGHTS_AGENT_TOKEN }}
    SL_LABID: ${{ vars.SEALIGHTS_LAB_ID }}
  run: |
    pip install sealights-python-agent
    sl-python behave \
      --token "$SL_TOKEN" \
      --labid "$SL_LABID" \
      --teststage "Functional Tests" \
      features/
```

{% endtab %}

{% tab title="PowerShell" %}

```powershell
$env:SL_TOKEN = "<your-sealights-agent-token>"
$env:SL_LABID = "my_app_env"

sl-python behave `
  --token $env:SL_TOKEN `
  --labid $env:SL_LABID `
  --teststage "Functional Tests" `
  features\
```

{% endtab %}
{% endtabs %}

***

### Common parameters

All `sl-python <framework>` subcommands accept the following parameters unless noted otherwise.

{% hint style="warning" %}
**Deprecated:** `--buildsessionid` and `--buildsessionidfile` are deprecated in favor of `--labid`. They still work for backward compatibility, but new integrations should use `--labid`.&#x20;
{% endhint %}

<table><thead><tr><th width="215.3333740234375">Parameter</th><th width="121">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>--token</code></td><td>string</td><td>SeaLights agent token. Mandatory unless <code>--tokenfile</code> is used. Case-sensitive.</td></tr><tr><td><code>--tokenfile</code></td><td>path</td><td>Path to a file containing the token. Case-sensitive.</td></tr><tr><td><code>--labid</code></td><td>string</td><td>Lab ID for the target environment. Case-sensitive.</td></tr><tr><td><code>--teststage</code></td><td>string</td><td>Human-readable name of the test stage, e.g. <code>Unit Tests</code>, <code>Integration Tests</code>, <code>Regression</code>. Appears in the SeaLights UI.</td></tr><tr><td><code>--cov-report</code></td><td>path</td><td>Path where the agent writes the coverage XML report.</td></tr><tr><td><code>--per-test</code></td><td>boolean</td><td>Capture per-test coverage. Default: <code>true</code>. <em>(pytest, unittest)</em></td></tr><tr><td><code>--interval</code></td><td>int (ms)</td><td>Footprint flush interval. Default: <code>10000</code>. <em>(pytest)</em></td></tr><tr><td><code>-tsd</code>, <code>--test-selection-disable</code></td><td>flag</td><td>Disable Test Optimization for this run. <em>(pytest)</em></td></tr><tr><td><code>-tsri</code>, <code>--test-selection-retry-interval</code></td><td>int (sec)</td><td>Retry interval when fetching the exclusion list. Default: <code>5</code>. <em>(pytest)</em></td></tr><tr><td><code>-tsrt</code>, <code>--test-selection-retry-timeout</code></td><td>int (sec)</td><td>Total timeout for fetching the exclusion list. Default: <code>60</code>. <em>(pytest)</em></td></tr></tbody></table>

### Troubleshooting

**`tests must run for at least 1 second for SeaLights to calculate coverage`** SeaLights samples footprints periodically. If a test process completes in under one second, the sampler may not capture anything. For very fast unit-test suites, add a short delay at the end of the run, or batch tests so total wall time exceeds one second.

**`token is required` / authentication errors** Verify the `SL_TOKEN` environment variable is set in the shell that runs `sl-python`, and that it resolves to a valid, non-expired token. In CI, confirm the secret is bound to the job (e.g. that the `env:` block at job/step scope references the right secret name).

**No coverage appears in SeaLights for functional tests** The Lab ID on `sl-python <framework>` must match the Lab ID configured on the running AUT. If they don't match, test events and coverage footprints land in different buckets and cannot be correlated. Verify both sides are using the same `--labid`.

**`pytest-cov` version conflict** If `pytest-cov` is in your project's dependency lock at a version older than `sl-python` requires, the agent fails to attach. Remove `pytest-cov` from your project's direct dependencies — `sl-python` installs a compatible version itself.

**Conflicting coverage flags on pytest** Remove `--cov` from your test command and from any config file (`pytest.ini`, `pyproject.toml`, `setup.cfg`). The SeaLights agent provides its own coverage collection and cannot share the process with another collector.

**Tests run but no test stage opens in SeaLights.** Check that `--teststage` is provided and that the agent has network access to the SeaLights server. Enable agent logs to confirm the test session lifecycle messages.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sealights.io/knowledgebase/setup-and-configuration/sealights-agents-and-plugins/python-agent/running-tests/supported-framework.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
