Files
gitea-agent/harness/tests/common/evidence/test_pytest_evidence_recipe.py

87 lines
4.2 KiB
Python

"""Conditional pytest recipe: documentation contract and real synthetic execution.
Run with an independently admitted pytest interpreter for execution coverage.
No dependency installation occurs in this test or the production workflow.
"""
from harness.tests._support.paths import ROOT as SOURCE_ROOT
import importlib.util
import json
import os
from pathlib import Path
from harness.tests._support.contracts import read_contract
import subprocess
import sys
import tempfile
import unittest
ROOT = SOURCE_ROOT
SKILL = ROOT / 'harness/agents/impl/skills/gitea-issue-rework/SKILL.md'
HEADING = '### Conditional pytest evidence recipe'
class PytestEvidenceRecipeTests(unittest.TestCase):
def recipe(self):
text = read_contract(SKILL)
self.assertIn(HEADING, text, 'conditional pytest recipe is missing')
section = text.split(HEADING, 1)[1].split('\n### ', 1)[0]
return section, json.loads(section.split('```json\n', 1)[1].split('\n```', 1)[0])
def test_documentation_contract_limits_recipe_to_existing_pytest_projects(self):
section, argv = self.recipe()
for rule in ['PYTEST_ADDOPTS', 'plugin', 'evidence_gap', 'timeout', 'output_limit']:
self.assertIn(rule, section)
self.assertIsInstance(argv, list)
self.assertEqual(argv[:4], ['{python}', '-B', '-m', 'pytest'])
@unittest.skipUnless(importlib.util.find_spec('pytest'), 'admitted pytest interpreter required')
def test_real_recipe_preserves_pass_skip_warning_summary_under_quiet_project_config(self):
_, argv = self.recipe()
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
(root / 'pytest.ini').write_text('[pytest]\naddopts = -qq\n')
(root / 'test_sample.py').write_text(
'import pytest, warnings\n'
'def test_pass():\n warnings.warn("synthetic warning", UserWarning)\n'
'@pytest.mark.skip(reason="synthetic skip")\ndef test_skip():\n pass\n')
control = self.invoke([sys.executable, '-B', '-m', 'pytest', 'test_sample.py'], root)
self.assertEqual(control['status'], 'completed')
self.assertEqual(control['exit_code'], 0)
self.assertNotIn('1 passed', control['output'])
actual = self.invoke(self.expand(argv), root)
self.assertEqual(actual['status'], 'completed')
self.assertEqual(actual['exit_code'], 0)
self.assertRegex(actual['output'], r'1 passed, 1 skipped, 1 warning')
self.assertNotIn('\x1b[', actual['output'])
@unittest.skipUnless(importlib.util.find_spec('pytest'), 'admitted pytest interpreter required')
def test_real_recipe_preserves_failure_summary_and_exit_code(self):
_, argv = self.recipe()
with tempfile.TemporaryDirectory() as temporary:
root = Path(temporary)
(root / 'pytest.ini').write_text('[pytest]\naddopts = -qq\n')
(root / 'test_sample.py').write_text('def test_fail():\n assert False, "synthetic failure"\n')
actual = self.invoke(self.expand(argv), root)
self.assertEqual(actual['status'], 'completed')
self.assertEqual(actual['exit_code'], 1)
self.assertIn('1 failed', actual['output'])
def expand(self, argv):
return [part.replace('{python}', sys.executable).replace('{tests}', 'test_sample.py') for part in argv]
def invoke(self, argv, root):
import importlib.util
path = ROOT / 'harness/agents/impl/skills/gitea-issue-rework/scripts/evidence_manifest.py'
spec = importlib.util.spec_from_file_location('pytest_recipe_evidence', path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
env = {key: os.environ[key] for key in ['PATH', 'HOME', 'TMPDIR', 'LANG'] if key in os.environ}
# Isolate synthetic tests from unrelated globally installed pytest plugins.
env['PYTEST_DISABLE_PLUGIN_AUTOLOAD'] = '1'
result = module.run_bounded(argv, root, env, 65536, 30)
return {'status': result['status'], 'exit_code': result['exit_code'],
'output': result['output'].decode('utf-8', 'replace')}
if __name__ == '__main__':
unittest.main()