Skip to content

Commit d445a7c

Browse files
authored
Merge pull request #33 from azure-ai-foundry/python-tools-estraight
updated conftest
2 parents c28740f + f677078 commit d445a7c

1 file changed

Lines changed: 56 additions & 70 deletions

File tree

conftest.py

Lines changed: 56 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,70 @@
1-
import json
2-
import types
3-
from pathlib import Path
4-
from typing import Dict
5-
1+
# conftest.py
2+
#
3+
# Purpose
4+
# -------
5+
# Treat every Python sample under doc-samples/agents/python/**
6+
# as a Pytest test item. The script “passes” if it runs without
7+
# raising an exception (exit code 0).
8+
#
9+
# How it works
10+
# ------------
11+
# • pytest_collect_file() is a collection hook called for every file
12+
# Pytest sees. We accept the file if:
13+
# – it ends with .py
14+
# – its path is under SAMPLE_ROOT (any depth)
15+
# • Accepted files become SampleItem objects, which simply execute
16+
# the script with runpy.run_path().
17+
#
18+
# Edit SAMPLE_ROOT if you move the samples elsewhere.
19+
20+
import pathlib
21+
import runpy
622
import pytest
723

8-
REPO_ROOT = Path(__file__).parent.resolve()
9-
10-
11-
@pytest.fixture
12-
def notebook_path(
13-
# Create and activate a new venv for each test that requests `notebook_path`
14-
venv: types.SimpleNamespace, # noqa: ARG001
15-
notebook_path: Path,
16-
) -> Path:
17-
"""Activates a virtual environment for tests that request notebook_path (Jupyter Notebook tests)."""
18-
return notebook_path
19-
24+
# Root directory that contains all Python samples
25+
SAMPLE_ROOT = (
26+
pathlib.Path(__file__).parent
27+
/ "doc-samples"
28+
/ "agents"
29+
/ "python"
30+
).resolve()
2031

21-
@pytest.fixture
22-
def deployment_outputs() -> Dict[str, str]:
23-
"""The outputs of the deployment used to setup resources for testing samples.
2432

25-
Depends on the existence of a `deployment.json` file in the root of the repository,
26-
which is the output of running `az deployment sub create -o json`
33+
def _is_under_sample_root(path_obj: pathlib.Path) -> bool:
2734
"""
28-
deployment_file_path = REPO_ROOT / "deployment.json"
35+
Return True if `path_obj` is inside SAMPLE_ROOT (recursive).
2936
37+
Using Path.relative_to() is the safest way and works on all OSes.
38+
"""
3039
try:
31-
with deployment_file_path.open() as f:
32-
deployment = json.load(f)
33-
except (FileExistsError, json.JSONDecodeError) as e:
34-
raise AssertionError("Please use azure-cli to perform a deployment and same result to deployment.json") from e
35-
36-
properties = deployment.get("properties")
37-
38-
if properties is None or "outputs" not in properties:
39-
raise AssertionError("Key 'properties.outputs' not present in deployment json")
40-
41-
outputs = properties.get("outputs")
40+
path_obj.resolve().relative_to(SAMPLE_ROOT)
41+
return True
42+
except ValueError:
43+
return False
4244

43-
return {output_name: output["value"] for output_name, output in outputs.items()}
44-
45-
46-
@pytest.fixture
47-
def azure_ai_project(deployment_outputs: Dict[str, str]) -> Dict[str, str]:
48-
"""Azure ai project dictionary."""
49-
return {
50-
"subscription_id": deployment_outputs["subscription_id"],
51-
"resource_group_name": deployment_outputs["resource_group_name"],
52-
"project_name": deployment_outputs["project_name"],
53-
}
54-
55-
56-
@pytest.fixture
57-
def azure_ai_project_connection_string(deployment_outputs: Dict[str, str]) -> str:
58-
"""The connection string for the azure ai project"""
59-
return ";".join(
60-
[
61-
f"{deployment_outputs['project_location']}.api.azureml.ms",
62-
deployment_outputs["subscription_id"],
63-
deployment_outputs["resource_group_name"],
64-
deployment_outputs["project_name"],
65-
]
66-
)
6745

46+
def pytest_collect_file(parent, path):
47+
"""
48+
PyTest collection hook: decide whether *path* should become a test item.
49+
`path` is a py.path.local object; convert to Path for easier checks.
50+
"""
51+
if path.ext == ".py" and _is_under_sample_root(pathlib.Path(path)):
52+
return SampleItem.from_parent(parent, fspath=path)
6853

69-
@pytest.fixture
70-
def azure_openai_endpoint(deployment_outputs: Dict[str, str]) -> str:
71-
"""The azure openai endpoint for the azure ai project."""
72-
return deployment_outputs["azure_openai_endpoint"]
7354

55+
class SampleItem(pytest.Item):
56+
"""
57+
Wrapper around an arbitrary Python script.
58+
The test *passes* if the script finishes without an exception.
59+
"""
7460

75-
@pytest.fixture
76-
def azure_openai_gpt4_deployment(deployment_outputs: Dict[str, str]) -> str:
77-
"""The deployment name of the gpt-4 deployment."""
78-
return deployment_outputs["azure_openai_gpt4_deployment_name"]
61+
def runtest(self):
62+
# Execute the script in its own namespace.
63+
runpy.run_path(str(self.fspath))
7964

65+
def repr_failure(self, excinfo):
66+
# Nicely format any exception raised during runtest().
67+
return f"Sample {self.fspath} failed:\n{excinfo.value}"
8068

81-
@pytest.fixture
82-
def azure_openai_gpt4_api_version(deployment_outputs: Dict[str, str]) -> str:
83-
"""The api version of the gpt-4 deployment."""
84-
return deployment_outputs["azure_openai_gpt4_api_version"]
69+
def reportinfo(self):
70+
return self.fspath, 0, "sample script"

0 commit comments

Comments
 (0)