-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: connector-builder-test-read
CLI with custom components support (do not merge)
#329
base: main
Are you sure you want to change the base?
Changes from all commits
3de3edf
3b88490
282be0b
f98b5fa
b47176b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Copyright (c) 2025 Airbyte, Inc., all rights reserved. | ||
"""CLI for running test reads from the Airbyte Connector Builder. | ||
|
||
This CLI accepts a config file and an action to perform on the connector. | ||
|
||
Usage: | ||
connector-builder-test-read [--config CONFIG] [--action ACTION] | ||
|
||
Options: | ||
--action ACTION The action to perform (e.g., test, validate). | ||
--config CONFIG Path to the config file. | ||
""" | ||
from airbyte_cdk.cli.connector_builder_test_read.run import run | ||
|
||
__all__ = [ | ||
"run", | ||
] |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Copyright (c) 2024 Airbyte, Inc., all rights reserved. | ||
"""Declarative tests framework. | ||
|
||
This module provides fixtures and utilities for testing Airbyte sources and destinations | ||
in a declarative way. | ||
""" | ||
|
||
from airbyte_cdk.test.declarative.test_suites import ( | ||
ConnectorTestSuiteBase, | ||
DestinationTestSuiteBase, | ||
SourceTestSuiteBase, | ||
) | ||
|
||
__all__ = [ | ||
"ConnectorTestSuiteBase", | ||
"DestinationTestSuiteBase", | ||
"SourceTestSuiteBase", | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from dataclasses import dataclass | ||
from typing import Protocol, Type | ||
|
||
|
||
class ConnectorInterface(Protocol): | ||
"""Protocol for Airbyte connectors.""" | ||
|
||
@classmethod | ||
def launch(cls, args: list[str] | None): ... | ||
|
||
|
||
@dataclass | ||
class PythonWrapper: | ||
"""Wrapper for Python source and destination connectors.""" | ||
|
||
connector_class: Type["ConnectorInterface"] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from scenario import ( | ||
AcceptanceTestScenario, | ||
) | ||
|
||
__all__ = [ | ||
"AcceptanceTestScenario", | ||
] |
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,48 @@ | ||||||||||||||||
# Copyright (c) 2024 Airbyte, Inc., all rights reserved. | ||||||||||||||||
"""Run acceptance tests in PyTest. | ||||||||||||||||
|
||||||||||||||||
These tests leverage the same `acceptance-test-config.yml` configuration files as the | ||||||||||||||||
acceptance tests in CAT, but they run in PyTest instead of CAT. This allows us to run | ||||||||||||||||
the acceptance tests in the same local environment as we are developing in, speeding | ||||||||||||||||
up iteration cycles. | ||||||||||||||||
""" | ||||||||||||||||
|
||||||||||||||||
from __future__ import annotations | ||||||||||||||||
|
||||||||||||||||
from pathlib import Path | ||||||||||||||||
from typing import Literal | ||||||||||||||||
|
||||||||||||||||
import yaml | ||||||||||||||||
from pydantic import BaseModel | ||||||||||||||||
|
||||||||||||||||
|
||||||||||||||||
class AcceptanceTestScenario(BaseModel): | ||||||||||||||||
"""Acceptance test instance, as a Pydantic model. | ||||||||||||||||
|
||||||||||||||||
This class represents an acceptance test instance, which is a single test case | ||||||||||||||||
that can be run against a connector. It is used to deserialize and validate the | ||||||||||||||||
acceptance test configuration file. | ||||||||||||||||
""" | ||||||||||||||||
|
||||||||||||||||
class AcceptanceTestExpectRecords(BaseModel): | ||||||||||||||||
path: Path | ||||||||||||||||
exact_order: bool = False | ||||||||||||||||
|
||||||||||||||||
class AcceptanceTestFileTypes(BaseModel): | ||||||||||||||||
skip_test: bool | ||||||||||||||||
bypass_reason: str | ||||||||||||||||
|
||||||||||||||||
config_path: Path | ||||||||||||||||
configured_catalog_path: Path | None = None | ||||||||||||||||
timeout_seconds: int | None = None | ||||||||||||||||
expect_records: AcceptanceTestExpectRecords | None = None | ||||||||||||||||
file_types: AcceptanceTestFileTypes | None = None | ||||||||||||||||
status: Literal["succeed", "failed"] | None = None | ||||||||||||||||
|
||||||||||||||||
@property | ||||||||||||||||
def expect_exception(self) -> bool: | ||||||||||||||||
return self.status and self.status == "failed" | ||||||||||||||||
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix type safety in expect_exception property. The property could return None when self.status is None, which doesn't match the declared bool return type. Wdyt about this fix? @property
def expect_exception(self) -> bool:
- return self.status and self.status == "failed"
+ return bool(self.status and self.status == "failed") 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Linters[error] 44-44: Incompatible return value type (got 'bool | None', expected 'bool') |
||||||||||||||||
|
||||||||||||||||
@property | ||||||||||||||||
def instance_name(self) -> str: | ||||||||||||||||
return self.config_path.stem |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Copyright (c) 2024 Airbyte, Inc., all rights reserved. | ||
"""Declarative test suites. | ||
|
||
Here we have base classes for a robust set of declarative connector test suites. | ||
""" | ||
|
||
from airbyte_cdk.test.declarative.test_suites.connector_base import ConnectorTestSuiteBase | ||
from airbyte_cdk.test.declarative.test_suites.destination_base import DestinationTestSuiteBase | ||
from airbyte_cdk.test.declarative.test_suites.source_base import SourceTestSuiteBase | ||
|
||
__all__ = [ | ||
"ConnectorTestSuiteBase", | ||
"DestinationTestSuiteBase", | ||
"SourceTestSuiteBase", | ||
] |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,110 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Copyright (c) 2024 Airbyte, Inc., all rights reserved. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Base class for connector test suites.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from __future__ import annotations | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import abc | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pathlib import Path | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from typing import Any, Literal | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import pytest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import yaml | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from airbyte_connector_tester.job_runner import run_test_job | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from pydantic import BaseModel | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from airbyte_cdk import Connector | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from airbyte_cdk.models import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AirbyteMessage, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Type, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from airbyte_cdk.test import entrypoint_wrapper | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from airbyte_cdk.test.declarative.models import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AcceptanceTestScenario, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ACCEPTANCE_TEST_CONFIG_PATH = Path("acceptance-test-config.yml") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class ConnectorTestSuiteBase(abc.ABC): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Base class for connector test suites.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
acceptance_test_file_path = Path("./acceptance-test-config.json") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""The path to the acceptance test config file. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
By default, this is set to the `acceptance-test-config.json` file in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
the root of the connector source directory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
connector_class: type[Connector] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""The connector class to test.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Public Methods - Subclasses may override these | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@abc.abstractmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def new_connector(self, **kwargs: dict[str, Any]) -> Connector: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Create a new connector instance. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
By default, this returns a new instance of the connector class. Subclasses | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
may override this method to generate a dynamic connector instance. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return self.connector_factory() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+43
to
+50
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix implementation of abstract method The current implementation has a few issues:
What do you think about this implementation instead? @abc.abstractmethod
def new_connector(self, **kwargs: dict[str, Any]) -> Connector:
"""Create a new connector instance.
By default, this returns a new instance of the connector class. Subclasses
may override this method to generate a dynamic connector instance.
"""
- return self.connector_factory()
+ raise NotImplementedError("Subclasses must implement new_connector") 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Linters[error] 50-50: Returning Any from function declared to return 'Connector' [error] 50-50: 'ConnectorTestSuiteBase' has no attribute 'connector_factory' |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Internal Methods - We don't expect subclasses to override these | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def _get_acceptance_tests( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
category: str, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
accept_test_config_path: Path = ACCEPTANCE_TEST_CONFIG_PATH, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> list[AcceptanceTestScenario]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
all_tests_config = yaml.safe_load(accept_test_config_path.read_text()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if "acceptance_tests" not in all_tests_config: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ValueError(f"Acceptance tests config not found in {accept_test_config_path}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if category not in all_tests_config["acceptance_tests"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if "tests" not in all_tests_config["acceptance_tests"][category]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
raise ValueError(f"No tests found for category {category}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
AcceptanceTestScenario.model_validate(test) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for test in all_tests_config["acceptance_tests"][category]["tests"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if "iam_role" not in test["config_path"] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+54
to
+71
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix classmethod signature The How about this fix? @classmethod
def _get_acceptance_tests(
+ cls,
category: str,
accept_test_config_path: Path = ACCEPTANCE_TEST_CONFIG_PATH,
) -> list[AcceptanceTestScenario]: 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Linters[error] 55-55: Self argument missing for a non-static method (or an invalid type for self) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Test Definitions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@pytest.mark.parametrize( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"test_input,expected", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
[ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
("3+5", 8), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
("2+4", 6), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
("6*9", 54), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def test_use_plugin_parametrized_test( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
test_input, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
expected, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert eval(test_input) == expected | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+83
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add type annotations to test method The test method is missing type annotations for its parameters and return type. Would this implementation be better? def test_use_plugin_parametrized_test(
self,
- test_input,
- expected,
+ test_input: str,
+ expected: int,
-):
+) -> None: 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Linters[error] 83-83: Function is missing a type annotation |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@pytest.mark.parametrize( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"instance", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self._get_acceptance_tests("connection"), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ids=lambda instance: instance.instance_name, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+90
to
+93
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix parametrize decorator usage The decorator is using undefined What about using @pytest.mark.parametrize(
"instance",
- self._get_acceptance_tests("connection"),
+ _get_acceptance_tests("connection"),
ids=lambda instance: instance.instance_name,
)
🧰 Tools🪛 GitHub Actions: Linters[error] 92-92: Name 'self' is not defined |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def test_check( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
instance: AcceptanceTestScenario, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"""Run `connection` acceptance tests.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result: entrypoint_wrapper.EntrypointOutput = run_test_job( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.new_connector(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"check", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
test_instance=instance, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
conn_status_messages: list[AirbyteMessage] = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
msg for msg in result._messages if msg.type == Type.CONNECTION_STATUS | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] # noqa: SLF001 # Non-public API | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert len(conn_status_messages) == 1, ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
"Expected exactly one CONNECTION_STATUS message. Got: \n" + "\n".join(result._messages) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+105
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix string joining of AirbyteMessages The code attempts to join AirbyteMessage objects directly, which will fail as they need to be converted to strings first. How about this fix? assert len(conn_status_messages) == 1, (
- "Expected exactly one CONNECTION_STATUS message. Got: \n" + "\n".join(result._messages)
+ "Expected exactly one CONNECTION_STATUS message. Got: \n" + "\n".join(str(msg) for msg in result._messages)
) 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Linters[error] 109-109: Argument 1 to 'join' of 'str' has incompatible type 'list[AirbyteMessage]'; expected 'Iterable[str]' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Copyright (c) 2024 Airbyte, Inc., all rights reserved. | ||
"""Base class for destination test suites.""" | ||
|
||
from airbyte_connector_tester.connector_tests import ConnectorTestSuiteBase | ||
|
||
|
||
class DestinationTestSuiteBase(ConnectorTestSuiteBase): | ||
"""Base class for destination test suites. | ||
|
||
This class provides a base set of functionality for testing destination connectors, and it | ||
inherits all generic connector tests from the `ConnectorTestSuiteBase` class. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix function call to match signature
The
run()
function is called without the requiredargs
parameter. While the function has a default value, it's better to be explicit.Would this be clearer?
📝 Committable suggestion
🧰 Tools
🪛 GitHub Actions: Linters
[error] 112-112: Missing positional argument 'args' in call to 'run'