Files
darth-veitcher-comfydv/tests
3322f6f05e feat: standardise logging across all comfydv nodes (#5)
* chore: initialise BEACON framework with all bootstrap artefacts

- Problem statement, constitution, architecture doc, roadmap populated
- CHANGELOG.md created (Keep a Changelog); README expanded with
  What-is-this, Install, and Quickstart sections
- pyproject.toml gains [project.urls] (repository + documentation)
- beacon doctor: 32 pass, 2 pre-commit warns, 0 failures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: Phase 1 — add NullHandler to package root, remove hardcoded setLevel

T001: logging.getLogger("comfydv").addHandler(NullHandler()) in __init__.py
T002: remove logger.setLevel(logging.DEBUG) from format_string.py
Also fix pyproject.toml TOML structure (project.urls was inside [project] block)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: failing tests for logging modernisation (T010-T through T030-T)

RED phase — 5 tests fail for the correct reasons before implementation:
T010-T: format_string produces stdout (print block)
T011-T: update_widget emits INFO records on hot path
T012-T: random_choice produces stdout (colorama/rich prints)
T020-T: load_node_state uses print() on error instead of logger.error
T021-T: circuit_breaker uses print() instead of logger

T001/T002/T030-T already green: NullHandler registered, setLevel removed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat: standardise logging across all nodes (T010-I through T044)

GREEN phase — all 11 logging tests pass:

T010-I: Remove 8-line diagnostic print block from format_string()
T011-I: Downgrade all hot-path logger.info() calls to logger.debug();
        switch all logger calls to %-style formatting; remove rich import
T012-I: Replace colorama/termcolor/rich print calls in random_choice with
        logger.debug(); add logger = logging.getLogger(__name__)
T020-I: Convert print() on load_node_state error to logger.error()
T021-I: Add logger to circuit_breaker; replace print() with logger.debug();
        fix logic so status=False triggers the interrupt (per BDD spec)
T040:   Remove colorama, rich, termcolor from pyproject.toml dependencies
T042:   ruff check + format clean
T044:   beacon doctor --strict passes (34/34)

Also adds ADR-001 and ADR-002 capturing the stdlib logging and NullHandler
decisions, linked from the logging-modernisation epic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: mark all 001-standardise-logging tasks complete in tasks.md

All [x] checkboxes flipped after 11/11 tests pass and beacon doctor --strict
reports 0 failures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: mark logging-modernisation epic success criteria complete

All success criteria verified: NullHandler added, setLevel removed, print()
calls converted, colorama/rich/termcolor removed from deps, zero stdout in
normal operation, errors surface at ERROR level, all tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* chore: commit spec artefacts and dependency lock for 001-standardise-logging

Includes spec.md, plan.md, research.md, BDD feature files, contracts, .beacon.toml
backlink, and uv.lock after removing colorama/rich/termcolor.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: James Veitch <darthveitcher@office-mac-mini.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 16:00:43 +01:00
..
2025-11-05 12:54:02 +00:00

Tests

This directory contains comprehensive pytest tests for the comfydv package.

Running Tests

# Run all tests
uv run pytest

# Run with verbose output
uv run pytest -v

# Run with coverage report
uv run pytest --cov=src/comfydv --cov-report=html

# Run specific test file
uv run pytest tests/test_format_string.py

# Run specific test class
uv run pytest tests/test_format_string.py::TestVariableExtraction

# Run specific test
uv run pytest tests/test_format_string.py::TestVariableExtraction::test_extract_simple_single_variable

# Run tests matching a pattern
uv run pytest -k "jinja2"

Coverage reports are available in htmlcov/index.html after running with --cov-report=html.

Test Coverage

Current: 75% (203 statements total, 51 missed)

  • format_string.py: 78% coverage
  • __init__.py: 100% coverage
  • circuit_breaker.py: 68% coverage
  • random_choice.py: 60% coverage
  • utils.py: 75% coverage

Test Structure

conftest.py

Contains pytest configuration, fixtures, and mocks for ComfyUI dependencies:

  • Mock ComfyUI modules (comfy, server, folder_paths, aiohttp)
  • Uses pytest_configure hook to install mocks before test collection
  • Provides format_string_class fixture using importlib to directly load module
  • Fixtures for test data and class instances
  • Pytest hooks for early mock installation

test_format_string.py

Comprehensive test suite for the FormatString node with 47 tests organized into classes:

  • TestVariableExtraction (12 tests): Variable extraction from templates
  • TestSimpleFormatting (4 tests): Python format string rendering
  • TestJinja2Formatting (5 tests): Jinja2 template rendering
  • TestDynamicOutputs (6 tests): Dynamic output configuration
  • TestOutputConsistency (3 tests): Outputs match RETURN_TYPES/RETURN_NAMES
  • TestInputTypes (4 tests): INPUT_TYPES method validation
  • TestIsChanged (5 tests): Cache invalidation logic
  • TestStatePersistence (2 tests): State saving/loading
  • TestEdgeCases (4 tests): Error handling and edge cases
  • TestTimeNowFunction (2 tests): time_now utility function

Mocking Strategy

The tests use importlib.util to directly load the format_string.py module, bypassing the package __init__.py which has ComfyUI dependencies. This allows testing without ComfyUI installation while maintaining the root __init__.py for ComfyUI extension discovery.

Writing Tests

Example test

def test_new_feature(self, format_string_class, sample_data):
    """Test that new feature works correctly."""
    result = format_string_class.some_method(sample_data["name"])
    assert result == expected_value

Available fixtures

  • format_string_class: Fresh FormatString class with reset state
  • sample_templates: Dictionary of sample template strings
  • sample_data: Dictionary of sample data for templates

Test naming convention

Use descriptive names: test_<what>_<condition>_<expected>

Troubleshooting

Debugging failed tests

# Run with verbose output
uv run pytest -vv --tb=long

# Run with pdb debugger
uv run pytest --pdb

Test isolation

Each test is independent. The format_string_class fixture provides a fresh instance with reset state.

Future Improvements

  • Add integration tests with actual ComfyUI installation
  • Add JavaScript tests for frontend functionality
  • Increase coverage for circuit_breaker and random_choice nodes
  • Add property-based testing with Hypothesis