Skip to content

TEST: Add unit tests for pyrit/common/ utilities#1600

Open
romanlutz wants to merge 3 commits intomicrosoft:mainfrom
romanlutz:test/common-coverage
Open

TEST: Add unit tests for pyrit/common/ utilities#1600
romanlutz wants to merge 3 commits intomicrosoft:mainfrom
romanlutz:test/common-coverage

Conversation

@romanlutz
Copy link
Copy Markdown
Contributor

Summary

Adds unit tests for 10 previously untested utility files in pyrit/common/.

New Test Files

Source File Tests Coverage
apply_defaults.py 22 Sentinel, scope hashing, registry CRUD, decorator with inheritance
csv_helper.py 5 Read/write/roundtrip
data_url_converter.py 4 Supported formats, errors, data URL output
deprecation.py 4 Warnings with callables, classes, strings, mixed
display_response.py 5 Notebook skip, blocked response, image read/display
path.py 14 Path constants, in_git_repo, get_default_data_path
question_answer_helpers.py 3 Prompt formatting
singleton.py 3 Identity, distinct classes, init preservation
utils.py 7 combine_list, to_sha256
yaml_loadable.py 4 Basic load, from_dict dispatch, error cases

Testing

All 71 tests pass locally.

romanlutz and others added 3 commits April 11, 2026 18:04
Adds tests for 10 previously untested utility files:
- apply_defaults.py (decorator, sentinel, registry)
- csv_helper.py (read/write/roundtrip)
- data_url_converter.py (format support, encoding)
- deprecation.py (warnings for callables, classes)
- display_response.py (notebook skip, image display)
- path.py (constants, git_repo detection, default paths)
- question_answer_helpers.py (prompt formatting)
- singleton.py (identity, distinct classes)
- utils.py (combine_list, to_sha256)
- yaml_loadable.py (basic load, from_dict, errors)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
# Conflicts:
#	tests/unit/common/test_csv_helper.py
@rlundeen2 rlundeen2 self-assigned this Apr 14, 2026
@rlundeen2 rlundeen2 requested a review from Copilot April 14, 2026 18:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds missing unit coverage for pyrit/common/ utilities by introducing new pytest tests across multiple helper modules.

Changes:

  • Added unit tests for YAML loading (YamlLoadable), hashing/list utilities, singleton metaclass behavior, and prompt construction helpers.
  • Added unit tests for filesystem/path constants/helpers, image display behavior, deprecation warnings, CSV read/write helpers, and data-url conversion.
  • Introduced fixtures and mocking for async I/O and notebook-dependent behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/unit/common/test_apply_defaults.py Covers default registry behavior and @apply_defaults decorator scenarios
tests/unit/common/test_csv_helper.py Adds coverage for CSV read/write and roundtrip behavior
tests/unit/common/test_data_url_converter.py Adds coverage for supported formats, errors, and data URL output
tests/unit/common/test_deprecation.py Validates warning emission/message contents across input types
tests/unit/common/test_display_response.py Tests notebook gating, blocked content logging, and image display flow with mocks
tests/unit/common/test_path.py Tests path constants plus in_git_repo / get_default_data_path
tests/unit/common/test_question_answer_helpers.py Validates evaluation prompt formatting for Q/A entries
tests/unit/common/test_singleton.py Tests singleton identity, class separation, and init-arg preservation
tests/unit/common/test_utils.py Tests list-combining behavior and SHA256 determinism/known value
tests/unit/common/test_yaml_loadable.py Tests YAML load success paths plus missing/invalid file error behavior

Comment on lines +56 to +61
def test_db_data_path_exists():
assert DB_DATA_PATH.exists()


def test_log_path_exists():
assert LOG_PATH.exists()
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions make the test suite depend on the executing machine’s filesystem state (and possibly on import-time side effects that create these paths). This can be flaky in clean CI containers or when the package is installed in environments that don’t pre-create these directories. Prefer asserting properties that are stable (e.g., that the paths are absolute / under an expected base) or explicitly creating the directories in the test setup (or patching the base directory to a tmp_path) depending on the intended contract of pyrit.common.path.

Suggested change
def test_db_data_path_exists():
assert DB_DATA_PATH.exists()
def test_log_path_exists():
assert LOG_PATH.exists()
def test_db_data_path_is_absolute():
assert DB_DATA_PATH.is_absolute()
def test_log_path_is_absolute():
assert LOG_PATH.is_absolute()

Copilot uses AI. Check for mistakes.
@pytest.mark.asyncio
@patch("pyrit.common.display_response.is_in_ipython_session", return_value=True)
@patch("pyrit.common.display_response.Image")
@patch("builtins.display", create=True)
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patching builtins.display is fragile because the implementation may call display via a module import (e.g., IPython.display.display) or a symbol imported into pyrit.common.display_response, in which case this patch won’t intercept the call (and the test may become environment-dependent). Patch the display symbol in the namespace where it’s used (e.g., pyrit.common.display_response.display) to make the test deterministic.

Suggested change
@patch("builtins.display", create=True)
@patch("pyrit.common.display_response.display")

Copilot uses AI. Check for mistakes.
Comment on lines +13 to +18
a = _MySingleton()
b = _MySingleton()
assert a is b

# Cleanup to avoid polluting other tests
Singleton._instances.pop(_MySingleton, None)
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cleanup relies on reaching into Singleton._instances and it won’t run if the test fails before the cleanup line (potentially polluting other tests). Consider moving this cleanup into a fixture/finalizer (or a try/finally) so state is always reset even on assertion failures, and to reduce coupling to the metaclass’s internal storage details.

Copilot uses AI. Check for mistakes.

def test_from_yaml_file_nonexistent_raises():
with pytest.raises(FileNotFoundError):
_SimpleYaml.from_yaml_file("nonexistent_file.yaml")
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other tests in this file pass a Path, but this one passes a string literal. If from_yaml_file is intended to accept Path objects, using Path("nonexistent_file.yaml") here would keep the tests consistent and avoid ambiguity about supported input types.

Suggested change
_SimpleYaml.from_yaml_file("nonexistent_file.yaml")
_SimpleYaml.from_yaml_file(Path("nonexistent_file.yaml"))

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@rlundeen2 rlundeen2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the copilot review suggestions, but no blockers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants