Repository: godatadriven/dbt-bouncer (language: python)

Issue:
Design interface for adding new checks
To add a new check a developer needs:

- Specify what kind of artifact is required for the check
  - Could be extracted from the arguments of the function
     - A decorator can capture the `*args`, `**kwargs`, and `inspect.signature`
  - Could be a pytest mark

- Specify the config available for the check
  - A Pydantic model

- Implement the check
  - Right now they are being discovered as functions starting with "check_"
  - If the developer needs to add both a Pydantic model and a function, it'd be nice to combine both as a single class with a `check` method
   - But for this the pytest plugin needs to be able to call methods from within classes (in the same way that you can organize tests under classes in normal pytest), but idk how hard it'd be to get this to work.


Discussion / hints:

Fix patch:
diff --git a/src/dbt_bouncer/checks/catalog/check_catalog_sources.py b/src/dbt_bouncer/checks/catalog/check_catalog_sources.py
index 18fb574e..3ebdd631 100644
--- a/src/dbt_bouncer/checks/catalog/check_catalog_sources.py
+++ b/src/dbt_bouncer/checks/catalog/check_catalog_sources.py
@@ -1,10 +1,13 @@
-from typing import List, Literal
+# mypy: disable-error-code="union-attr"
+
+from typing import List, Literal, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 
 from dbt_bouncer.conf_validator_base import BaseCheck
 from dbt_bouncer.parsers import DbtBouncerCatalogNode, DbtBouncerSource
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckSourceColumnsAreAllDocumented(BaseCheck):
@@ -12,17 +15,17 @@ class CheckSourceColumnsAreAllDocumented(BaseCheck):
 
 
 @pytest.mark.iterate_over_catalog_sources
+@bouncer_check
 def check_source_columns_are_all_documented(
-    sources: List[DbtBouncerSource], request, catalog_source: DbtBouncerCatalogNode = None
+    sources: List[DbtBouncerSource],
+    request: TopRequest,
+    catalog_source: Union[DbtBouncerCatalogNode, None] = None,
+    **kwargs,
 ) -> None:
     """
     All columns in a source should be included in the source's properties file, i.e. `.yml` file.
     """
 
-    catalog_source = get_check_inputs(catalog_source=catalog_source, request=request)[
-        "catalog_source"
-    ]
-
     source = [s for s in sources if s.unique_id == catalog_source.unique_id][0]
     undocumented_columns = [
         v.name for _, v in catalog_source.columns.items() if v.name not in source.columns.keys()
diff --git a/src/dbt_bouncer/checks/catalog/check_columns.py b/src/dbt_bouncer/checks/catalog/check_columns.py
index 7c75fdef..fe1f43c6 100644
--- a/src/dbt_bouncer/checks/catalog/check_columns.py
+++ b/src/dbt_bouncer/checks/catalog/check_columns.py
@@ -1,11 +1,15 @@
+# mypy: disable-error-code="union-attr"
+
 import re
-from typing import List, Literal
+from typing import List, Literal, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
+from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogTable
 
 from dbt_bouncer.conf_validator_base import BaseCheck
-from dbt_bouncer.parsers import DbtBouncerCatalogNode, DbtBouncerModel, DbtBouncerTest
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.parsers import DbtBouncerModel, DbtBouncerTest
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckColumnNameCompliesToColumnType(BaseCheck):
@@ -15,29 +19,27 @@ class CheckColumnNameCompliesToColumnType(BaseCheck):
 
 
 @pytest.mark.iterate_over_catalog_nodes
+@bouncer_check
 def check_column_name_complies_to_column_type(
-    request, check_config=None, catalog_node: DbtBouncerCatalogNode = None
+    request: TopRequest,
+    catalog_node: Union[CatalogTable, None] = None,
+    column_name_pattern: Union[None, str] = None,
+    types: Union[List[str], None] = None,
+    **kwargs,
 ) -> None:
     """
     Columns with specified data types must comply to the specified regexp naming pattern.
     """
 
-    input_vars = get_check_inputs(
-        catalog_node=catalog_node, check_config=check_config, request=request
-    )
-    catalog_node = input_vars["catalog_node"]
-    check_config = input_vars["check_config"]
-
     non_complying_columns = [
         v.name
         for _, v in catalog_node.columns.items()
-        if v.type in check_config["types"]
-        and re.compile(check_config["column_name_pattern"].strip()).match(v.name) is None
+        if v.type in types and re.compile(column_name_pattern.strip()).match(v.name) is None  # type: ignore[operator]
     ]
 
     assert (
         not non_complying_columns
-    ), f"`{catalog_node.unique_id.split('.')[-1]}` has columns that don't comply with the specified regexp pattern (`{check_config['column_name_pattern']}`): {non_complying_columns}"
+    ), f"`{catalog_node.unique_id.split('.')[-1]}` has columns that don't comply with the specified regexp pattern (`{column_name_pattern}`): {non_complying_columns}"
 
 
 class CheckColumnsAreAllDocumented(BaseCheck):
@@ -45,15 +47,17 @@ class CheckColumnsAreAllDocumented(BaseCheck):
 
 
 @pytest.mark.iterate_over_catalog_nodes
+@bouncer_check
 def check_columns_are_all_documented(
-    models: List[DbtBouncerModel], request, catalog_node: DbtBouncerCatalogNode = None
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    catalog_node: Union[CatalogTable, None] = None,
+    **kwargs,
 ) -> None:
     """
     All columns in a model should be included in the model's properties file, i.e. `.yml` file.
     """
 
-    catalog_node = get_check_inputs(catalog_node=catalog_node, request=request)["catalog_node"]
-
     if catalog_node.unique_id.split(".")[0] == "model":
         model = [m for m in models if m.unique_id == catalog_node.unique_id][0]
         undocumented_columns = [
@@ -69,15 +73,17 @@ class CheckColumnsAreDocumentedInPublicModels(BaseCheck):
 
 
 @pytest.mark.iterate_over_catalog_nodes
+@bouncer_check
 def check_columns_are_documented_in_public_models(
-    models: List[DbtBouncerModel], request, catalog_node: DbtBouncerCatalogNode = None
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    catalog_node: Union[CatalogTable, None] = None,
+    **kwargs,
 ) -> None:
     """
     Columns should have a populated description in public models.
     """
 
-    catalog_node = get_check_inputs(catalog_node=catalog_node, request=request)["catalog_node"]
-
     if catalog_node.unique_id.split(".")[0] == "model":
         model = [m for m in models if m.unique_id == catalog_node.unique_id][0]
         non_complying_columns = []
@@ -99,23 +105,19 @@ class CheckColumnHasSpecifiedTest(BaseCheck):
 
 
 @pytest.mark.iterate_over_catalog_nodes
+@bouncer_check
 def check_column_has_specified_test(
-    request,
+    request: TopRequest,
     tests: List[DbtBouncerTest],
-    check_config=None,
-    catalog_node: DbtBouncerCatalogNode = None,
+    catalog_node: Union[CatalogTable, None] = None,
+    column_name_pattern: Union[None, str] = None,
+    test_name: Union[None, str] = None,
+    **kwargs,
 ) -> None:
     """
     Columns that match the specified regexp pattern must have a specified test.
     """
 
-    input_vars = get_check_inputs(
-        catalog_node=catalog_node, check_config=check_config, request=request
-    )
-    catalog_node = input_vars["catalog_node"]
-    column_name_pattern = input_vars["check_config"]["column_name_pattern"]
-    test_name = input_vars["check_config"]["test_name"]
-
     columns_to_check = [
         v.name
         for _, v in catalog_node.columns.items()
diff --git a/src/dbt_bouncer/checks/manifest/check_exposures.py b/src/dbt_bouncer/checks/manifest/check_exposures.py
index 351ed9b4..114a4207 100644
--- a/src/dbt_bouncer/checks/manifest/check_exposures.py
+++ b/src/dbt_bouncer/checks/manifest/check_exposures.py
@@ -1,12 +1,15 @@
-from typing import List, Literal
+# mypy: disable-error-code="union-attr"
+
+from typing import List, Literal, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Exposures
 from pydantic import Field
 
 from dbt_bouncer.conf_validator_base import BaseCheck
 from dbt_bouncer.parsers import DbtBouncerModel
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckExposureOnNonPublicModels(BaseCheck):
@@ -14,15 +17,17 @@ class CheckExposureOnNonPublicModels(BaseCheck):
 
 
 @pytest.mark.iterate_over_exposures
+@bouncer_check
 def check_exposure_based_on_non_public_models(
-    models: List[DbtBouncerModel], request, exposure: Exposures = None
-):
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    exposure: Union[Exposures, None] = None,
+    **kwargs,
+) -> None:
     """
     Exposures should be based on public models only.
     """
 
-    exposure = get_check_inputs(exposure=exposure, request=request)["exposure"]
-
     non_public_upstream_dependencies = []
     for model in exposure.depends_on.nodes:
         if (
@@ -47,17 +52,18 @@ class CheckExposureOnView(BaseCheck):
 
 
 @pytest.mark.iterate_over_exposures
+@bouncer_check
 def check_exposure_based_on_view(
-    models: List[DbtBouncerModel], request, check_config=None, exposure: Exposures = None
-):
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    exposure: Union[Exposures, None] = None,
+    materializations_to_include: Union[List[str], None] = None,
+    **kwargs,
+) -> None:
     """
     Exposures should not be based on views.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, exposure=exposure, request=request)
-    exposure = input_vars["exposure"]
-    materializations_to_include = input_vars["check_config"]["materializations_to_include"]
-
     non_table_upstream_dependencies = []
     for model in exposure.depends_on.nodes:
         if (
@@ -65,7 +71,7 @@ def check_exposure_based_on_view(
             and model.split(".")[1] == exposure.unique_id.split(".")[1]
         ):
             model = [m for m in models if m.unique_id == model][0]
-            if model.config.materialized in materializations_to_include:
+            if model.config.materialized in materializations_to_include:  # type: ignore[operator]
                 non_table_upstream_dependencies.append(model.unique_id.split(".")[-1])
 
     assert (
diff --git a/src/dbt_bouncer/checks/manifest/check_lineage.py b/src/dbt_bouncer/checks/manifest/check_lineage.py
index ab2285a2..7c51dc90 100644
--- a/src/dbt_bouncer/checks/manifest/check_lineage.py
+++ b/src/dbt_bouncer/checks/manifest/check_lineage.py
@@ -1,11 +1,14 @@
+# mypy: disable-error-code="union-attr"
+
 import re
-from typing import List, Literal, Optional
+from typing import List, Literal, Optional, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from pydantic import BaseModel, ConfigDict, Field
 
 from dbt_bouncer.parsers import DbtBouncerManifest, DbtBouncerModel
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckLineagePermittedUpstreamModels(BaseModel):
@@ -24,21 +27,19 @@ class CheckLineagePermittedUpstreamModels(BaseModel):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_lineage_permitted_upstream_models(
     manifest_obj: DbtBouncerManifest,
     models: List[DbtBouncerModel],
-    request,
-    check_config=None,
-    model: DbtBouncerModel = None,
-):
+    request: TopRequest,
+    model: Union[DbtBouncerModel, None] = None,
+    upstream_path_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     Upstream models must have a path that matches the provided `upstream_path_pattern`.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
     upstream_models = [
         x
         for x in model.depends_on.nodes
@@ -48,7 +49,7 @@ def check_lineage_permitted_upstream_models(
     not_permitted_upstream_models = [
         upstream_model
         for upstream_model in upstream_models
-        if re.compile(check_config["upstream_path_pattern"].strip()).match(
+        if re.compile(upstream_path_pattern.strip()).match(
             [m for m in models if m.unique_id == upstream_model][0].path
         )
         is None
@@ -71,13 +72,14 @@ class CheckLineageSeedCannotBeUsed(BaseModel):
 
 
 @pytest.mark.iterate_over_models
-def check_lineage_seed_cannot_be_used(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_lineage_seed_cannot_be_used(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Seed cannot be referenced in models with a path that matches the specified `include` config.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     assert not [
         x for x in model.depends_on.nodes if x.split(".")[0] == "seed"
     ], f"`{model.unique_id.split('.')[-1]}` references a seed even though this is not permitted."
@@ -96,13 +98,14 @@ class CheckLineageSourceCannotBeUsed(BaseModel):
 
 
 @pytest.mark.iterate_over_models
-def check_lineage_source_cannot_be_used(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_lineage_source_cannot_be_used(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Sources cannot be referenced in models with a path that matches the specified `include` config.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     assert not [
         x for x in model.depends_on.nodes if x.split(".")[0] == "source"
     ], f"`{model.unique_id.split('.')[-1]}` references a source even though this is not permitted."
diff --git a/src/dbt_bouncer/checks/manifest/check_macros.py b/src/dbt_bouncer/checks/manifest/check_macros.py
index 69a8a381..88ee9474 100644
--- a/src/dbt_bouncer/checks/manifest/check_macros.py
+++ b/src/dbt_bouncer/checks/manifest/check_macros.py
@@ -1,12 +1,15 @@
+# mypy: disable-error-code="union-attr"
+
 import re
-from typing import Literal
+from typing import Literal, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Macros
 from pydantic import Field
 
 from dbt_bouncer.conf_validator_base import BaseCheck
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckMacroArgumentsDescriptionPopulated(BaseCheck):
@@ -14,14 +17,14 @@ class CheckMacroArgumentsDescriptionPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_macros
+@bouncer_check
 def check_macro_arguments_description_populated(
-    request, check_config=None, macro: Macros = None
+    request: TopRequest, macro: Union[Macros, None] = None, **kwargs
 ) -> None:
     """
     Macro arguments must have a populated description.
     """
 
-    macro = get_check_inputs(check_config=check_config, macro=macro, request=request)["macro"]
     for arg in macro.arguments:
         assert (
             len(arg.description.strip()) > 4
@@ -36,21 +39,20 @@ class CheckMacroCodeDoesNotContainRegexpPattern(BaseCheck):
 
 
 @pytest.mark.iterate_over_macros
+@bouncer_check
 def check_macro_code_does_not_contain_regexp_pattern(
-    request, check_config=None, macro: Macros = None
-):
+    request: TopRequest,
+    macro: Union[Macros, None] = None,
+    regexp_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     The raw code for a macro must not match the specified regexp pattern.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, macro=macro, request=request)
-    check_config = input_vars["check_config"]
-    macro = input_vars["macro"]
-
     assert (
-        re.compile(check_config["regexp_pattern"].strip(), flags=re.DOTALL).match(macro.macro_sql)
-        is None
-    ), f"`{macro.unique_id.split('.')[-1]}` contains a banned string: `{check_config['regexp_pattern'].strip()}`."
+        re.compile(regexp_pattern.strip(), flags=re.DOTALL).match(macro.macro_sql) is None
+    ), f"`{macro.unique_id.split('.')[-1]}` contains a banned string: `{regexp_pattern.strip()}`."
 
 
 class CheckMacroDescriptionPopulated(BaseCheck):
@@ -58,12 +60,14 @@ class CheckMacroDescriptionPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_macros
-def check_macro_description_populated(request, check_config=None, macro: Macros = None) -> None:
+@bouncer_check
+def check_macro_description_populated(
+    request: TopRequest, macro: Union[Macros, None] = None, **kwargs
+) -> None:
     """
     Macros must have a populated description.
     """
 
-    macro = get_check_inputs(check_config=check_config, macro=macro, request=request)["macro"]
     assert (
         len(macro.description.strip()) > 4
     ), f"`{macro.unique_id.split('.')[-1]}` does not have a populated description."
@@ -74,14 +78,16 @@ class CheckMacroNameMatchesFileName(BaseCheck):
 
 
 @pytest.mark.iterate_over_macros
-def check_macro_name_matches_file_name(request, check_config=None, macro: Macros = None) -> None:
+@bouncer_check
+def check_macro_name_matches_file_name(
+    request: TopRequest, macro: Union[Macros, None] = None, **kwargs
+) -> None:
     """
     Macros names must be the same as the file they are contained in.
 
     Generic tests are also macros, however to document these tests the "name" value must be precededed with "test_".
     """
 
-    macro = get_check_inputs(macro=macro, request=request)["macro"]
     if macro.name.startswith("test_"):
         assert (
             macro.name[5:] == macro.path.split("/")[-1].split(".")[0]
@@ -97,13 +103,14 @@ class CheckMacroPropertyFileLocation(BaseCheck):
 
 
 @pytest.mark.iterate_over_macros
-def check_macro_property_file_location(request, macro: Macros = None):
+@bouncer_check
+def check_macro_property_file_location(
+    request: TopRequest, macro: Union[Macros, None] = None, **kwargs
+) -> None:
     """
     Macro properties files must follow the guidance provided by dbt [here](https://docs.getdbt.com/best-practices/how-we-structure/5-the-rest-of-the-project#how-we-use-the-other-folders).
     """
 
-    macro = get_check_inputs(macro=macro, request=request)["macro"]
-
     expected_substr = "_".join(macro.path[6:].split("/")[:-1])
     properties_yml_name = macro.patch_path.split("/")[-1]
 
diff --git a/src/dbt_bouncer/checks/manifest/check_metadata.py b/src/dbt_bouncer/checks/manifest/check_metadata.py
index e86915bc..3e364105 100644
--- a/src/dbt_bouncer/checks/manifest/check_metadata.py
+++ b/src/dbt_bouncer/checks/manifest/check_metadata.py
@@ -1,10 +1,13 @@
+# mypy: disable-error-code="union-attr"
+
 import re
-from typing import Literal, Optional
+from typing import Literal, Optional, Union
 
+from _pytest.fixtures import TopRequest
 from pydantic import BaseModel, ConfigDict, Field
 
 from dbt_bouncer.parsers import DbtBouncerManifest
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckProjectName(BaseModel):
@@ -17,16 +20,18 @@ class CheckProjectName(BaseModel):
     project_name_pattern: str = Field(description="Regexp the project name must match.")
 
 
-def check_project_name(manifest_obj: DbtBouncerManifest, request, check_config=None):
+@bouncer_check
+def check_project_name(
+    manifest_obj: DbtBouncerManifest,
+    request: TopRequest,
+    project_name_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     Enforce that the name of the dbt project matches a supplied regex. Generally used to enforce that project names conform to something like  `company_<DOMAIN>`.
     """
 
-    check_config = get_check_inputs(check_config=check_config, request=request)["check_config"]
-
     assert (
-        re.compile(check_config["project_name_pattern"].strip()).match(
-            manifest_obj.manifest.metadata.project_name
-        )
+        re.compile(project_name_pattern.strip()).match(manifest_obj.manifest.metadata.project_name)
         is not None
-    ), f"Project name (`{manifest_obj.manifest.metadata.project_name}`) does not conform to the supplied regex `({check_config['project_name_pattern'].strip()})`."
+    ), f"Project name (`{manifest_obj.manifest.metadata.project_name}`) does not conform to the supplied regex `({project_name_pattern.strip()})`."
diff --git a/src/dbt_bouncer/checks/manifest/check_models.py b/src/dbt_bouncer/checks/manifest/check_models.py
index 197eaa88..b0f1c24b 100644
--- a/src/dbt_bouncer/checks/manifest/check_models.py
+++ b/src/dbt_bouncer/checks/manifest/check_models.py
@@ -1,13 +1,15 @@
+# mypy: disable-error-code="union-attr"
+
 import re
 from typing import Any, Dict, List, Literal, Optional, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from pydantic import BaseModel, ConfigDict, Field
 
 from dbt_bouncer.conf_validator_base import BaseCheck
-from dbt_bouncer.logger import logger
 from dbt_bouncer.parsers import DbtBouncerManifest, DbtBouncerModel
-from dbt_bouncer.utils import find_missing_meta_keys, get_check_inputs
+from dbt_bouncer.utils import bouncer_check, find_missing_meta_keys
 
 
 class CheckModelAccess(BaseCheck):
@@ -16,18 +18,20 @@ class CheckModelAccess(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_access(request, check_config=None, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_access(
+    request: TopRequest,
+    access: Union[None, str] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     Models must have the specified access attribute. Requires dbt 1.7+.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
     assert (
-        model.access.value == check_config["access"]
-    ), f"`{model.unique_id.split('.')[-1]}` has `{model.access.value}` access, it should have access `{check_config['access']}`."
+        model.access.value == access
+    ), f"`{model.unique_id.split('.')[-1]}` has `{model.access.value}` access, it should have access `{access}`."
 
 
 class CheckModelContractsEnforcedForPublicModel(BaseCheck):
@@ -35,13 +39,14 @@ class CheckModelContractsEnforcedForPublicModel(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_contract_enforced_for_public_model(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_contract_enforced_for_public_model(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Public models must have contracts enforced.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     if model.access.value == "public":
         assert (
             model.contract.enforced is True
@@ -53,13 +58,14 @@ class CheckModelDescriptionPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_description_populated(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_description_populated(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Models must have a populated description.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     assert (
         len(model.description.strip()) > 4
     ), f"`{model.unique_id.split('.')[-1]}` does not have a populated description."
@@ -75,15 +81,17 @@ class CheckModelsDocumentationCoverage(BaseCheck):
     )
 
 
-def check_model_documentation_coverage(models: List[DbtBouncerModel], request, check_config=None):
+@bouncer_check
+def check_model_documentation_coverage(
+    request: TopRequest,
+    models: List[DbtBouncerModel],
+    min_model_documentation_coverage_pct: Union[float, None] = None,
+    **kwargs,
+) -> None:
     """
     Set the minimum percentage of models that have a populated description.
     """
 
-    min_model_documentation_coverage_pct = get_check_inputs(
-        check_config=check_config, request=request
-    )["check_config"]["min_model_documentation_coverage_pct"]
-
     num_models = len(models)
     models_with_description = []
     for model in models:
@@ -94,7 +102,7 @@ def check_model_documentation_coverage(models: List[DbtBouncerModel], request, c
     model_description_coverage_pct = (num_models_with_descriptions / num_models) * 100
 
     assert (
-        model_description_coverage_pct >= min_model_documentation_coverage_pct
+        model_description_coverage_pct >= min_model_documentation_coverage_pct  # type: ignore[operator]
     ), f"Only {model_description_coverage_pct}% of models have a populated description, this is less than the permitted minimum of {min_model_documentation_coverage_pct}%."
 
 
@@ -103,13 +111,14 @@ class CheckModelDocumentedInSameDirectory(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_documented_in_same_directory(request, model: DbtBouncerModel = None) -> None:
+@bouncer_check
+def check_model_documented_in_same_directory(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Models must be documented in the same directory where they are defined (i.e. `.yml` and `.sql` files are in the same directory).
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     model_doc_dir = model.patch_path[model.patch_path.find("models") :].split("/")[1:-1]
     model_sql_dir = model.path.split("/")[:-1]
 
@@ -126,21 +135,20 @@ class CheckModelCodeDoesNotContainRegexpPattern(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_model_code_does_not_contain_regexp_pattern(
-    request, check_config=None, model: DbtBouncerModel = None
-):
+    request: TopRequest,
+    model: Union[DbtBouncerModel, None] = None,
+    regexp_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     The raw code for a model must not match the specified regexp pattern.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
     assert (
-        re.compile(check_config["regexp_pattern"].strip(), flags=re.DOTALL).match(model.raw_code)
-        is None
-    ), f"`{model.unique_id.split('.')[-1]}` contains a banned string: `{check_config['regexp_pattern'].strip()}`."
+        re.compile(regexp_pattern.strip(), flags=re.DOTALL).match(model.raw_code) is None
+    ), f"`{model.unique_id.split('.')[-1]}` contains a banned string: `{regexp_pattern.strip()}`."
 
 
 class CheckModelDependsOnMultipleSources(BaseCheck):
@@ -148,13 +156,14 @@ class CheckModelDependsOnMultipleSources(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_depends_on_multiple_sources(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_depends_on_multiple_sources(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Models cannot reference more than one source.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     num_reffed_sources = sum(x.split(".")[0] == "source" for x in model.depends_on.nodes)
     assert (
         num_reffed_sources <= 1
@@ -175,27 +184,29 @@ class CheckModelDirectories(BaseModel):
 
 
 @pytest.mark.iterate_over_models
-def check_model_directories(request, check_config=None, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_directories(
+    request: TopRequest,
+    include: Union[None, str] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    permitted_sub_directories: Union[List[str], None] = None,
+    **kwargs,
+) -> None:
     """
     Only specified sub-directories are permitted.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    include = input_vars["check_config"]["include"]
-    model = input_vars["model"]
-    permitted_sub_directories = input_vars["check_config"]["permitted_sub_directories"]
-
     # Special case for `models` directory
     if include == "":
         assert (
-            model.path.split("/")[0] in permitted_sub_directories
+            model.path.split("/")[0] in permitted_sub_directories  # type: ignore[operator]
         ), f"{model.unique_id} is located in `{model.path.split('/')[0]}`, this is not a valid sub- directory."
     else:
         matched_path = re.compile(include.strip()).match(model.path)
         path_after_match = model.path[matched_path.end() + 1 :]  # type: ignore[union-attr]
 
         assert (
-            path_after_match.split("/")[0] in permitted_sub_directories
+            path_after_match.split("/")[0] in permitted_sub_directories  # type: ignore[operator]
         ), f"`{model.unique_id.split('.')[-1]}` is located in `{model.path.split('/')[0]}`, this is not a valid sub-directory."
 
 
@@ -204,13 +215,14 @@ class CheckModelHasContractsEnforced(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_has_contracts_enforced(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_has_contracts_enforced(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Model must have contracts enforced.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     assert (
         model.contract.enforced is True
     ), f"`{model.unique_id.split('.')[-1]}` does not have contracts enforced."
@@ -222,22 +234,20 @@ class CheckModelHasMetaKeys(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_has_meta_keys(request, check_config=None, model: DbtBouncerModel = None) -> None:
+@bouncer_check
+def check_model_has_meta_keys(
+    request: TopRequest,
+    keys: Union[Dict[str, Dict[str, str]], None] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     The `meta` config for models must have the specified keys.
     """
 
-    input_vars = get_check_inputs(
-        check_config=check_config,
-        model=model,
-        request=request,
-    )
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
     missing_keys = find_missing_meta_keys(
         meta_config=model.meta,
-        required_keys=check_config["keys"],
+        required_keys=keys,
     )
     assert (
         missing_keys == []
@@ -249,12 +259,14 @@ class CheckModelHasNoUpstreamDependencies(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_has_no_upstream_dependencies(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_has_no_upstream_dependencies(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Identify if models have no upstream dependencies as this likely indicates hard-coded tables references.
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
     assert (
         len(model.depends_on.nodes) > 0
     ), f"`{model.unique_id.split('.')[-1]}` has no upstream dependencies, this likely indicates hard-coded tables references."
@@ -266,15 +278,17 @@ class CheckModelHasTags(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_has_tags(request, check_config=None, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_has_tags(
+    request: TopRequest,
+    model: Union[DbtBouncerModel, None] = None,
+    tags: Union[List[str], None] = None,
+    **kwargs,
+) -> None:
     """
     Models must have the specified tags.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    model = input_vars["model"]
-    tags = input_vars["check_config"]["tags"]
-
     missing_tags = [tag for tag in tags if tag not in model.tags]
     assert (
         not missing_tags
@@ -294,23 +308,21 @@ class CheckModelHasUniqueTest(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_model_has_unique_test(
-    request, tests: List[DbtBouncerModel], check_config=None, model: DbtBouncerModel = None
-):
+    request: TopRequest,
+    tests: List[DbtBouncerModel],
+    accepted_uniqueness_tests: Union[List[str], None] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     Models must have a test for uniqueness of a column.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
-    accepted_uniqueness_tests = check_config["accepted_uniqueness_tests"]
-    logger.debug(f"{accepted_uniqueness_tests=}")
-
     num_unique_tests = sum(
         test.attached_node == model.unique_id
-        and test.test_metadata.name in accepted_uniqueness_tests
+        and test.test_metadata.name in accepted_uniqueness_tests  # type: ignore[operator]
         for test in tests
     )
     assert (
@@ -331,13 +343,16 @@ class CheckModelMaxChainedViews(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_model_max_chained_views(
     manifest_obj: DbtBouncerManifest,
     models: List[DbtBouncerModel],
-    request,
-    check_config=None,
-    model: DbtBouncerModel = None,
-):
+    request: TopRequest,
+    materializations_to_include: Union[List[str], None] = None,
+    max_chained_views: Union[int, None] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     Models cannot have more than the specified number of upstream dependents that are not tables (default: 3).
     """
@@ -384,11 +399,6 @@ def return_upstream_view_models(
             depth=depth,
         )
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    materializations_to_include = input_vars["check_config"]["materializations_to_include"]
-    max_chained_views = input_vars["check_config"]["max_chained_views"]
-    model = input_vars["model"]
-
     assert (
         len(
             return_upstream_view_models(
@@ -411,20 +421,22 @@ class CheckModelMaxFanout(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_model_max_fanout(
-    models: List[DbtBouncerModel], request, check_config=None, model: DbtBouncerModel = None
-):
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    max_downstream_models: Union[int, None] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     Models cannot have more than the specified number of downstream models (default: 3).
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    max_downstream_models = input_vars["check_config"]["max_downstream_models"]
-    model = input_vars["model"]
     num_downstream_models = sum(model.unique_id in m.depends_on.nodes for m in models)
 
     assert (
-        num_downstream_models <= max_downstream_models
+        num_downstream_models <= max_downstream_models  # type: ignore[operator]
     ), f"`{model.unique_id.split('.')[-1]}` has {num_downstream_models} downstream models, which is more than the permitted maximum of {max_downstream_models}."
 
 
@@ -442,31 +454,31 @@ class CheckModelMaxUpstreamDependencies(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
+@bouncer_check
 def check_model_max_upstream_dependencies(
-    request, check_config=None, model: DbtBouncerModel = None
-):
+    request: TopRequest,
+    max_upstream_macros: Union[int, None] = None,
+    max_upstream_models: Union[int, None] = None,
+    max_upstream_sources: Union[int, None] = None,
+    model: Union[DbtBouncerModel, None] = None,
+    **kwargs,
+) -> None:
     """
     Limit the number of upstream dependencies a model has. Default values are 5 for models, 5 for macros, and 1 for sources.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    max_upstream_macros = input_vars["check_config"]["max_upstream_macros"]
-    max_upstream_models = input_vars["check_config"]["max_upstream_models"]
-    max_upstream_sources = input_vars["check_config"]["max_upstream_sources"]
-    model = input_vars["model"]
-
     num_upstream_macros = len([m for m in model.depends_on.macros])
     num_upstream_models = len([m for m in model.depends_on.nodes if m.split(".")[0] == "model"])
     num_upstream_sources = len([m for m in model.depends_on.nodes if m.split(".")[0] == "source"])
 
     assert (
-        num_upstream_macros <= max_upstream_macros
+        num_upstream_macros <= max_upstream_macros  # type: ignore[operator]
     ), f"`{model.unique_id.split('.')[-1]}` has {num_upstream_macros} upstream macros, which is more than the permitted maximum of {max_upstream_macros}."
     assert (
-        num_upstream_models <= max_upstream_models
+        num_upstream_models <= max_upstream_models  # type: ignore[operator]
     ), f"`{model.unique_id.split('.')[-1]}` has {num_upstream_models} upstream models, which is more than the permitted maximum of {max_upstream_models}."
     assert (
-        num_upstream_sources <= max_upstream_sources
+        num_upstream_sources <= max_upstream_sources  # type: ignore[operator]
     ), f"`{model.unique_id.split('.')[-1]}` has {num_upstream_sources} upstream sources, which is more than the permitted maximum of {max_upstream_sources}."
 
 
@@ -478,18 +490,20 @@ class CheckModelNames(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_names(request, check_config=None, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_names(
+    request: TopRequest,
+    model: Union[DbtBouncerModel, None] = None,
+    model_name_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     Models must have a name that matches the supplied regex.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, model=model, request=request)
-    check_config = input_vars["check_config"]
-    model = input_vars["model"]
-
     assert (
-        re.compile(check_config["model_name_pattern"].strip()).match(model.name) is not None
-    ), f"`{model.unique_id.split('.')[-1]}` does not match the supplied regex `({check_config['model_name_pattern'].strip()})`."
+        re.compile(model_name_pattern.strip()).match(model.name) is not None
+    ), f"`{model.unique_id.split('.')[-1]}` does not match the supplied regex `{model_name_pattern.strip()})`."
 
 
 class CheckModelPropertyFileLocation(BaseCheck):
@@ -497,13 +511,14 @@ class CheckModelPropertyFileLocation(BaseCheck):
 
 
 @pytest.mark.iterate_over_models
-def check_model_property_file_location(request, model: DbtBouncerModel = None):
+@bouncer_check
+def check_model_property_file_location(
+    request: TopRequest, model: Union[DbtBouncerModel, None] = None, **kwargs
+) -> None:
     """
     Model properties files must follow the guidance provided by dbt [here](https://docs.getdbt.com/best-practices/how-we-structure/1-guide-overview).
     """
 
-    model = get_check_inputs(model=model, request=request)["model"]
-
     expected_substr = (
         "_".join(model.path.split("/")[:-1])
         .replace("staging", "stg")
@@ -533,17 +548,18 @@ class CheckModelsTestCoverage(BaseCheck):
     )
 
 
+@bouncer_check
 def check_model_test_coverage(
-    models: List[DbtBouncerModel], request, tests: List[DbtBouncerModel], check_config=None
-):
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    tests: List[DbtBouncerModel],
+    min_model_test_coverage_pct: Union[int, None] = None,
+    **kwargs,
+) -> None:
     """
     Set the minimum percentage of models that have at least one test.
     """
 
-    min_model_test_coverage_pct = get_check_inputs(check_config=check_config, request=request)[
-        "check_config"
-    ]["min_model_test_coverage_pct"]
-
     num_models = len(models)
     models_with_tests = []
     for model in models:
@@ -554,5 +570,5 @@ def check_model_test_coverage(
     model_test_coverage_pct = (num_models_with_tests / num_models) * 100
 
     assert (
-        model_test_coverage_pct >= min_model_test_coverage_pct
+        model_test_coverage_pct >= min_model_test_coverage_pct  # type: ignore[operator]
     ), f"Only {model_test_coverage_pct}% of models have at least one test, this is less than the permitted minimum of {min_model_test_coverage_pct}%."
diff --git a/src/dbt_bouncer/checks/manifest/check_sources.py b/src/dbt_bouncer/checks/manifest/check_sources.py
index 3da3f183..abaf2646 100644
--- a/src/dbt_bouncer/checks/manifest/check_sources.py
+++ b/src/dbt_bouncer/checks/manifest/check_sources.py
@@ -1,12 +1,15 @@
+# mypy: disable-error-code="union-attr"
+
 import re
 from typing import Any, Dict, List, Literal, Optional, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from pydantic import Field
 
 from dbt_bouncer.conf_validator_base import BaseCheck
 from dbt_bouncer.parsers import DbtBouncerModel, DbtBouncerSource
-from dbt_bouncer.utils import find_missing_meta_keys, get_check_inputs
+from dbt_bouncer.utils import bouncer_check, find_missing_meta_keys
 
 
 class CheckSourceDescriptionPopulated(BaseCheck):
@@ -14,13 +17,14 @@ class CheckSourceDescriptionPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_description_populated(request, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_description_populated(
+    request: TopRequest, source: Union[DbtBouncerSource, None] = None, **kwargs
+) -> None:
     """
     Sources must have a populated description.
     """
 
-    source = get_check_inputs(source=source, request=request)["source"]
-
     assert (
         len(source.description.strip()) > 4
     ), f"`{source.unique_id}` does not have a populated description."
@@ -31,13 +35,14 @@ class CheckSourceFreshnessPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_freshness_populated(request, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_freshness_populated(
+    request: TopRequest, source: Union[DbtBouncerSource, None] = None, **kwargs
+) -> None:
     """
     Sources must have a populated freshness.
     """
 
-    source = get_check_inputs(source=source, request=request)["source"]
-
     assert (
         source.freshness.error_after.count is not None
         and source.freshness.error_after.period is not None
@@ -53,24 +58,20 @@ class CheckSourceHasMetaKeys(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
+@bouncer_check
 def check_source_has_meta_keys(
-    request, check_config=None, source: DbtBouncerSource = None
+    request,
+    keys: Union[Dict[str, Dict[str, str]], None] = None,
+    source: Union[DbtBouncerSource, None] = None,
+    **kwargs,
 ) -> None:
     """
     The `meta` config for sources must have the specified keys.
     """
 
-    input_vars = get_check_inputs(
-        check_config=check_config,
-        request=request,
-        source=source,
-    )
-    check_config = input_vars["check_config"]
-    source = input_vars["source"]
-
     missing_keys = find_missing_meta_keys(
         meta_config=source.meta,
-        required_keys=check_config["keys"],
+        required_keys=keys,
     )
     assert (
         missing_keys == []
@@ -83,15 +84,17 @@ class CheckSourceHasTags(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_has_tags(request, check_config=None, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_has_tags(
+    request: TopRequest,
+    source: Union[DbtBouncerSource, None] = None,
+    tags: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     Sources must have the specified tags.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, source=source, request=request)
-    source = input_vars["source"]
-    tags = input_vars["check_config"]["tags"]
-
     missing_tags = [tag for tag in tags if tag not in source.tags]
     assert not missing_tags, f"`{source.unique_id}` is missing required tags: {missing_tags}."
 
@@ -101,13 +104,14 @@ class CheckSourceLoaderPopulated(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_loader_populated(request, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_loader_populated(
+    request: TopRequest, source: Union[DbtBouncerSource, None] = None, **kwargs
+) -> None:
     """
     Sources must have a populated loader.
     """
 
-    source = get_check_inputs(source=source, request=request)["source"]
-
     assert source.loader != "", f"`{source.unique_id}` does not have a populated loader."
 
 
@@ -117,18 +121,20 @@ class CheckSourceNames(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_names(request, check_config=None, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_names(
+    request: TopRequest,
+    source: Union[DbtBouncerSource, None] = None,
+    source_name_pattern: Union[None, str] = None,
+    **kwargs,
+) -> None:
     """
     Sources must have a name that matches the supplied regex.
     """
 
-    input_vars = get_check_inputs(check_config=check_config, source=source, request=request)
-    check_config = input_vars["check_config"]
-    source = input_vars["source"]
-
     assert (
-        re.compile(check_config["source_name_pattern"].strip()).match(source.name) is not None
-    ), f"`{source.unique_id.split('.')[0]}` does not match the supplied regex `({check_config['source_name_pattern'].strip()})`."
+        re.compile(source_name_pattern.strip()).match(source.name) is not None
+    ), f"`{source.unique_id.split('.')[0]}` does not match the supplied regex `({source_name_pattern.strip()})`."
 
 
 class CheckSourceNotOrphaned(BaseCheck):
@@ -136,18 +142,17 @@ class CheckSourceNotOrphaned(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
+@bouncer_check
 def check_source_not_orphaned(
-    models: List[DbtBouncerModel], request, source: DbtBouncerSource = None
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    source: Union[DbtBouncerSource, None] = None,
+    **kwargs,
 ) -> None:
     """
     Sources must be referenced in at least one model.
     """
 
-    source = get_check_inputs(
-        request=request,
-        source=source,
-    )["source"]
-
     num_refs = sum(source.unique_id in model.depends_on.nodes for model in models)
     assert (
         num_refs >= 1
@@ -159,13 +164,14 @@ class CheckSourcePropertyFileLocation(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
-def check_source_property_file_location(request, source: DbtBouncerSource = None):
+@bouncer_check
+def check_source_property_file_location(
+    request: TopRequest, source: Union[DbtBouncerSource, None] = None, **kwargs
+) -> None:
     """
     Source properties files must follow the guidance provided by dbt [here](https://docs.getdbt.com/best-practices/how-we-structure/1-guide-overview).
     """
 
-    source = get_check_inputs(source=source, request=request)["source"]
-
     path_cleaned = source.path.replace("models/staging", "")
     expected_substring = "_".join(path_cleaned.split("/")[:-1])
 
@@ -185,18 +191,17 @@ class CheckSourceUsedByModelsInSameDirectory(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
+@bouncer_check
 def check_source_used_by_models_in_same_directory(
-    models: List[DbtBouncerModel], request, source: DbtBouncerSource = None
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    source: Union[DbtBouncerSource, None] = None,
+    **kwargs,
 ) -> None:
     """
     Sources can only be referenced by models that are located in the same directory where the source is defined.
     """
 
-    source = get_check_inputs(
-        request=request,
-        source=source,
-    )["source"]
-
     reffed_models_not_in_same_dir = []
     for model in models:
         if (
@@ -215,17 +220,16 @@ class CheckSourceUsedByOnlyOneModel(BaseCheck):
 
 
 @pytest.mark.iterate_over_sources
+@bouncer_check
 def check_source_used_by_only_one_model(
-    models: List[DbtBouncerModel], request, source: DbtBouncerSource = None
+    models: List[DbtBouncerModel],
+    request: TopRequest,
+    source: Union[DbtBouncerSource, None] = None,
+    **kwargs,
 ) -> None:
     """
     Each source can be referenced by a maximum of one model.
     """
 
-    source = get_check_inputs(
-        request=request,
-        source=source,
-    )["source"]
-
     num_refs = sum(source.unique_id in model.depends_on.nodes for model in models)
     assert num_refs <= 1, f"Source `{source.unique_id}` is referenced by more than one model."
diff --git a/src/dbt_bouncer/checks/run_results/check_run_results.py b/src/dbt_bouncer/checks/run_results/check_run_results.py
index 31db339b..0abff9e8 100644
--- a/src/dbt_bouncer/checks/run_results/check_run_results.py
+++ b/src/dbt_bouncer/checks/run_results/check_run_results.py
@@ -1,34 +1,35 @@
-from typing import Literal
+# mypy: disable-error-code="union-attr"
+
+from typing import Literal, Union
 
 import pytest
+from _pytest.fixtures import TopRequest
 from pydantic import Field
 
 from dbt_bouncer.conf_validator_base import BaseCheck
 from dbt_bouncer.parsers import DbtBouncerResult
-from dbt_bouncer.utils import get_check_inputs
+from dbt_bouncer.utils import bouncer_check
 
 
 class CheckRunResultsMaxGigabytesBilled(BaseCheck):
-    max_gigabytes_billed: int = Field(
+    max_gigabytes_billed: float = Field(
         description="The maximum gigagbytes billed allowed for a node."
     )
     name: Literal["check_run_results_max_gigabytes_billed"]
 
 
 @pytest.mark.iterate_over_run_results
+@bouncer_check
 def check_run_results_max_gigabytes_billed(
-    request, check_config=None, run_result: DbtBouncerResult = None
+    request: TopRequest,
+    max_gigabytes_billed: Union[float, None] = None,
+    run_result: Union[DbtBouncerResult, None] = None,
+    **kwargs,
 ) -> None:
     """
     Each result can have a maximum number of gigabytes billed. Note that this only works for the `dbt-bigquery` adapter.
     """
 
-    input_vars = get_check_inputs(
-        check_config=check_config, run_result=run_result, request=request
-    )
-    check_config = input_vars["check_config"]
-    run_result = input_vars["run_result"]
-
     try:
         gigabytes_billed = run_result.adapter_response["bytes_billed"] / (1000**3)
     except KeyError:
@@ -37,8 +38,8 @@ def check_run_results_max_gigabytes_billed(
         )
 
     assert (
-        gigabytes_billed < check_config["max_gigabytes_billed"]
-    ), f"`{run_result.unique_id.split('.')[-2]}` results in ({gigabytes_billed} billed bytes, this is greater than permitted ({check_config['max_gigabytes_billed']})."
+        gigabytes_billed < max_gigabytes_billed
+    ), f"`{run_result.unique_id.split('.')[-2]}` results in ({gigabytes_billed} billed bytes, this is greater than permitted ({max_gigabytes_billed})."
 
 
 class CheckRunResultsMaxExecutionTime(BaseCheck):
@@ -49,19 +50,17 @@ class CheckRunResultsMaxExecutionTime(BaseCheck):
 
 
 @pytest.mark.iterate_over_run_results
+@bouncer_check
 def check_run_results_max_execution_time(
-    request, check_config=None, run_result: DbtBouncerResult = None
+    request: TopRequest,
+    max_execution_time: Union[float, None] = None,
+    run_result: Union[DbtBouncerResult, None] = None,
+    **kwargs,
 ) -> None:
     """
     Each result can take a maximum duration (seconds).
     """
 
-    input_vars = get_check_inputs(
-        check_config=check_config, run_result=run_result, request=request
-    )
-    check_config = input_vars["check_config"]
-    run_result = input_vars["run_result"]
-
     assert (
-        run_result.execution_time <= check_config["max_execution_time"]
-    ), f"`{run_result.unique_id.split('.')[-1]}` has an execution time ({run_result.execution_time} greater than permitted ({check_config['max_execution_time']}s)."
+        run_result.execution_time <= max_execution_time
+    ), f"`{run_result.unique_id.split('.')[-1]}` has an execution time ({run_result.execution_time} greater than permitted ({max_execution_time}s)."
diff --git a/src/dbt_bouncer/utils.py b/src/dbt_bouncer/utils.py
index af03776c..6522b840 100644
--- a/src/dbt_bouncer/utils.py
+++ b/src/dbt_bouncer/utils.py
@@ -1,22 +1,161 @@
+# mypy: disable-error-code="union-attr"
+
 import contextlib
 import os
 import re
+from functools import wraps
 from pathlib import Path
-from typing import Any, Dict, List, Mapping, Union
+from typing import Any, List, Mapping, Union
 
 import toml
 import yaml
-from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Exposures, Macros
+from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Exposures
 
 from dbt_bouncer.logger import logger
 from dbt_bouncer.parsers import (
-    DbtBouncerCatalogNode,
+    DbtBouncerManifest,
     DbtBouncerModel,
-    DbtBouncerResult,
     DbtBouncerSource,
+    DbtBouncerTest,
 )
 
 
+def bouncer_check(func):
+    @wraps(func)
+    def wrapper(
+        exposures: Union[List[Exposures], None] = None,
+        manifest_obj: Union[DbtBouncerManifest, None] = None,
+        models: Union[List[DbtBouncerModel], None] = None,
+        sources: Union[List[DbtBouncerSource], None] = None,
+        tests: Union[List[DbtBouncerTest], None] = None,
+        **kwargs,
+    ):
+        request = kwargs.get("request")
+        if request is not None:
+            # From provided check_config
+            accepted_uniqueness_tests = request.node.check_config.get("accepted_uniqueness_tests")
+            access = request.node.check_config.get("access")
+            column_name_pattern = request.node.check_config.get("column_name_pattern")
+            include = request.node.check_config.get("include")
+            keys = request.node.check_config.get("keys")
+            materializations_to_include = request.node.check_config.get(
+                "materializations_to_include"
+            )
+            max_chained_views = request.node.check_config.get("max_chained_views")
+            max_downstream_models = request.node.check_config.get("max_downstream_models")
+            max_execution_time = request.node.check_config.get("max_execution_time")
+            max_gigabytes_billed = request.node.check_config.get("max_gigabytes_billed")
+            max_upstream_macros = request.node.check_config.get("max_upstream_macros")
+            max_upstream_models = request.node.check_config.get("max_upstream_models")
+            max_upstream_sources = request.node.check_config.get("max_upstream_sources")
+            min_model_documentation_coverage_pct = request.node.check_config.get(
+                "min_model_documentation_coverage_pct"
+            )
+            min_model_test_coverage_pct = request.node.check_config.get(
+                "min_model_test_coverage_pct"
+            )
+            model_name_pattern = request.node.check_config.get("model_name_pattern")
+            permitted_sub_directories = request.node.check_config.get("permitted_sub_directories")
+            project_name_pattern = request.node.check_config.get("project_name_pattern")
+            regexp_pattern = request.node.check_config.get("regexp_pattern")
+            source_name_pattern = request.node.check_config.get("source_name_pattern")
+            tags = request.node.check_config.get("tags")
+            test_name = request.node.check_config.get("test_name")
+            types = request.node.check_config.get("types")
+            upstream_path_pattern = request.node.check_config.get("upstream_path_pattern")
+
+            # Variables from `iterate_over_*` markers
+            catalog_node = getattr(request.node.catalog_node, "node", lambda: None)
+            catalog_source = getattr(request.node.catalog_source, "node", lambda: None)
+            exposure = request.node.exposure
+            macro = request.node.macro
+            model = getattr(request.node.model, "model", lambda: None)
+            run_result = getattr(request.node.run_result, "result", lambda: None)
+            source = getattr(request.node.source, "source", lambda: None)
+        else:
+            # From provided check_config
+            accepted_uniqueness_tests = kwargs.get("accepted_uniqueness_tests")
+            access = kwargs.get("access")
+            column_name_pattern = kwargs.get("column_name_pattern")
+            include = kwargs.get("include")
+            keys = kwargs.get("keys")
+            materializations_to_include = kwargs.get("materializations_to_include")
+            max_chained_views = kwargs.get("max_chained_views")
+            max_downstream_models = kwargs.get("max_downstream_models")
+            max_execution_time = kwargs.get("max_execution_time")
+            max_gigabytes_billed = kwargs.get("max_gigabytes_billed")
+            max_upstream_macros = kwargs.get("max_upstream_macros")
+            max_upstream_models = kwargs.get("max_upstream_models")
+            max_upstream_sources = kwargs.get("max_upstream_sources")
+            min_model_documentation_coverage_pct = kwargs.get(
+                "min_model_documentation_coverage_pct"
+            )
+            min_model_test_coverage_pct = kwargs.get("min_model_test_coverage_pct")
+            model_name_pattern = kwargs.get("model_name_pattern")
+            permitted_sub_directories = kwargs.get("permitted_sub_directories")
+            project_name_pattern = kwargs.get("project_name_pattern")
+            regexp_pattern = kwargs.get("regexp_pattern")
+            source_name_pattern = kwargs.get("source_name_pattern")
+            tags = kwargs.get("tags")
+            test_name = kwargs.get("test_name")
+            types = kwargs.get("types")
+            upstream_path_pattern = kwargs.get("upstream_path_pattern")
+
+            # Variables from `iterate_over_*` markers
+            catalog_node = kwargs.get("catalog_node")
+            catalog_source = kwargs.get("catalog_source")
+            exposure = kwargs.get("exposure")
+            macro = kwargs.get("macro")
+            model = kwargs.get("model")
+            run_result = kwargs.get("run_result")
+            source = kwargs.get("source")
+
+        func(
+            # From provided check_config
+            accepted_uniqueness_tests=accepted_uniqueness_tests,
+            access=access,
+            column_name_pattern=column_name_pattern,
+            include=include,
+            keys=keys,
+            materializations_to_include=materializations_to_include,
+            max_chained_views=max_chained_views,
+            max_downstream_models=max_downstream_models,
+            max_execution_time=max_execution_time,
+            max_gigabytes_billed=max_gigabytes_billed,
+            max_upstream_macros=max_upstream_macros,
+            max_upstream_models=max_upstream_models,
+            max_upstream_sources=max_upstream_sources,
+            min_model_documentation_coverage_pct=min_model_documentation_coverage_pct,
+            min_model_test_coverage_pct=min_model_test_coverage_pct,
+            model_name_pattern=model_name_pattern,
+            permitted_sub_directories=permitted_sub_directories,
+            project_name_pattern=project_name_pattern,
+            regexp_pattern=regexp_pattern,
+            request=request,
+            source_name_pattern=source_name_pattern,
+            tags=tags,
+            test_name=test_name,
+            types=types,
+            upstream_path_pattern=upstream_path_pattern,
+            # Variables from `iterate_over_*` markers
+            catalog_node=catalog_node,
+            catalog_source=catalog_source,
+            exposure=exposure,
+            model=model,
+            macro=macro,
+            run_result=run_result,
+            source=source,
+            # Fixtures from `FixturePlugin`
+            exposures=exposures,
+            manifest_obj=manifest_obj,
+            models=models,
+            sources=sources,
+            tests=tests,
+        )
+
+    return wrapper
+
+
 def create_github_comment_file(failed_checks: List[List[str]]) -> None:
     """
     Create a markdown file containing a comment for GitHub.
@@ -73,64 +212,6 @@ def flatten(structure: Any, key: str = "", path: str = "", flattened=None):
     return flattened
 
 
-def get_check_inputs(
-    catalog_node: DbtBouncerCatalogNode = None,
-    catalog_source: DbtBouncerCatalogNode = None,
-    check_config: Union[Dict[str, Union[Dict[str, str], str]], None] = None,
-    exposure: Exposures = None,
-    macro: Macros = None,
-    model: DbtBouncerModel = None,
-    request=None,
-    run_result: DbtBouncerResult = None,
-    source: DbtBouncerSource = None,
-) -> Dict[
-    str,
-    Union[
-        DbtBouncerCatalogNode,
-        Dict[str, Union[Dict[str, str], str]],
-        Exposures,
-        Macros,
-        DbtBouncerModel,
-        DbtBouncerResult,
-        DbtBouncerSource,
-    ],
-]:
-    """
-    Helper function that is used to account for the difference in how arguments are passed to check functions
-    when they are run by `dbt-bouncer` and when they are called by pytest.
-    """
-
-    if request is not None:
-        catalog_node = getattr(request.node.catalog_node, "node", lambda: None)
-        catalog_source = getattr(request.node.catalog_source, "node", lambda: None)
-        check_config = request.node.check_config
-        exposure = request.node.exposure
-        macro = request.node.macro
-        model = getattr(request.node.model, "model", lambda: None)
-        run_result = getattr(request.node.run_result, "result", lambda: None)
-        source = getattr(request.node.source, "source", lambda: None)
-    else:
-        catalog_node = getattr(catalog_node, "node", lambda: None)
-        catalog_source = getattr(catalog_source, "node", lambda: None)
-        check_config = check_config
-        exposure = exposure
-        macro = macro
-        model = model
-        run_result = getattr(run_result, "result", lambda: None)
-        source = source
-
-    return {
-        "catalog_node": catalog_node,
-        "catalog_source": catalog_source,
-        "check_config": check_config,
-        "exposure": exposure,
-        "macro": macro,
-        "model": model,
-        "run_result": run_result,
-        "source": source,
-    }
-
-
 def get_dbt_bouncer_config(config_file: str, config_file_source: str) -> Mapping[str, Any]:
     """
     Get the config for dbt-bouncer. This is fetched from (in order):


Test patch:
diff --git a/tests/unit/checks/catalog/test_catalog_sources.py b/tests/unit/checks/catalog/test_catalog_sources.py
index 689fdd74..33af055a 100644
--- a/tests/unit/checks/catalog/test_catalog_sources.py
+++ b/tests/unit/checks/catalog/test_catalog_sources.py
@@ -1,42 +1,38 @@
 from contextlib import nullcontext as does_not_raise
 
 import pytest
+from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogTable
 from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Sources
 
 from dbt_bouncer.checks.catalog.check_catalog_sources import (
     check_source_columns_are_all_documented,
 )
-from dbt_bouncer.parsers import DbtBouncerCatalogNode
 
 
 @pytest.mark.parametrize(
     "catalog_source, sources, expectation",
     [
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                            "col_2": {
-                                "index": 2,
-                                "name": "col_2",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2": {
+                            "index": 2,
+                            "name": "col_2",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "source.package_name.source_1.table_1",
                     },
-                    "path": "path/to/source_1.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "source.package_name.source_1.table_1",
                 }
             ),
@@ -69,30 +65,26 @@
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                            "col_2": {
-                                "index": 1,
-                                "name": "col_2",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2": {
+                            "index": 1,
+                            "name": "col_2",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "source.package_name.source_1.table_1",
                     },
-                    "path": "path/to/source_1.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "source.package_name.source_1.table_1",
                 }
             ),
diff --git a/tests/unit/checks/catalog/test_columns.py b/tests/unit/checks/catalog/test_columns.py
index 52008772..569f3eda 100644
--- a/tests/unit/checks/catalog/test_columns.py
+++ b/tests/unit/checks/catalog/test_columns.py
@@ -1,6 +1,7 @@
 from contextlib import nullcontext as does_not_raise
 
 import pytest
+from dbt_artifacts_parser.parsers.catalog.catalog_v1 import CatalogTable
 from dbt_artifacts_parser.parsers.manifest.manifest_v12 import Nodes4, Nodes6
 
 from dbt_bouncer.checks.catalog.check_columns import (
@@ -9,36 +10,32 @@
     check_columns_are_all_documented,
     check_columns_are_documented_in_public_models,
 )
-from dbt_bouncer.parsers import DbtBouncerCatalogNode
 
 
 @pytest.mark.parametrize(
-    "catalog_node, check_config, tests, expectation",
+    "catalog_node, column_name_pattern, test_name, tests, expectation",
     [
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                        },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
-            {"column_name_pattern": ".*_1$", "test_name": "unique"},
+            ".*_1$",
+            "unique",
             [
                 Nodes6(
                     **{
@@ -68,29 +65,26 @@
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
-                        },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
-            {"column_name_pattern": ".*_1$", "test_name": "unique"},
+            ".*_1$",
+            "unique",
             [
                 Nodes6(
                     **{
@@ -116,10 +110,16 @@
         ),
     ],
 )
-def test_check_column_has_specified_test(catalog_node, check_config, tests, expectation):
+def test_check_column_has_specified_test(
+    catalog_node, column_name_pattern, test_name, tests, expectation
+):
     with expectation:
         check_column_has_specified_test(
-            catalog_node=catalog_node, check_config=check_config, tests=tests, request=None
+            catalog_node=catalog_node,
+            column_name_pattern=column_name_pattern,
+            test_name=test_name,
+            tests=tests,
+            request=None,
         )
 
 
@@ -127,30 +127,26 @@ def test_check_column_has_specified_test(catalog_node, check_config, tests, expe
     "catalog_node, models, expectation",
     [
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                            "col_2": {
-                                "index": 2,
-                                "name": "col_2",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2": {
+                            "index": 2,
+                            "name": "col_2",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
@@ -185,30 +181,26 @@ def test_check_column_has_specified_test(catalog_node, check_config, tests, expe
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                            "col_2": {
-                                "index": 2,
-                                "name": "col_2",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2": {
+                            "index": 2,
+                            "name": "col_2",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_2",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_2",
                 }
             ),
@@ -248,25 +240,21 @@ def test_check_columns_are_all_documented(catalog_node, models, expectation):
     "catalog_node, models, expectation",
     [
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                        },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
@@ -298,30 +286,26 @@ def test_check_columns_are_all_documented(catalog_node, models, expectation):
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "INTEGER",
-                            },
-                            "col_2": {
-                                "index": 2,
-                                "name": "col_2",
-                                "type": "INTEGER",
-                            },
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "INTEGER",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2": {
+                            "index": 2,
+                            "name": "col_2",
+                            "type": "INTEGER",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
@@ -368,100 +352,96 @@ def test_check_columns_are_documented_in_public_models(catalog_node, models, exp
 
 
 @pytest.mark.parametrize(
-    "catalog_node, check_config, expectation",
+    "catalog_node, column_name_pattern, types, expectation",
     [
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1_date": {
-                                "index": 1,
-                                "name": "col_1_date",
-                                "type": "DATE",
-                            },
-                        },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                    "columns": {
+                        "col_1_date": {
+                            "index": 1,
+                            "name": "col_1_date",
+                            "type": "DATE",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
-            {"column_name_pattern": ".*_date$", "types": ["DATE"]},
+            ".*_date$",
+            ["DATE"],
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1_date": {
-                                "index": 1,
-                                "name": "col_1_date",
-                                "type": "DATE",
-                            },
-                            "col_2_date": {
-                                "index": 2,
-                                "name": "col_2_date",
-                                "type": "DATE",
-                            },
-                            "col_3": {
-                                "index": 3,
-                                "name": "col_3",
-                                "type": "VARCHAR",
-                            },
+                    "columns": {
+                        "col_1_date": {
+                            "index": 1,
+                            "name": "col_1_date",
+                            "type": "DATE",
                         },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                        "col_2_date": {
+                            "index": 2,
+                            "name": "col_2_date",
+                            "type": "DATE",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
+                        "col_3": {
+                            "index": 3,
+                            "name": "col_3",
+                            "type": "VARCHAR",
+                        },
+                    },
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
-            {"column_name_pattern": ".*_date$", "types": ["DATE"]},
+            ".*_date$",
+            ["DATE"],
             does_not_raise(),
         ),
         (
-            DbtBouncerCatalogNode(
+            CatalogTable(
                 **{
-                    "node": {
-                        "columns": {
-                            "col_1": {
-                                "index": 1,
-                                "name": "col_1",
-                                "type": "DATE",
-                            },
-                        },
-                        "metadata": {
-                            "name": "table_1",
-                            "schema": "main",
-                            "type": "VIEW",
+                    "columns": {
+                        "col_1": {
+                            "index": 1,
+                            "name": "col_1",
+                            "type": "DATE",
                         },
-                        "stats": {},
-                        "unique_id": "model.package_name.model_1",
                     },
-                    "path": "marts/finance/_models.yml",
+                    "metadata": {
+                        "name": "table_1",
+                        "schema": "main",
+                        "type": "VIEW",
+                    },
+                    "stats": {},
                     "unique_id": "model.package_name.model_1",
                 }
             ),
-            {"column_name_pattern": ".*_date$", "types": ["DATE"]},
+            ".*_date$",
+            ["DATE"],
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_column_name_complies_to_column_type(catalog_node, check_config, expectation):
+def test_check_column_name_complies_to_column_type(
+    catalog_node, column_name_pattern, types, expectation
+):
     with expectation:
         check_column_name_complies_to_column_type(
-            catalog_node=catalog_node, check_config=check_config, request=None
+            catalog_node=catalog_node,
+            column_name_pattern=column_name_pattern,
+            types=types,
+            request=None,
         )
diff --git a/tests/unit/checks/manifest/test_exposures.py b/tests/unit/checks/manifest/test_exposures.py
index 9b95fab6..0eb8706e 100644
--- a/tests/unit/checks/manifest/test_exposures.py
+++ b/tests/unit/checks/manifest/test_exposures.py
@@ -112,10 +112,9 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
 
 
 @pytest.mark.parametrize(
-    "check_config, exposure, models, expectation",
+    "exposure, materializations_to_include, models, expectation",
     [
         (
-            {"materializations_to_include": ["ephemeral", "view"]},
             Exposures(
                 **{
                     "depends_on": {"nodes": ["model.package_name.model_1"]},
@@ -130,6 +129,7 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
                     "unique_id": "exposure.package_name.exposure_1",
                 },
             ),
+            ["ephemeral", "view"],
             [
                 Nodes4(
                     **{
@@ -163,7 +163,6 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
             does_not_raise(),
         ),
         (
-            {"materializations_to_include": ["ephemeral", "view"]},
             Exposures(
                 **{
                     "depends_on": {
@@ -180,6 +179,7 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
                     "unique_id": "exposure.package_name.exposure_1",
                 },
             ),
+            ["ephemeral", "view"],
             [
                 Nodes4(
                     **{
@@ -241,7 +241,6 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
             pytest.raises(AssertionError),
         ),
         (
-            {"materializations_to_include": ["ephemeral", "view"]},
             Exposures(
                 **{
                     "depends_on": {"nodes": ["model.package_name.model_1"]},
@@ -256,6 +255,7 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
                     "unique_id": "exposure.package_name.exposure_1",
                 },
             ),
+            ["ephemeral", "view"],
             [
                 Nodes4(
                     **{
@@ -290,8 +290,11 @@ def test_check_exposure_based_on_non_public_models(exposure, models, expectation
         ),
     ],
 )
-def test_check_exposure_based_on_view(check_config, exposure, models, expectation):
+def test_check_exposure_based_on_view(exposure, materializations_to_include, models, expectation):
     with expectation:
         check_exposure_based_on_view(
-            check_config=check_config, exposure=exposure, models=models, request=None
+            exposure=exposure,
+            materializations_to_include=materializations_to_include,
+            models=models,
+            request=None,
         )
diff --git a/tests/unit/checks/manifest/test_lineage.py b/tests/unit/checks/manifest/test_lineage.py
index 96f65a75..32ee55e2 100644
--- a/tests/unit/checks/manifest/test_lineage.py
+++ b/tests/unit/checks/manifest/test_lineage.py
@@ -11,12 +11,9 @@
 
 
 @pytest.mark.parametrize(
-    "check_config, manifest_obj, model, models, expectation",
+    "manifest_obj, model, models, upstream_path_pattern, expectation",
     [
         (
-            {
-                "upstream_path_pattern": "^staging",
-            },
             "manifest_obj",
             Nodes4(
                 **{
@@ -63,12 +60,10 @@
                     }
                 )
             ],
+            "^staging",
             does_not_raise(),
         ),
         (
-            {
-                "upstream_path_pattern": "^staging",
-            },
             "manifest_obj",
             Nodes4(
                 **{
@@ -93,12 +88,10 @@
                 }
             ),
             [],
+            "^staging",
             does_not_raise(),
         ),
         (
-            {
-                "upstream_path_pattern": "^intermediate",
-            },
             "manifest_obj",
             Nodes4(
                 **{
@@ -145,20 +138,21 @@
                     }
                 ),
             ],
+            "^intermediate",
             pytest.raises(AssertionError),
         ),
     ],
     indirect=["manifest_obj"],
 )
 def test_check_lineage_permitted_upstream_models(
-    check_config, manifest_obj, model, models, expectation
+    manifest_obj, model, models, upstream_path_pattern, expectation
 ):
     with expectation:
         check_lineage_permitted_upstream_models(
-            check_config=check_config,
             manifest_obj=manifest_obj,
             model=model,
             models=models,
+            upstream_path_pattern=upstream_path_pattern,
             request=None,
         )
 
diff --git a/tests/unit/checks/manifest/test_macros.py b/tests/unit/checks/manifest/test_macros.py
index b1a43e83..3c9563e7 100644
--- a/tests/unit/checks/manifest/test_macros.py
+++ b/tests/unit/checks/manifest/test_macros.py
@@ -120,10 +120,9 @@ def test_check_macro_arguments_description_populated(macro, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, macro, expectation",
+    "macro, regexp_pattern, expectation",
     [
         (
-            {"regexp_pattern": ".*[i][f][n][u][l][l].*"},
             Macros(
                 **{
                     "arguments": [
@@ -145,12 +144,10 @@ def test_check_macro_arguments_description_populated(macro, expectation):
                     "unique_id": "macro.package_name.macro_1",
                 }
             ),
+            ".*[i][f][n][u][l][l].*",
             does_not_raise(),
         ),
         (
-            {
-                "regexp_pattern": ".*[i][f][n][u][l][l].*",
-            },
             Macros(
                 **{
                     "arguments": [
@@ -172,14 +169,15 @@ def test_check_macro_arguments_description_populated(macro, expectation):
                     "unique_id": "macro.package_name.macro_1",
                 }
             ),
+            ".*[i][f][n][u][l][l].*",
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_macro_code_does_not_contain_regexp_pattern(check_config, macro, expectation):
+def test_check_macro_code_does_not_contain_regexp_pattern(macro, regexp_pattern, expectation):
     with expectation:
         check_macro_code_does_not_contain_regexp_pattern(
-            check_config=check_config, macro=macro, request=None
+            macro=macro, regexp_pattern=regexp_pattern, request=None
         )
 
 
diff --git a/tests/unit/checks/manifest/test_metadata.py b/tests/unit/checks/manifest/test_metadata.py
index 79254a41..ef3ceae4 100644
--- a/tests/unit/checks/manifest/test_metadata.py
+++ b/tests/unit/checks/manifest/test_metadata.py
@@ -6,29 +6,25 @@
 
 
 @pytest.mark.parametrize(
-    "check_config, manifest_obj, expectation",
+    "manifest_obj, project_name_pattern, expectation",
     [
         (
-            {
-                "project_name_pattern": "^dbt_bouncer_",
-            },
             "manifest_obj",
+            "^dbt_bouncer_",
             does_not_raise(),
         ),
         (
-            {
-                "project_name_pattern": "^company_",
-            },
             "manifest_obj",
+            "^company_",
             pytest.raises(AssertionError),
         ),
     ],
     indirect=["manifest_obj"],
 )
-def test_check_project_name(check_config, manifest_obj, expectation, request):
+def test_check_project_name(manifest_obj, project_name_pattern, expectation):
     with expectation:
         check_project_name(
-            check_config=check_config,
             manifest_obj=manifest_obj,
+            project_name_pattern=project_name_pattern,
             request=None,
         )
diff --git a/tests/unit/checks/manifest/test_models.py b/tests/unit/checks/manifest/test_models.py
index f47252be..c982e1d4 100644
--- a/tests/unit/checks/manifest/test_models.py
+++ b/tests/unit/checks/manifest/test_models.py
@@ -27,12 +27,10 @@
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "access, model, expectation",
     [
         (
-            {
-                "access": "public",
-            },
+            "public",
             Nodes4(
                 **{
                     "access": "public",
@@ -58,7 +56,7 @@
             does_not_raise(),
         ),
         (
-            {"access": "public"},
+            "public",
             Nodes4(
                 **{
                     "access": "protected",
@@ -85,9 +83,9 @@
         ),
     ],
 )
-def test_check_model_access(check_config, model, expectation):
+def test_check_model_access(access, model, expectation):
     with expectation:
-        check_model_access(check_config=check_config, model=model, request=None)
+        check_model_access(access=access, model=model, request=None)
 
 
 @pytest.mark.parametrize(
@@ -241,12 +239,10 @@ def test_check_model_depends_on_multiple_sources(model, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, models, expectation",
+    "min_model_documentation_coverage_pct, models, expectation",
     [
         (
-            {
-                "min_model_documentation_coverage_pct": 100,
-            },
+            100,
             [
                 Nodes4(
                     **{
@@ -274,9 +270,7 @@ def test_check_model_depends_on_multiple_sources(model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "min_model_documentation_coverage_pct": 50,
-            },
+            50,
             [
                 Nodes4(
                     **{
@@ -326,9 +320,7 @@ def test_check_model_depends_on_multiple_sources(model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "min_model_documentation_coverage_pct": 100,
-            },
+            100,
             [
                 Nodes4(
                     **{
@@ -357,9 +349,15 @@ def test_check_model_depends_on_multiple_sources(model, expectation):
         ),
     ],
 )
-def test_check_model_documentation_coverage(check_config, models, expectation):
+def test_check_model_documentation_coverage(
+    min_model_documentation_coverage_pct, models, expectation
+):
     with expectation:
-        check_model_documentation_coverage(check_config=check_config, models=models, request=None)
+        check_model_documentation_coverage(
+            min_model_documentation_coverage_pct=min_model_documentation_coverage_pct,
+            models=models,
+            request=None,
+        )
 
 
 @pytest.mark.parametrize(
@@ -483,10 +481,10 @@ def test_check_model_has_contracts_enforced(model, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "keys, model, expectation",
     [
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -512,7 +510,7 @@ def test_check_model_has_contracts_enforced(model, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -538,7 +536,7 @@ def test_check_model_has_contracts_enforced(model, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner", {"name": ["first", "last"]}]},
+            ["owner", {"name": ["first", "last"]}],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -564,7 +562,7 @@ def test_check_model_has_contracts_enforced(model, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -590,7 +588,7 @@ def test_check_model_has_contracts_enforced(model, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -616,7 +614,7 @@ def test_check_model_has_contracts_enforced(model, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {"keys": ["owner", {"name": ["first", "last"]}]},
+            ["owner", {"name": ["first", "last"]}],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -643,9 +641,9 @@ def test_check_model_has_contracts_enforced(model, expectation):
         ),
     ],
 )
-def test_check_model_has_meta_keys(check_config, model, expectation):
+def test_check_model_has_meta_keys(keys, model, expectation):
     with expectation:
-        check_model_has_meta_keys(check_config=check_config, model=model, request=None)
+        check_model_has_meta_keys(keys=keys, model=model, request=None)
 
 
 @pytest.mark.parametrize(
@@ -734,12 +732,9 @@ def test_check_model_has_no_upstream_dependencies(model, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "model, tags, expectation",
     [
         (
-            {
-                "tags": ["tag_1"],
-            },
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -763,12 +758,10 @@ def test_check_model_has_no_upstream_dependencies(model, expectation):
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ["tag_1"],
             does_not_raise(),
         ),
         (
-            {
-                "tags": ["tag_1"],
-            },
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -792,22 +785,21 @@ def test_check_model_has_no_upstream_dependencies(model, expectation):
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ["tag_1"],
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_model_has_tags(check_config, model, expectation):
+def test_check_model_has_tags(model, tags, expectation):
     with expectation:
-        check_model_has_tags(check_config=check_config, model=model, request=None)
+        check_model_has_tags(model=model, tags=tags, request=None)
 
 
 @pytest.mark.parametrize(
-    "check_config, model, tests, expectation",
+    "accepted_uniqueness_tests, model, tests, expectation",
     [
         (
-            {
-                "accepted_uniqueness_tests": ["expect_compound_columns_to_be_unique", "unique"],
-            },
+            ["expect_compound_columns_to_be_unique", "unique"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -853,9 +845,7 @@ def test_check_model_has_tags(check_config, model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "accepted_uniqueness_tests": ["my_custom_test", "unique"],
-            },
+            ["my_custom_test", "unique"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -901,9 +891,7 @@ def test_check_model_has_tags(check_config, model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "accepted_uniqueness_tests": ["unique"],
-            },
+            ["unique"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -949,9 +937,7 @@ def test_check_model_has_tags(check_config, model, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {
-                "accepted_uniqueness_tests": ["expect_compound_columns_to_be_unique", "unique"],
-            },
+            ["expect_compound_columns_to_be_unique", "unique"],
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -978,18 +964,20 @@ def test_check_model_has_tags(check_config, model, expectation):
         ),
     ],
 )
-def test_check_model_has_unique_test(check_config, model, tests, expectation):
+def test_check_model_has_unique_test(accepted_uniqueness_tests, model, tests, expectation):
     with expectation:
         check_model_has_unique_test(
-            check_config=check_config, model=model, tests=tests, request=None
+            accepted_uniqueness_tests=accepted_uniqueness_tests,
+            model=model,
+            tests=tests,
+            request=None,
         )
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "model, regexp_pattern, expectation",
     [
         (
-            {"regexp_pattern": ".*[i][f][n][u][l][l].*"},
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1012,12 +1000,10 @@ def test_check_model_has_unique_test(check_config, model, tests, expectation):
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ".*[i][f][n][u][l][l].*",
             does_not_raise(),
         ),
         (
-            {
-                "regexp_pattern": ".*[i][f][n][u][l][l].*",
-            },
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1040,22 +1026,23 @@ def test_check_model_has_unique_test(check_config, model, tests, expectation):
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ".*[i][f][n][u][l][l].*",
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_model_code_does_not_contain_regexp_pattern(check_config, model, expectation):
+def test_check_model_code_does_not_contain_regexp_pattern(model, regexp_pattern, expectation):
     with expectation:
         check_model_code_does_not_contain_regexp_pattern(
-            check_config=check_config, model=model, request=None
+            model=model, regexp_pattern=regexp_pattern, request=None
         )
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "include, model, permitted_sub_directories, expectation",
     [
         (
-            {"include": "", "permitted_sub_directories": ["staging", "mart", "intermediate"]},
+            "",
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1077,10 +1064,11 @@ def test_check_model_code_does_not_contain_regexp_pattern(check_config, model, e
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ["staging", "mart", "intermediate"],
             does_not_raise(),
         ),
         (
-            {"include": "marts", "permitted_sub_directories": ["finance", "marketing"]},
+            "marts",
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1102,10 +1090,11 @@ def test_check_model_code_does_not_contain_regexp_pattern(check_config, model, e
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ["finance", "marketing"],
             does_not_raise(),
         ),
         (
-            {"include": "marts", "permitted_sub_directories": ["finance", "marketing"]},
+            "marts",
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1127,21 +1116,28 @@ def test_check_model_code_does_not_contain_regexp_pattern(check_config, model, e
                     "unique_id": "model.package_name.model_1",
                 }
             ),
+            ["finance", "marketing"],
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_model_directories(check_config, model, expectation):
+def test_check_model_directories(include, model, permitted_sub_directories, expectation):
     with expectation:
-        check_model_directories(check_config=check_config, model=model, request=None)
+        check_model_directories(
+            include=include,
+            model=model,
+            permitted_sub_directories=permitted_sub_directories,
+            request=None,
+        )
 
 
 @pytest.mark.parametrize(
-    "check_config, manifest_obj, model, models, expectation",
+    "manifest_obj, materializations_to_include, max_chained_views, model, models, expectation",
     [
         (
-            {"materializations_to_include": ["ephemeral", "view"], "max_chained_views": 3},
             "manifest_obj",
+            ["ephemeral", "view"],
+            3,
             Nodes4(
                 **{
                     "alias": "model_0",
@@ -1238,8 +1234,9 @@ def test_check_model_directories(check_config, model, expectation):
             does_not_raise(),
         ),
         (
-            {"materializations_to_include": ["ephemeral", "view"], "max_chained_views": 3},
             "manifest_obj",
+            ["ephemeral", "view"],
+            3,
             Nodes4(
                 **{
                     "alias": "model_0",
@@ -1361,11 +1358,14 @@ def test_check_model_directories(check_config, model, expectation):
     ],
     indirect=["manifest_obj"],
 )
-def test_check_model_max_chained_views(check_config, manifest_obj, model, models, expectation):
+def test_check_model_max_chained_views(
+    manifest_obj, materializations_to_include, max_chained_views, model, models, expectation
+):
     with expectation:
         check_model_max_chained_views(
-            check_config=check_config,
             manifest_obj=manifest_obj,
+            materializations_to_include=materializations_to_include,
+            max_chained_views=max_chained_views,
             model=model,
             models=models,
             request=None,
@@ -1373,12 +1373,11 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "include, model_name_pattern, model, expectation",
     [
         (
-            {
-                "model_name_pattern": "^stg_",
-            },
+            "",
+            "^stg_",
             Nodes4(
                 **{
                     "alias": "stg_model_1",
@@ -1403,10 +1402,8 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
             does_not_raise(),
         ),
         (
-            {
-                "include": "^staging",
-                "model_name_pattern": "^stg_",
-            },
+            "^staging",
+            "^stg_",
             Nodes4(
                 **{
                     "alias": "stg_model_2",
@@ -1431,10 +1428,8 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
             does_not_raise(),
         ),
         (
-            {
-                "include": "^intermediate",
-                "model_name_pattern": "^stg_",
-            },
+            "^intermediate",
+            "^stg_",
             Nodes4(
                 **{
                     "alias": "stg_model_3",
@@ -1459,10 +1454,8 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
             does_not_raise(),
         ),
         (
-            {
-                "include": "^intermediate",
-                "model_name_pattern": "^int_",
-            },
+            "^intermediate",
+            "^int_",
             Nodes4(
                 **{
                     "alias": "int_model_1",
@@ -1487,10 +1480,8 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
             does_not_raise(),
         ),
         (
-            {
-                "include": "^intermediate",
-                "model_name_pattern": "^int_",
-            },
+            "^intermediate",
+            "^int_",
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1515,10 +1506,8 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
             pytest.raises(AssertionError),
         ),
         (
-            {
-                "include": "^intermediate",
-                "model_name_pattern": "^int_",
-            },
+            "^intermediate",
+            "^int_",
             Nodes4(
                 **{
                     "alias": "model_int_2",
@@ -1544,18 +1533,18 @@ def test_check_model_max_chained_views(check_config, manifest_obj, model, models
         ),
     ],
 )
-def test_check_mode_names(check_config, model, expectation):
+def test_check_mode_names(include, model_name_pattern, model, expectation):
     with expectation:
-        check_model_names(check_config=check_config, model=model, request=None)
+        check_model_names(
+            include=include, model_name_pattern=model_name_pattern, model=model, request=None
+        )
 
 
 @pytest.mark.parametrize(
-    "check_config, model, models, expectation",
+    "max_downstream_models, model, models, expectation",
     [
         (
-            {
-                "max_downstream_models": 1,
-            },
+            1,
             Nodes4(
                 **{
                     "alias": "stg_model_1",
@@ -1608,9 +1597,7 @@ def test_check_mode_names(check_config, model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "max_downstream_models": 1,
-            },
+            1,
             Nodes4(
                 **{
                     "alias": "stg_model_1",
@@ -1690,20 +1677,20 @@ def test_check_mode_names(check_config, model, expectation):
         ),
     ],
 )
-def test_check_model_max_fanout(check_config, model, models, expectation):
+def test_check_model_max_fanout(max_downstream_models, model, models, expectation):
     with expectation:
-        check_model_max_fanout(check_config=check_config, model=model, models=models, request=None)
+        check_model_max_fanout(
+            max_downstream_models=max_downstream_models, model=model, models=models, request=None
+        )
 
 
 @pytest.mark.parametrize(
-    "check_config, model, expectation",
+    "max_upstream_macros, max_upstream_models, max_upstream_sources, model, expectation",
     [
         (
-            {
-                "max_upstream_macros": 5,
-                "max_upstream_models": 5,
-                "max_upstream_sources": 1,
-            },
+            5,
+            5,
+            1,
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1746,11 +1733,9 @@ def test_check_model_max_fanout(check_config, model, models, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "max_upstream_macros": 5,
-                "max_upstream_models": 5,
-                "max_upstream_sources": 1,
-            },
+            5,
+            5,
+            1,
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1780,11 +1765,9 @@ def test_check_model_max_fanout(check_config, model, models, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "max_upstream_macros": 5,
-                "max_upstream_models": 5,
-                "max_upstream_sources": 1,
-            },
+            5,
+            5,
+            1,
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1817,11 +1800,9 @@ def test_check_model_max_fanout(check_config, model, models, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {
-                "max_upstream_macros": 5,
-                "max_upstream_models": 5,
-                "max_upstream_sources": 1,
-            },
+            5,
+            5,
+            1,
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1858,11 +1839,9 @@ def test_check_model_max_fanout(check_config, model, models, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {
-                "max_upstream_macros": 5,
-                "max_upstream_models": 5,
-                "max_upstream_sources": 1,
-            },
+            5,
+            5,
+            1,
             Nodes4(
                 **{
                     "alias": "model_1",
@@ -1900,9 +1879,17 @@ def test_check_model_max_fanout(check_config, model, models, expectation):
         ),
     ],
 )
-def test_check_model_max_upstream_dependencies(check_config, model, expectation):
+def test_check_model_max_upstream_dependencies(
+    max_upstream_macros, max_upstream_models, max_upstream_sources, model, expectation
+):
     with expectation:
-        check_model_max_upstream_dependencies(check_config=check_config, model=model, request=None)
+        check_model_max_upstream_dependencies(
+            max_upstream_macros=max_upstream_macros,
+            max_upstream_models=max_upstream_models,
+            max_upstream_sources=max_upstream_sources,
+            model=model,
+            request=None,
+        )
 
 
 @pytest.mark.parametrize(
@@ -2255,12 +2242,10 @@ def test_check_model_description_populated(model, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, models, tests, expectation",
+    "min_model_test_coverage_pct, models, tests, expectation",
     [
         (
-            {
-                "min_model_test_coverage_pct": 100,
-            },
+            100,
             [
                 Nodes4(
                     **{
@@ -2313,9 +2298,7 @@ def test_check_model_description_populated(model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "min_model_test_coverage_pct": 50,
-            },
+            50,
             [
                 Nodes4(
                     **{
@@ -2389,9 +2372,7 @@ def test_check_model_description_populated(model, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "min_model_test_coverage_pct": 100,
-            },
+            100,
             [
                 Nodes4(
                     **{
@@ -2466,8 +2447,11 @@ def test_check_model_description_populated(model, expectation):
         ),
     ],
 )
-def test_check_model_test_coverage(check_config, models, tests, expectation):
+def test_check_model_test_coverage(min_model_test_coverage_pct, models, tests, expectation):
     with expectation:
         check_model_test_coverage(
-            check_config=check_config, models=models, tests=tests, request=None
+            min_model_test_coverage_pct=min_model_test_coverage_pct,
+            models=models,
+            tests=tests,
+            request=None,
         )
diff --git a/tests/unit/checks/manifest/test_sources.py b/tests/unit/checks/manifest/test_sources.py
index 87bb797a..d811931d 100644
--- a/tests/unit/checks/manifest/test_sources.py
+++ b/tests/unit/checks/manifest/test_sources.py
@@ -332,10 +332,10 @@ def test_check_source_loader_populated(source, expectation):
 
 
 @pytest.mark.parametrize(
-    "check_config, source, expectation",
+    "keys, source, expectation",
     [
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -357,7 +357,7 @@ def test_check_source_loader_populated(source, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -379,7 +379,7 @@ def test_check_source_loader_populated(source, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner", {"name": ["first", "last"]}]},
+            ["owner", {"name": ["first", "last"]}],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -401,7 +401,7 @@ def test_check_source_loader_populated(source, expectation):
             does_not_raise(),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -423,7 +423,7 @@ def test_check_source_loader_populated(source, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {"keys": ["owner"]},
+            ["owner"],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -445,7 +445,7 @@ def test_check_source_loader_populated(source, expectation):
             pytest.raises(AssertionError),
         ),
         (
-            {"keys": ["owner", {"name": ["first", "last"]}]},
+            ["owner", {"name": ["first", "last"]}],
             Sources(
                 **{
                     "description": "Description that is more than 4 characters.",
@@ -468,18 +468,15 @@ def test_check_source_loader_populated(source, expectation):
         ),
     ],
 )
-def test_check_source_has_meta_keys(check_config, source, expectation):
+def test_check_source_has_meta_keys(keys, source, expectation):
     with expectation:
-        check_source_has_meta_keys(check_config=check_config, source=source, request=None)
+        check_source_has_meta_keys(keys=keys, source=source, request=None)
 
 
 @pytest.mark.parametrize(
-    "check_config, source, expectation",
+    "source, tags, expectation",
     [
         (
-            {
-                "tags": ["tag_1"],
-            },
             Sources(
                 **{
                     "description": "",
@@ -498,12 +495,10 @@ def test_check_source_has_meta_keys(check_config, source, expectation):
                     "unique_id": "source.package_name.source_1.table_1",
                 }
             ),
+            ["tag_1"],
             does_not_raise(),
         ),
         (
-            {
-                "tags": ["tag_1"],
-            },
             Sources(
                 **{
                     "description": "",
@@ -522,22 +517,21 @@ def test_check_source_has_meta_keys(check_config, source, expectation):
                     "unique_id": "source.package_name.source_1.table_1",
                 }
             ),
+            ["tag_1"],
             pytest.raises(AssertionError),
         ),
     ],
 )
-def test_check_source_has_tags(check_config, source, expectation):
+def test_check_source_has_tags(source, tags, expectation):
     with expectation:
-        check_source_has_tags(check_config=check_config, source=source, request=None)
+        check_source_has_tags(source=source, tags=tags, request=None)
 
 
 @pytest.mark.parametrize(
-    "check_config, source, expectation",
+    "source_name_pattern, source, expectation",
     [
         (
-            {
-                "source_name_pattern": "^[a-z_]*$",
-            },
+            "^[a-z_]*$",
             Sources(
                 **{
                     "description": "",
@@ -559,9 +553,7 @@ def test_check_source_has_tags(check_config, source, expectation):
             does_not_raise(),
         ),
         (
-            {
-                "source_name_pattern": "^[a-z_]*$",
-            },
+            "^[a-z_]*$",
             Sources(
                 **{
                     "description": "",
@@ -584,9 +576,9 @@ def test_check_source_has_tags(check_config, source, expectation):
         ),
     ],
 )
-def test_check_source_names(check_config, source, expectation):
+def test_check_source_names(source_name_pattern, source, expectation):
     with expectation:
-        check_source_names(check_config=check_config, source=source, request=None)
+        check_source_names(source_name_pattern=source_name_pattern, source=source, request=None)
 
 
 @pytest.mark.parametrize(
diff --git a/tests/unit/checks/run_results/test_run_results.py b/tests/unit/checks/run_results/test_run_results.py
index 5b17d8ad..28ffc219 100644
--- a/tests/unit/checks/run_results/test_run_results.py
+++ b/tests/unit/checks/run_results/test_run_results.py
@@ -1,52 +1,40 @@
 from contextlib import nullcontext as does_not_raise
 
 import pytest
+from dbt_artifacts_parser.parsers.run_results.run_results_v6 import Result
 
 from dbt_bouncer.checks.run_results.check_run_results import (
     check_run_results_max_execution_time,
     check_run_results_max_gigabytes_billed,
 )
-from dbt_bouncer.parsers import DbtBouncerResult
 
 
 @pytest.mark.parametrize(
-    "check_config, run_result, expectation",
+    "max_gigabytes_billed, run_result, expectation",
     [
         (
-            {
-                "max_gigabytes_billed": 10,
-            },
-            DbtBouncerResult(
+            10,
+            Result(
                 **{
-                    "path": "model_1.sql",
-                    "result": {
-                        "adapter_response": {"bytes_billed": 1},
-                        "execution_time": 1,
-                        "status": "success",
-                        "thread_id": "Thread-1",
-                        "timing": [],
-                        "unique_id": "model.package_name.model_1",
-                    },
+                    "adapter_response": {"bytes_billed": 1},
+                    "execution_time": 1,
+                    "status": "success",
+                    "thread_id": "Thread-1",
+                    "timing": [],
                     "unique_id": "model.package_name.model_1",
                 }
             ),
             does_not_raise(),
         ),
         (
-            {
-                "max_gigabytes_billed": 10,
-            },
-            DbtBouncerResult(
+            10,
+            Result(
                 **{
-                    "path": "model_1.sql",
-                    "result": {
-                        "adapter_response": {"bytes_billed": 100000000000},
-                        "execution_time": 1,
-                        "status": "success",
-                        "thread_id": "Thread-1",
-                        "timing": [],
-                        "unique_id": "model.package_name.model_1",
-                    },
+                    "adapter_response": {"bytes_billed": 100000000000},
+                    "execution_time": 1,
+                    "status": "success",
+                    "thread_id": "Thread-1",
+                    "timing": [],
                     "unique_id": "model.package_name.model_1",
                 }
             ),
@@ -54,71 +42,53 @@
         ),
     ],
 )
-def test_check_run_results_max_gigabytes_billed(check_config, run_result, expectation):
+def test_check_run_results_max_gigabytes_billed(max_gigabytes_billed, run_result, expectation):
     with expectation:
         check_run_results_max_gigabytes_billed(
-            check_config=check_config, run_result=run_result, request=None
+            max_gigabytes_billed=max_gigabytes_billed, run_result=run_result, request=None
         )
 
 
 @pytest.mark.parametrize(
-    "check_config, run_result, expectation",
+    "max_execution_time, run_result, expectation",
     [
         (
-            {
-                "max_execution_time": 10,
-            },
-            DbtBouncerResult(
+            10,
+            Result(
                 **{
-                    "path": "model_1.sql",
-                    "result": {
-                        "adapter_response": {"bytes_billed": 1},
-                        "execution_time": 1,
-                        "status": "success",
-                        "thread_id": "Thread-1",
-                        "timing": [],
-                        "unique_id": "model.package_name.model_1",
-                    },
+                    "adapter_response": {"bytes_billed": 1},
+                    "execution_time": 1,
+                    "status": "success",
+                    "thread_id": "Thread-1",
+                    "timing": [],
                     "unique_id": "model.package_name.model_1",
                 }
             ),
             does_not_raise(),
         ),
         (
-            {
-                "max_execution_time": 10,
-            },
-            DbtBouncerResult(
+            10,
+            Result(
                 **{
-                    "path": "model_1.sql",
-                    "result": {
-                        "adapter_response": {"bytes_billed": 1},
-                        "execution_time": 10,
-                        "status": "success",
-                        "thread_id": "Thread-1",
-                        "timing": [],
-                        "unique_id": "model.package_name.model_1",
-                    },
+                    "adapter_response": {"bytes_billed": 1},
+                    "execution_time": 10,
+                    "status": "success",
+                    "thread_id": "Thread-1",
+                    "timing": [],
                     "unique_id": "model.package_name.model_1",
                 }
             ),
             does_not_raise(),
         ),
         (
-            {
-                "max_execution_time": 10,
-            },
-            DbtBouncerResult(
+            10,
+            Result(
                 **{
-                    "path": "model_1.sql",
-                    "result": {
-                        "adapter_response": {"bytes_billed": 1},
-                        "execution_time": 100,
-                        "status": "success",
-                        "thread_id": "Thread-1",
-                        "timing": [],
-                        "unique_id": "model.package_name.model_1",
-                    },
+                    "adapter_response": {"bytes_billed": 1},
+                    "execution_time": 100,
+                    "status": "success",
+                    "thread_id": "Thread-1",
+                    "timing": [],
                     "unique_id": "model.package_name.model_1",
                 }
             ),
@@ -126,8 +96,8 @@ def test_check_run_results_max_gigabytes_billed(check_config, run_result, expect
         ),
     ],
 )
-def test_check_run_results_max_execution_time(check_config, run_result, expectation):
+def test_check_run_results_max_execution_time(max_execution_time, run_result, expectation):
     with expectation:
         check_run_results_max_execution_time(
-            check_config=check_config, run_result=run_result, request=None
+            max_execution_time=max_execution_time, run_result=run_result, request=None
         )