sift_client.util.test_results
¶
Test Results Utilities.
This module provides utilities for working with test results.
Context Managers¶
ReportContext- Context manager for a new TestReport.NewStep- Context manager to create a new step in a test report.
Example¶
client = SiftClient(api_key=api_key, grpc_url=grpc_url, rest_url=rest_url)
with ReportContext(client, name="Example Report") as rc:
with rc.new_step(name="Setup") as step:
controller_setup(step)
with rc.new_step(name="Example Step", description=desc) as parent_step:
cmd_interface.cmd("ec1", "rtv.cmd", 75.0)
sleep(0.01)
with parent_step.substep(name="Substep 1", description="Measure position") as substep:
ec = "ec1"
pos_channel = "rtv.pos"
pos = tlm.read(ec, pos_channel)
result = substep.measure(pos, name=f"{ec}.{pos_channel}", bounds=(min=74.9, max=75.1))
return result # This is optional for other uses, but the step and its parents will be updated correctly i.e. failed if the measurement fails.
Manually Updating Underlyling Report¶
You can also manually update the underlying report or steps by accessing the context manager's attributes.
with ReportContext(client, name="Example Report") as rc:
with rc.new_step(name="Example Step") as step:
if !conditions:
step.update({"status": TestStatus.SKIPPED})
else:
step.measure(name="Example Measurement", value=test_value, bounds={"min": -1, "max": 10})
rc.report.update({"run_id": run_id})
For a larger class or script, consider creating the context in a setup method and passing it to the test functions.
def main(self):
self.sift_client = SiftClient(api_key=api_key, grpc_url=grpc_url, rest_url=rest_url)
with ReportContext(self.sift_client, name="Test Class", description="Test Class") as rc:
setup(rc)
test_one(rc)
test_two(rc)
teardown(rc)
cleanup()
Pytest Fixtures¶
The report context and steps can also be accessed in pytest by importing the report_context and step fixtures.
How to use:¶
- These fixtures are set to autouse and will automatically create a report and steps for each test function.
- If you want each module(file) to be marked as a step w/ each test as a substep, import the
module_substepfixture as well. - The
report_contextfixture requires a fixturesift_clientreturning anSiftClientinstance to be passed in.
Example at top of your test file or in your conftest.py file:¶
import pytest
@pytest.fixture(scope="session")
def sift_client() -> SiftClient:
grpc_url = os.getenv("SIFT_GRPC_URI", "localhost:50051")
rest_url = os.getenv("SIFT_REST_URI", "localhost:8080")
api_key = os.getenv("SIFT_API_KEY", "")
client = SiftClient(api_key=api_key, grpc_url=grpc_url, rest_url=rest_url)
return client
from sift_client.util.test_results import pytest_runtest_makereport, report_context, step, module_substep
Then in your test file:¶
# Because step was already imported and set autouse=True, this test will automatically get a step created for it.
def test_no_includes():
assert condition, "Example failure"
# Passing the fixtures to the test function allows you to take measurements or create substeps.
def test_example(report_context, step):
# This will add a measurement to the current step for this function
step.measure(name="Example Measurement", value=test_string_value, bounds="expected_string_value")
with report_context.new_step(name="Example Step") as substep:
example_measurement = tlm.read(channel_name)
substep.measure(name="Substep Measurement", value=example_measurement, bounds=(min=74.9, max=75.1))
| MODULE | DESCRIPTION |
|---|---|
bounds |
|
context_manager |
|
pytest_util |
|
| CLASS | DESCRIPTION |
|---|---|
NewStep |
Context manager to create a new step in a test report. See usage example in init.py. |
ReportContext |
Context manager for a new TestReport. See usage example in init.py. |
| FUNCTION | DESCRIPTION |
|---|---|
client_has_connection |
Check if the SiftClient has a connection to the Sift server. |
module_substep |
Create a step per module. |
module_substep_check_connection |
Create a step per module. Doesn't run if the client has no connection to the Sift server. |
pytest_runtest_makereport |
You should import this hook to capture any AssertionErrors that occur during the test. If not included, any assert failures in a test will not automatically fail the step. |
report_context |
Create a report context for the session. |
report_context_check_connection |
Create a report context for the session. Doesn't run if the client has no connection to the Sift server. |
step |
Create an outer step for the function. |
step_check_connection |
Create an outer step for the function. Doesn't run if the client has no connection to the Sift server. |
NewStep
¶
NewStep(
report_context: ReportContext,
name: str,
description: str | None = None,
)
Bases: AbstractContextManager
Context manager to create a new step in a test report. See usage example in init.py.
Initialize a new step context.
| PARAMETER | DESCRIPTION |
|---|---|
report_context
|
The report context to create the step in.
TYPE:
|
name
|
The name of the step.
TYPE:
|
description
|
The description of the step.
TYPE:
|
| METHOD | DESCRIPTION |
|---|---|
__enter__ |
Enter the context manager to create a new step. |
__exit__ |
|
measure |
Measure a value and return the result. |
substep |
Alias to return a new step context manager from the current step. The ReportContext will manage nesting of steps. |
update_step_from_result |
Update the step based on its substeps and if there was an exception while executing the step. |
| ATTRIBUTE | DESCRIPTION |
|---|---|
client |
TYPE:
|
current_step |
TYPE:
|
report_context |
TYPE:
|
current_step
class-attribute
instance-attribute
¶
current_step: TestStep | None = create_step(
name, description
)
measure
¶
measure(
*,
name: str,
value: float | str | bool,
bounds: dict[str, float]
| NumericBounds
| str
| None = None,
timestamp: datetime | None = None,
unit: str | None = None,
) -> bool
Measure a value and return the result.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The name of the measurement.
TYPE:
|
value
|
The value of the measurement.
TYPE:
|
bounds
|
[Optional] The bounds to compare the value to.
TYPE:
|
timestamp
|
[Optional] The timestamp of the measurement. Defaults to the current time.
TYPE:
|
unit
|
[Optional] The unit of the measurement.
TYPE:
|
returns: The result of the measurement.
substep
¶
substep(
name: str, description: str | None = None
) -> NewStep
Alias to return a new step context manager from the current step. The ReportContext will manage nesting of steps.
update_step_from_result
¶
update_step_from_result(
exc: type[Exception] | None,
exc_value: Exception | None,
tb: TracebackException | None,
)
Update the step based on its substeps and if there was an exception while executing the step.
| PARAMETER | DESCRIPTION |
|---|---|
exc
|
The class of Exception that was raised.
TYPE:
|
exc_value
|
The exception value.
TYPE:
|
tb
|
The traceback object.
TYPE:
|
ReportContext
¶
ReportContext(
client: SiftClient,
name: str,
test_system_name: str | None = None,
system_operator: str | None = None,
test_case: str | None = None,
)
Bases: AbstractContextManager
Context manager for a new TestReport. See usage example in init.py.
Initialize a new report context.
| PARAMETER | DESCRIPTION |
|---|---|
client
|
The Sift client to use to create the report.
TYPE:
|
name
|
The name of the report.
TYPE:
|
test_system_name
|
The name of the test system. Will default to the hostname if not provided.
TYPE:
|
system_operator
|
The operator of the test system. Will default to the current user if not provided.
TYPE:
|
test_case
|
The name of the test case. Will default to the basename of the file containing the test if not provided.
TYPE:
|
| METHOD | DESCRIPTION |
|---|---|
__enter__ |
|
__exit__ |
|
create_step |
Create a new step in the report context. |
exit_step |
Exit a step and update the report context. |
get_next_step_path |
Get the next step path for the current depth. |
new_step |
Alias to return a new step context manager from this report context. Use create_step for actually creating a TestStep in the current context. |
report_measurement |
Report a failure to the report context. |
resolve_and_propagate_step_result |
Resolve the result of a step and propagate the result to the parent step if it failed. |
| ATTRIBUTE | DESCRIPTION |
|---|---|
any_failures |
TYPE:
|
open_step_results |
TYPE:
|
report |
TYPE:
|
step_is_open |
TYPE:
|
step_number_at_depth |
TYPE:
|
step_stack |
TYPE:
|
create_step
¶
create_step(
name: str, description: str | None = None
) -> TestStep
Create a new step in the report context.
| PARAMETER | DESCRIPTION |
|---|---|
name
|
The name of the step.
TYPE:
|
description
|
The description of the step.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
TestStep
|
The created step. |
new_step
¶
new_step(
name: str, description: str | None = None
) -> NewStep
Alias to return a new step context manager from this report context. Use create_step for actually creating a TestStep in the current context.
report_measurement
¶
report_measurement(
measurement: TestMeasurement, step: TestStep
)
Report a failure to the report context.
client_has_connection
¶
Check if the SiftClient has a connection to the Sift server.
Can be used to skip tests that require a connection to the Sift server.
module_substep
¶
module_substep(
report_context: ReportContext, request: FixtureRequest
) -> Generator[NewStep | None, None, None]
Create a step per module.
module_substep_check_connection
¶
module_substep_check_connection(
report_context: ReportContext,
client_has_connection: bool,
request: FixtureRequest,
) -> Generator[NewStep | None, None, None]
Create a step per module. Doesn't run if the client has no connection to the Sift server.
pytest_runtest_makereport
¶
You should import this hook to capture any AssertionErrors that occur during the test. If not included, any assert failures in a test will not automatically fail the step.
report_context
¶
report_context(
sift_client: SiftClient, request: FixtureRequest
) -> Generator[ReportContext | None, None, None]
Create a report context for the session.
report_context_check_connection
¶
report_context_check_connection(
sift_client: SiftClient,
client_has_connection: bool,
request: FixtureRequest,
) -> Generator[ReportContext | None, None, None]
Create a report context for the session. Doesn't run if the client has no connection to the Sift server.
step
¶
step(
report_context: ReportContext, request: FixtureRequest
) -> Generator[NewStep | None, None, None]
Create an outer step for the function.
step_check_connection
¶
step_check_connection(
report_context: ReportContext,
client_has_connection: bool,
request: FixtureRequest,
) -> Generator[NewStep | None, None, None]
Create an outer step for the function. Doesn't run if the client has no connection to the Sift server.