Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions airbyte_cdk/cli/airbyte_cdk/_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,18 @@ def connector_cli_group() -> None:
multiple=True,
help="Additional argument(s) to pass to pytest. Can be specified multiple times.",
)
@click.option(
"--no-creds",
is_flag=True,
default=False,
help="Skip tests that require credentials (marked with 'requires_creds').",
)
def connector_test(
connector: str | Path | None = None,
*,
collect_only: bool = False,
pytest_args: list[str] | None = None,
no_creds: bool = False,
) -> None:
"""Run connector tests.

Expand All @@ -147,6 +154,9 @@ def connector_test(
if collect_only:
pytest_args.append("--collect-only")

if no_creds:
pytest_args.extend(["-m", "not requires_creds"])

run_connector_tests(
connector_name=connector_name,
connector_directory=connector_directory,
Expand Down
13 changes: 12 additions & 1 deletion airbyte_cdk/cli/airbyte_cdk/_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,17 @@ def build(
"--image",
help="Image to test, instead of building a new one.",
)
@click.option(
"--no-creds",
is_flag=True,
default=False,
help="Skip tests that require credentials (marked with 'requires_creds').",
)
def image_test( # "image test" command
connector: str | None = None,
*,
image: str | None = None,
no_creds: bool = False,
) -> None:
"""Test a connector Docker image.

Expand All @@ -124,7 +131,11 @@ def image_test( # "image test" command
connector_name, connector_directory = resolve_connector_name_and_directory(connector)

# Select only tests with the 'image_tests' mark
pytest_args = ["-m", "image_tests"]
pytest_filter = "image_tests"
if no_creds:
pytest_filter += " and not requires_creds"

pytest_args = ["-m", pytest_filter]
if not image:
metadata_file_path: Path = connector_directory / "metadata.yaml"
try:
Expand Down
5 changes: 5 additions & 0 deletions airbyte_cdk/test/models/scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,8 @@ def with_expecting_success(self) -> ConnectorTestScenario:
**self.model_dump(exclude={"status"}),
status="succeed",
)

@property
def requires_creds(self) -> bool:
"""Return True if the scenario requires credentials to run."""
return bool(self.config_path and "secrets" in self.config_path.parts)
21 changes: 18 additions & 3 deletions airbyte_cdk/test/standard_tests/pytest_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,29 @@ class TestMyConnector(ConnectorTestSuiteBase):
if test_class is None:
return

# Get the 'scenarios' attribute from the class
# Check that the class is compatible with our test suite
scenarios_attr = getattr(test_class, "get_scenarios", None)
if scenarios_attr is None:
raise ValueError(
f"Test class {test_class} does not have a 'scenarios' attribute. "
"Please define the 'scenarios' attribute in the test class."
)

# Get the scenarios defined or discovered in the test class
scenarios = test_class.get_scenarios()
ids = [str(scenario) for scenario in scenarios]
metafunc.parametrize("scenario", scenarios, ids=ids)

# Create pytest.param objects with special marks as needed
parametrized_scenarios = [
pytest.param(
scenario,
marks=[pytest.mark.requires_creds] if scenario.requires_creds else [],
)
for scenario in scenarios
]

# Parametrize the 'scenario' argument with the scenarios
metafunc.parametrize(
"scenario",
parametrized_scenarios,
ids=[str(scenario) for scenario in scenarios],
)
Loading