Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions .github/workflows/pytest-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
name: Pytest Tests For Development

on:
workflow_dispatch:
pull_request:
branches:
- main
push:
branches:
- main

jobs:
test:
strategy:
matrix:
include:
- os: windows-latest
python-version: 3.11
- os: ubuntu-latest
python-version: 3.11

runs-on: ${{ matrix.os }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Install uv (Linux/macOS)
if: runner.os != 'Windows'
run: curl -LsSf https://astral.sh/uv/install.sh | sh

- name: Install uv (Windows)
if: runner.os == 'Windows'
run: |
python -m pip install uv

- name: Install dependencies (Linux/macOS)
if: runner.os != 'Windows'
run: |
uv venv .venv
source .venv/bin/activate
uv sync --no-install-project --group test --group dev

- name: Install dependencies (Windows)
if: runner.os == 'Windows'
run: |
uv venv .venv
.venv\Scripts\activate
uv sync --no-install-project --group test --group dev

- name: Run pytest tests (Linux/macOS)
if: runner.os != 'Windows'
run: |
source .venv/bin/activate
uv run pytest tests/test_01_message_pytest.py -v --cov=hololinked --cov-report=term-missing

- name: Run pytest tests (Windows)
if: runner.os == 'Windows'
run: |
.venv\Scripts\activate
uv run pytest tests/test_01_message_pytest.py -v --cov=hololinked --cov-report=term-missing

- name: Upload coverage report as artifact
uses: actions/upload-artifact@v4
if: runner.os != 'Windows'
with:
name: pytest-coverage-report-ubuntu-latest-py3.11
path: coverage.xml
if-no-files-found: warn

publish:
name: Publish coverage (disabled for pytest per issue #107)
needs: test
runs-on: ubuntu-latest
if: ${{ false }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Download Ubuntu 3.11 coverage artifact
id: dl
uses: actions/download-artifact@v4
with:
name: pytest-coverage-report-ubuntu-latest-py3.11
path: .
continue-on-error: true

- name: Upload coverage to Codecov (disabled)
if: false
uses: codecov/codecov-action@v4
with:
files: coverage.xml

- name: Skip note (coverage upload disabled for pytest)
run: echo "Skipping Codecov upload in pytest workflow per issue #107."
24 changes: 23 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,30 @@ test = [
"numpy>=2.0.0",
"faker==37.5.0",
"bcrypt==4.3.0",
"fastjsonschema==2.20.0"
"fastjsonschema==2.20.0",
"pytest>=8.0.0",
"pytest-cov>=4.0.0",
"pytest-order>=1.0.0"
]
linux = [
"uvloop==0.20.0"
]

[tool.pytest.ini_options]
minversion = "8.0"
addopts = "-ra --strict-markers --strict-config"
testpaths = ["tests/pytest"]
python_files = ["test_*_pytest.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
markers = [
"order: mark test to run in a specific order",
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: marks tests as integration tests"
]
filterwarnings = [
"error",
"ignore::UserWarning",
"ignore::DeprecationWarning",
"ignore::pytest.PytestCollectionWarning"
]
66 changes: 66 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""
Pytest configuration and shared fixtures for hololinked tests.
"""
import asyncio
import pytest
import zmq.asyncio
from uuid import uuid4
from faker import Faker

from hololinked.config import global_config


@pytest.fixture(scope="session")
def event_loop():
"""Create an instance of the default event loop for the test session."""
loop = asyncio.get_event_loop_policy().new_event_loop()
yield loop
loop.close()


@pytest.fixture(scope="class")
def zmq_context():
"""Setup ZMQ context for test classes."""
global_config.ZMQ_CONTEXT = zmq.asyncio.Context()
yield global_config.ZMQ_CONTEXT
# Cleanup is handled by the context manager


@pytest.fixture(scope="class")
def test_ids():
"""Generate unique test IDs for each test class."""
return {
"server_id": f"test-server-{uuid4().hex[:8]}",
"client_id": f"test-client-{uuid4().hex[:8]}",
"thing_id": f"test-thing-{uuid4().hex[:8]}"
}


@pytest.fixture(scope="session")
def fake():
"""Provide a Faker instance for generating test data."""
return Faker()


@pytest.fixture(autouse=True)
def setup_test_environment(zmq_context):
"""Automatically setup test environment for each test."""
# This fixture runs automatically for every test
pass


def pytest_configure(config):
"""Configure pytest with custom settings."""
config.addinivalue_line(
"markers", "order: mark test to run in a specific order"
)


def pytest_collection_modifyitems(config, items):
"""Modify test collection to add ordering markers."""
# Add order markers based on test file names
for item in items:
if "test_01_" in item.nodeid:
item.add_marker(pytest.mark.order(1))
elif "test_00_" in item.nodeid:
item.add_marker(pytest.mark.order(0))
Loading
Loading