Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/execution_engine/split_and_sample/data_splitter.py b/great_expectations/execution_engine/split_and_sample/data_splitter.py
--- a/great_expectations/execution_engine/split_and_sample/data_splitter.py
+++ b/great_expectations/execution_engine/split_and_sample/data_splitter.py
@@ -64,7 +64,8 @@ def get_splitter_method(self, splitter_method_name: str) -> Callable:
 
         return getattr(self, splitter_method_name)
 
-    def _get_splitter_method_name(self, splitter_method_name: str) -> str:
+    @staticmethod
+    def _get_splitter_method_name(splitter_method_name: str) -> str:
         """Accept splitter methods with or without starting with `_`.
 
         Args:
@@ -78,8 +79,9 @@ def _get_splitter_method_name(self, splitter_method_name: str) -> str:
         else:
             return splitter_method_name
 
+    @staticmethod
     def _convert_date_parts(
-        self, date_parts: Union[List[DatePart], List[str]]
+        date_parts: Union[List[DatePart], List[str]]
     ) -> List[DatePart]:
         """Convert a list of date parts to DatePart objects.
 
diff --git a/great_expectations/execution_engine/split_and_sample/sqlalchemy_data_splitter.py b/great_expectations/execution_engine/split_and_sample/sqlalchemy_data_splitter.py
--- a/great_expectations/execution_engine/split_and_sample/sqlalchemy_data_splitter.py
+++ b/great_expectations/execution_engine/split_and_sample/sqlalchemy_data_splitter.py
@@ -181,18 +181,20 @@ def split_on_date_parts(
 
         return query
 
-    def split_on_whole_table(self, batch_identifiers: dict) -> bool:
+    @staticmethod
+    def split_on_whole_table(batch_identifiers: dict) -> bool:
         """'Split' by returning the whole table"""
 
         return True
 
-    def split_on_column_value(self, column_name: str, batch_identifiers: dict) -> bool:
+    @staticmethod
+    def split_on_column_value(column_name: str, batch_identifiers: dict) -> bool:
         """Split using the values in the named column"""
 
         return sa.column(column_name) == batch_identifiers[column_name]
 
+    @staticmethod
     def split_on_converted_datetime(
-        self,
         column_name: str,
         batch_identifiers: dict,
         date_format_string: str = "%Y-%m-%d",
@@ -207,8 +209,11 @@ def split_on_converted_datetime(
             == batch_identifiers[column_name]
         )
 
+    @staticmethod
     def split_on_divided_integer(
-        self, column_name: str, divisor: int, batch_identifiers: dict
+        column_name: str,
+        divisor: int,
+        batch_identifiers: dict,
     ) -> bool:
         """Divide the values in the named column by `divisor`, and split on that"""
 
@@ -217,15 +222,20 @@ def split_on_divided_integer(
             == batch_identifiers[column_name]
         )
 
+    @staticmethod
     def split_on_mod_integer(
-        self, column_name: str, mod: int, batch_identifiers: dict
+        column_name: str,
+        mod: int,
+        batch_identifiers: dict,
     ) -> bool:
         """Divide the values in the named column by `divisor`, and split on that"""
 
         return sa.column(column_name) % mod == batch_identifiers[column_name]
 
+    @staticmethod
     def split_on_multi_column_values(
-        self, column_names: List[str], batch_identifiers: dict
+        column_names: List[str],
+        batch_identifiers: dict,
     ) -> bool:
         """Split on the joint values in the named columns"""
 
@@ -236,8 +246,8 @@ def split_on_multi_column_values(
             )
         )
 
+    @staticmethod
     def split_on_hashed_column(
-        self,
         column_name: str,
         hash_digits: int,
         batch_identifiers: dict,
@@ -310,6 +320,7 @@ def get_data_for_batch_identifiers_year(
         column_name. This data can be used to build BatchIdentifiers.
 
         Args:
+            execution_engine: SqlAlchemyExecutionEngine to be used for executing the query.
             table_name: table to split.
             column_name: column in table to use in determining split.
 
@@ -335,6 +346,7 @@ def get_data_for_batch_identifiers_year_and_month(
         column_name. This data can be used to build BatchIdentifiers.
 
         Args:
+            execution_engine: SqlAlchemyExecutionEngine to be used for executing the query.
             table_name: table to split.
             column_name: column in table to use in determining split.
 
@@ -360,6 +372,7 @@ def get_data_for_batch_identifiers_year_and_month_and_day(
         column_name. This data can be used to build BatchIdentifiers.
 
         Args:
+            execution_engine: SqlAlchemyExecutionEngine to be used for executing the query.
             table_name: table to split.
             column_name: column in table to use in determining split.
 
@@ -487,8 +500,8 @@ def get_data_for_batch_identifiers_for_split_on_date_parts(
             column_name, result, date_parts
         )
 
+    @staticmethod
     def _execute_split_query(
-        self,
         execution_engine: "SqlAlchemyExecutionEngine",  # noqa: F821
         split_query: Selectable,  # noqa: F821
     ) -> List[LegacyRow]:
@@ -530,7 +543,8 @@ def _get_params_for_batch_identifiers_from_date_part_splitter(
         ]
         return data_for_batch_identifiers
 
-    def _get_column_names_from_splitter_kwargs(self, splitter_kwargs) -> List[str]:
+    @staticmethod
+    def _get_column_names_from_splitter_kwargs(splitter_kwargs) -> List[str]:
         column_names: List[str] = []
 
         if "column_names" in splitter_kwargs:
@@ -599,8 +613,8 @@ def _get_method_name_for_get_data_for_batch_identifiers_method(
                 f"Please provide a supported splitter method name, you provided: {splitter_method_name}"
             )
 
+    @staticmethod
     def _get_params_for_batch_identifiers_from_non_date_part_splitters(
-        self,
         column_names: List[str],
         rows: List[LegacyRow],
     ) -> List[dict]:
@@ -615,8 +629,8 @@ def _get_params_for_batch_identifiers_from_non_date_part_splitters(
         """
         return [dict(zip(column_names, row)) for row in rows]
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_whole_table(
-        self,
         table_name: str,
     ) -> Selectable:
         """
@@ -626,8 +640,8 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_whole_table(
         """
         return sa.select([sa.true()])
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_column_value(
-        self,
         table_name: str,
         column_name: str,
     ) -> Selectable:
@@ -640,8 +654,8 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_column_value(
             .order_by(sa.column(column_name).asc())
         )
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_converted_datetime(
-        self,
         table_name: str,
         column_name: str,
         date_format_string: str = "%Y-%m-%d",
@@ -660,8 +674,11 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_converted_dateti
             ]
         ).select_from(sa.text(table_name))
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_divided_integer(
-        self, table_name: str, column_name: str, divisor: int
+        table_name: str,
+        column_name: str,
+        divisor: int,
     ) -> Selectable:
         """Divide the values in the named column by `divisor`, and split on that"""
         # query = f"SELECT DISTINCT(\"{self.column_name}\" / {divisor}) AS my_var FROM {self.table_name}"
@@ -670,8 +687,11 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_divided_integer(
             [sa.func.distinct(sa.cast(sa.column(column_name) / divisor, sa.Integer))]
         ).select_from(sa.text(table_name))
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_mod_integer(
-        self, table_name: str, column_name: str, mod: int
+        table_name: str,
+        column_name: str,
+        mod: int,
     ) -> Selectable:
         """Divide the values in the named column by `divisor`, and split on that"""
         # query = f"SELECT DISTINCT(\"{self.column_name}\" / {divisor}) AS my_var FROM {self.table_name}"
@@ -680,8 +700,8 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_mod_integer(
             [sa.func.distinct(sa.cast(sa.column(column_name) % mod, sa.Integer))]
         ).select_from(sa.text(table_name))
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_multi_column_values(
-        self,
         table_name: str,
         column_names: List[str],
     ) -> Selectable:
@@ -694,8 +714,8 @@ def get_split_query_for_data_for_batch_identifiers_for_split_on_multi_column_val
             .select_from(sa.text(table_name))
         )
 
+    @staticmethod
     def get_split_query_for_data_for_batch_identifiers_for_split_on_hashed_column(
-        self,
         table_name: str,
         column_name: str,
         hash_digits: int,


Test patch:
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -1966,7 +1966,7 @@ def generate_ascending_list_of_datetimes(
 
         datetime_list = [
             start_time
-            + datetime.timedelta(seconds=random.randrange(days_between_dates))
+            + datetime.timedelta(seconds=random.randrange(round(days_between_dates)))
             for i in range(k)
         ]
         datetime_list.sort()
diff --git a/tests/execution_engine/conftest.py b/tests/execution_engine/conftest.py
--- a/tests/execution_engine/conftest.py
+++ b/tests/execution_engine/conftest.py
@@ -1,8 +1,15 @@
 import datetime
+import os
 import random
+from pathlib import Path
+from typing import List
 
+import boto3
 import pandas as pd
 import pytest
+from moto import mock_s3
+
+from great_expectations.core.batch_spec import AzureBatchSpec, GCSBatchSpec
 
 try:
     import pyspark
@@ -17,6 +24,130 @@
     StringType = None
 
 
+@pytest.fixture(scope="function")
+def aws_credentials():
+    """Mocked AWS Credentials for moto."""
+    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
+    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
+    os.environ["AWS_SECURITY_TOKEN"] = "testing"
+    os.environ["AWS_SESSION_TOKEN"] = "testing"
+
+
+@pytest.fixture
+def s3(aws_credentials):
+    with mock_s3():
+        yield boto3.client("s3", region_name="us-east-1")
+
+
+@pytest.fixture
+def s3_bucket(s3):
+    bucket: str = "test_bucket"
+    s3.create_bucket(Bucket=bucket)
+    return bucket
+
+
+@pytest.fixture
+def test_df_small() -> pd.DataFrame:
+    return pd.DataFrame(data={"col1": [1, 0, 505], "col2": [3, 4, 101]})
+
+
+@pytest.fixture
+def test_df_small_csv(test_df_small, tmpdir) -> bytes:
+    path = Path(tmpdir) / "file.csv"
+    test_df_small.to_csv(path, index=False)
+    return path.read_bytes()
+
+
+@pytest.fixture
+def test_df_small_csv_compressed(test_df_small, tmpdir) -> bytes:
+    path = Path(tmpdir) / "file.csv.gz"
+    test_df_small.to_csv(path, index=False, compression="gzip")
+    return path.read_bytes()
+
+
+@pytest.fixture
+def test_s3_files_parquet(tmpdir, s3, s3_bucket, test_df_small, test_df_small_csv):
+    keys: List[str] = [
+        "path/A-100.csv",
+        "path/A-101.csv",
+        "directory/B-1.parquet",
+        "directory/B-2.parquet",
+        "alpha-1.csv",
+        "alpha-2.csv",
+    ]
+    path = Path(tmpdir) / "file.parquet"
+    test_df_small.to_parquet(path)
+    for key in keys:
+        if key.endswith(".parquet"):
+            with open(path, "rb") as f:
+                s3.put_object(Bucket=s3_bucket, Body=f, Key=key)
+        else:
+            s3.put_object(Bucket=s3_bucket, Body=test_df_small_csv, Key=key)
+    return s3_bucket, keys
+
+
+@pytest.fixture
+def test_s3_files_compressed(s3, s3_bucket, test_df_small_csv_compressed):
+    keys: List[str] = [
+        "path/A-100.csv.gz",
+        "path/A-101.csv.gz",
+        "directory/B-1.csv.gz",
+        "directory/B-2.csv.gz",
+    ]
+
+    for key in keys:
+        s3.put_object(
+            Bucket=s3_bucket,
+            Body=test_df_small_csv_compressed,
+            Key=key,
+        )
+    return s3_bucket, keys
+
+
+@pytest.fixture
+def azure_batch_spec() -> AzureBatchSpec:
+    container = "test_container"
+    keys: List[str] = [
+        "path/A-100.csv",
+        "path/A-101.csv",
+        "directory/B-1.csv",
+        "directory/B-2.csv",
+        "alpha-1.csv",
+        "alpha-2.csv",
+    ]
+    path = keys[0]
+    full_path = os.path.join("mock_account.blob.core.windows.net", container, path)
+
+    batch_spec = AzureBatchSpec(
+        path=full_path,
+        reader_method="read_csv",
+        splitter_method="_split_on_whole_table",
+    )
+    return batch_spec
+
+
+@pytest.fixture
+def gcs_batch_spec() -> GCSBatchSpec:
+    bucket = "test_bucket"
+    keys: List[str] = [
+        "path/A-100.csv",
+        "path/A-101.csv",
+        "directory/B-1.csv",
+        "directory/B-2.csv",
+        "alpha-1.csv",
+        "alpha-2.csv",
+    ]
+    path = keys[0]
+    full_path = os.path.join("gs://", bucket, path)
+
+    batch_spec = GCSBatchSpec(
+        path=full_path,
+        reader_method="read_csv",
+        splitter_method="_split_on_whole_table",
+    )
+    return batch_spec
+
+
 @pytest.fixture
 def test_sparkdf(spark_session):
     def generate_ascending_list_of_datetimes(
diff --git a/tests/execution_engine/split_and_sample/test_pandas_execution_engine_splitting.py b/tests/execution_engine/split_and_sample/test_pandas_execution_engine_splitting.py
--- a/tests/execution_engine/split_and_sample/test_pandas_execution_engine_splitting.py
+++ b/tests/execution_engine/split_and_sample/test_pandas_execution_engine_splitting.py
@@ -1,3 +1,5 @@
+import datetime
+import os
 from typing import List
 from unittest import mock
 
@@ -5,8 +7,16 @@
 import pandas.api.types as ptypes
 import pytest
 
-from great_expectations.core.batch_spec import RuntimeDataBatchSpec
-from great_expectations.execution_engine import PandasExecutionEngine
+import great_expectations.exceptions as ge_exceptions
+from great_expectations.core import IDDict
+from great_expectations.core.batch import BatchDefinition
+from great_expectations.core.batch_spec import (
+    PathBatchSpec,
+    RuntimeDataBatchSpec,
+    S3BatchSpec,
+)
+from great_expectations.datasource.data_connector import ConfiguredAssetS3DataConnector
+from great_expectations.execution_engine import ExecutionEngine, PandasExecutionEngine
 from great_expectations.execution_engine.split_and_sample.data_splitter import DatePart
 from great_expectations.execution_engine.split_and_sample.pandas_data_splitter import (
     PandasDataSplitter,
@@ -35,7 +45,6 @@
 
 @pytest.fixture
 def simple_multi_year_pandas_df():
-
     df: pd.DataFrame = pd.DataFrame(
         data={
             "input_timestamp": [
@@ -59,6 +68,35 @@ def simple_multi_year_pandas_df():
     return df
 
 
+@pytest.fixture
+def test_s3_files(s3, s3_bucket, test_df_small_csv):
+    keys: List[str] = [
+        "path/A-100.csv",
+        "path/A-101.csv",
+        "directory/B-1.csv",
+        "directory/B-2.csv",
+        "alpha-1.csv",
+        "alpha-2.csv",
+    ]
+    for key in keys:
+        s3.put_object(Bucket=s3_bucket, Body=test_df_small_csv, Key=key)
+    return s3_bucket, keys
+
+
+@pytest.fixture
+def batch_with_split_on_whole_table_s3(test_s3_files) -> S3BatchSpec:
+    bucket, keys = test_s3_files
+    path = keys[0]
+    full_path = f"s3a://{os.path.join(bucket, path)}"
+
+    batch_spec = S3BatchSpec(
+        path=full_path,
+        reader_method="read_csv",
+        splitter_method="_split_on_whole_table",
+    )
+    return batch_spec
+
+
 @pytest.mark.integration
 @pytest.mark.parametrize(
     "splitter_kwargs_year,num_values_in_df",
@@ -257,3 +295,234 @@ def test_get_splitter_method(underscore_prefix: str, splitter_method_name: str):
     assert data_splitter.get_splitter_method(
         splitter_method_name_with_prefix
     ) == getattr(data_splitter, splitter_method_name)
+
+
+def test_get_batch_with_split_on_whole_table_runtime(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df, splitter_method="_split_on_whole_table"
+        )
+    )
+    assert split_df.dataframe.shape == (120, 10)
+
+
+def test_get_batch_with_split_on_whole_table_filesystem(
+    test_folder_connection_path_csv,
+):
+    test_df = PandasExecutionEngine().get_batch_data(
+        PathBatchSpec(
+            path=os.path.join(test_folder_connection_path_csv, "test.csv"),
+            reader_method="read_csv",
+            splitter_method="_split_on_whole_table",
+        )
+    )
+    assert test_df.dataframe.shape == (5, 2)
+
+
+def test_get_batch_with_split_on_whole_table_s3(
+    batch_with_split_on_whole_table_s3, test_df_small
+):
+    df = PandasExecutionEngine().get_batch_data(
+        batch_spec=batch_with_split_on_whole_table_s3
+    )
+    assert df.dataframe.shape == test_df_small.shape
+
+
+def test_get_batch_with_split_on_whole_table_s3_with_configured_asset_s3_data_connector(
+    test_s3_files, test_df_small
+):
+    bucket, _keys = test_s3_files
+    expected_df = test_df_small
+
+    execution_engine: ExecutionEngine = PandasExecutionEngine()
+
+    my_data_connector = ConfiguredAssetS3DataConnector(
+        name="my_data_connector",
+        datasource_name="FAKE_DATASOURCE_NAME",
+        bucket=bucket,
+        execution_engine=execution_engine,
+        prefix="",
+        assets={"alpha": {}},
+        default_regex={
+            "pattern": "alpha-(.*)\\.csv",
+            "group_names": ["index"],
+        },
+    )
+    batch_def: BatchDefinition = BatchDefinition(
+        datasource_name="FAKE_DATASOURCE_NAME",
+        data_connector_name="my_data_connector",
+        data_asset_name="alpha",
+        batch_identifiers=IDDict(index=1),
+        batch_spec_passthrough={
+            "reader_method": "read_csv",
+            "splitter_method": "_split_on_whole_table",
+        },
+    )
+    test_df = execution_engine.get_batch_data(
+        batch_spec=my_data_connector.build_batch_spec(batch_definition=batch_def)
+    )
+    assert test_df.dataframe.shape == expected_df.shape
+
+    # if key does not exist
+    batch_def_no_key = BatchDefinition(
+        datasource_name="FAKE_DATASOURCE_NAME",
+        data_connector_name="my_data_connector",
+        data_asset_name="alpha",
+        batch_identifiers=IDDict(index=9),
+        batch_spec_passthrough={
+            "reader_method": "read_csv",
+            "splitter_method": "_split_on_whole_table",
+        },
+    )
+    with pytest.raises(ge_exceptions.ExecutionEngineError):
+        execution_engine.get_batch_data(
+            batch_spec=my_data_connector.build_batch_spec(
+                batch_definition=batch_def_no_key
+            )
+        )
+
+
+def test_get_batch_with_split_on_column_value(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_column_value",
+            splitter_kwargs={
+                "column_name": "batch_id",
+                "batch_identifiers": {"batch_id": 2},
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (12, 10)
+    assert (split_df.dataframe.batch_id == 2).all()
+
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_column_value",
+            splitter_kwargs={
+                "column_name": "date",
+                "batch_identifiers": {"date": datetime.date(2020, 1, 30)},
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (3, 10)
+
+
+def test_get_batch_with_split_on_converted_datetime(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_converted_datetime",
+            splitter_kwargs={
+                "column_name": "timestamp",
+                "batch_identifiers": {"timestamp": "2020-01-30"},
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (3, 10)
+
+
+def test_get_batch_with_split_on_divided_integer(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_divided_integer",
+            splitter_kwargs={
+                "column_name": "id",
+                "divisor": 10,
+                "batch_identifiers": {"id": 5},
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (10, 10)
+    assert split_df.dataframe.id.min() == 50
+    assert split_df.dataframe.id.max() == 59
+
+
+def test_get_batch_with_split_on_mod_integer(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_mod_integer",
+            splitter_kwargs={
+                "column_name": "id",
+                "mod": 10,
+                "batch_identifiers": {"id": 5},
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (12, 10)
+    assert split_df.dataframe.id.min() == 5
+    assert split_df.dataframe.id.max() == 115
+
+
+def test_get_batch_with_split_on_multi_column_values(test_df):
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_multi_column_values",
+            splitter_kwargs={
+                "column_names": ["y", "m", "d"],
+                "batch_identifiers": {
+                    "y": 2020,
+                    "m": 1,
+                    "d": 5,
+                },
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (4, 10)
+    assert (split_df.dataframe.date == datetime.date(2020, 1, 5)).all()
+
+    with pytest.raises(ValueError):
+        # noinspection PyUnusedLocal
+        split_df = PandasExecutionEngine().get_batch_data(
+            RuntimeDataBatchSpec(
+                batch_data=test_df,
+                splitter_method="_split_on_multi_column_values",
+                splitter_kwargs={
+                    "column_names": ["I", "dont", "exist"],
+                    "batch_identifiers": {
+                        "y": 2020,
+                        "m": 1,
+                        "d": 5,
+                    },
+                },
+            )
+        )
+
+
+def test_get_batch_with_split_on_hashed_column(test_df):
+    with pytest.raises(ge_exceptions.ExecutionEngineError):
+        # noinspection PyUnusedLocal
+        split_df = PandasExecutionEngine().get_batch_data(
+            RuntimeDataBatchSpec(
+                batch_data=test_df,
+                splitter_method="_split_on_hashed_column",
+                splitter_kwargs={
+                    "column_name": "favorite_color",
+                    "hash_digits": 1,
+                    "batch_identifiers": {
+                        "hash_value": "a",
+                    },
+                    "hash_function_name": "I_am_not_valid",
+                },
+            )
+        )
+
+    split_df = PandasExecutionEngine().get_batch_data(
+        RuntimeDataBatchSpec(
+            batch_data=test_df,
+            splitter_method="_split_on_hashed_column",
+            splitter_kwargs={
+                "column_name": "favorite_color",
+                "hash_digits": 1,
+                "batch_identifiers": {
+                    "hash_value": "a",
+                },
+                "hash_function_name": "sha256",
+            },
+        )
+    )
+    assert split_df.dataframe.shape == (8, 10)
diff --git a/tests/execution_engine/test_pandas_execution_engine.py b/tests/execution_engine/test_pandas_execution_engine.py
--- a/tests/execution_engine/test_pandas_execution_engine.py
+++ b/tests/execution_engine/test_pandas_execution_engine.py
@@ -1,15 +1,12 @@
 import datetime
 import os
 import random
-from pathlib import Path
-from typing import List
 from unittest import mock
 
-import boto3
 import pandas as pd
 import pytest
-from moto import mock_s3
 
+# noinspection PyBroadException
 try:
     from azure.storage.blob import BlobServiceClient
 except:
@@ -17,20 +14,8 @@
 
 
 import great_expectations.exceptions as ge_exceptions
-from great_expectations.core.batch import BatchDefinition
-from great_expectations.core.batch_spec import (
-    AzureBatchSpec,
-    GCSBatchSpec,
-    PathBatchSpec,
-    RuntimeDataBatchSpec,
-    S3BatchSpec,
-)
-from great_expectations.core.id_dict import IDDict
-from great_expectations.datasource.data_connector import ConfiguredAssetS3DataConnector
-from great_expectations.execution_engine.execution_engine import (
-    ExecutionEngine,
-    MetricDomainTypes,
-)
+from great_expectations.core.batch_spec import RuntimeDataBatchSpec, S3BatchSpec
+from great_expectations.execution_engine.execution_engine import MetricDomainTypes
 from great_expectations.execution_engine.pandas_execution_engine import (
     PandasExecutionEngine,
     storage,
@@ -40,159 +25,6 @@
 from tests.expectations.test_util import get_table_columns_metric
 
 
-@pytest.fixture(scope="function")
-def aws_credentials():
-    """Mocked AWS Credentials for moto."""
-    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
-    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
-    os.environ["AWS_SECURITY_TOKEN"] = "testing"
-    os.environ["AWS_SESSION_TOKEN"] = "testing"
-
-
-@pytest.fixture
-def s3(aws_credentials):
-    with mock_s3():
-        yield boto3.client("s3", region_name="us-east-1")
-
-
-@pytest.fixture
-def s3_bucket(s3):
-    bucket: str = "test_bucket"
-    s3.create_bucket(Bucket=bucket)
-    return bucket
-
-
-@pytest.fixture
-def test_df_small() -> pd.DataFrame:
-    return pd.DataFrame(data={"col1": [1, 0, 505], "col2": [3, 4, 101]})
-
-
-@pytest.fixture
-def test_df_small_csv_compressed(test_df_small, tmpdir) -> bytes:
-    path = Path(tmpdir) / "file.csv.gz"
-    test_df_small.to_csv(path, index=False, compression="gzip")
-    return path.read_bytes()
-
-
-@pytest.fixture
-def test_df_small_csv(test_df_small, tmpdir) -> bytes:
-    path = Path(tmpdir) / "file.csv"
-    test_df_small.to_csv(path, index=False)
-    return path.read_bytes()
-
-
-@pytest.fixture
-def test_s3_files(s3, s3_bucket, test_df_small_csv):
-    keys: List[str] = [
-        "path/A-100.csv",
-        "path/A-101.csv",
-        "directory/B-1.csv",
-        "directory/B-2.csv",
-        "alpha-1.csv",
-        "alpha-2.csv",
-    ]
-    for key in keys:
-        s3.put_object(Bucket=s3_bucket, Body=test_df_small_csv, Key=key)
-    return s3_bucket, keys
-
-
-@pytest.fixture
-def test_s3_files_parquet(tmpdir, s3, s3_bucket, test_df_small, test_df_small_csv):
-    keys: List[str] = [
-        "path/A-100.csv",
-        "path/A-101.csv",
-        "directory/B-1.parquet",
-        "directory/B-2.parquet",
-        "alpha-1.csv",
-        "alpha-2.csv",
-    ]
-    path = Path(tmpdir) / "file.parquet"
-    test_df_small.to_parquet(path)
-    for key in keys:
-        if key.endswith(".parquet"):
-            with open(path, "rb") as f:
-                s3.put_object(Bucket=s3_bucket, Body=f, Key=key)
-        else:
-            s3.put_object(Bucket=s3_bucket, Body=test_df_small_csv, Key=key)
-    return s3_bucket, keys
-
-
-@pytest.fixture
-def batch_with_split_on_whole_table_s3(test_s3_files) -> S3BatchSpec:
-    bucket, keys = test_s3_files
-    path = keys[0]
-    full_path = f"s3a://{os.path.join(bucket, path)}"
-
-    batch_spec = S3BatchSpec(
-        path=full_path,
-        reader_method="read_csv",
-        splitter_method="_split_on_whole_table",
-    )
-    return batch_spec
-
-
-@pytest.fixture
-def test_s3_files_compressed(s3, s3_bucket, test_df_small_csv_compressed):
-    keys: List[str] = [
-        "path/A-100.csv.gz",
-        "path/A-101.csv.gz",
-        "directory/B-1.csv.gz",
-        "directory/B-2.csv.gz",
-    ]
-
-    for key in keys:
-        s3.put_object(
-            Bucket=s3_bucket,
-            Body=test_df_small_csv_compressed,
-            Key=key,
-        )
-    return s3_bucket, keys
-
-
-@pytest.fixture
-def azure_batch_spec() -> AzureBatchSpec:
-    container = "test_container"
-    keys: List[str] = [
-        "path/A-100.csv",
-        "path/A-101.csv",
-        "directory/B-1.csv",
-        "directory/B-2.csv",
-        "alpha-1.csv",
-        "alpha-2.csv",
-    ]
-    path = keys[0]
-    full_path = os.path.join("mock_account.blob.core.windows.net", container, path)
-
-    batch_spec = AzureBatchSpec(
-        path=full_path,
-        reader_method="read_csv",
-        splitter_method="_split_on_whole_table",
-    )
-    return batch_spec
-
-
-@pytest.fixture
-def gcs_batch_spec() -> GCSBatchSpec:
-    bucket = "test_bucket"
-    keys: List[str] = [
-        "path/A-100.csv",
-        "path/A-101.csv",
-        "directory/B-1.csv",
-        "directory/B-2.csv",
-        "alpha-1.csv",
-        "alpha-2.csv",
-    ]
-    path = keys[0]
-    full_path = os.path.join("gs://", bucket, path)
-
-    batch_spec = GCSBatchSpec(
-        path=full_path,
-        reader_method="read_csv",
-        splitter_method="_split_on_whole_table",
-    )
-    return batch_spec
-
-
 def test_constructor_with_boto3_options():
     # default instantiation
     PandasExecutionEngine()
@@ -431,7 +263,6 @@ def test_get_compute_domain_with_no_domain_kwargs():
 def test_get_compute_domain_with_column_pair_domain():
     engine = PandasExecutionEngine()
     df = pd.DataFrame({"a": [1, 2, 3, 4], "b": [2, 3, 4, 5], "c": [1, 2, 3, 4]})
-    expected_column_pair_df = df.drop(columns=["c"])
 
     # Loading batch data
     engine.load_batch_data(batch_data=df, batch_id="1234")
@@ -595,6 +426,7 @@ def test_resolve_metric_bundle_with_nonexistent_metric():
     )
     desired_metrics = (mean, stdev)
 
+    # noinspection PyUnusedLocal
     with pytest.raises(ge_exceptions.MetricProviderError) as e:
         # noinspection PyUnusedLocal
         metrics = engine.resolve_metrics(metrics_to_resolve=desired_metrics)
@@ -625,91 +457,6 @@ def test_get_batch_data(test_df):
         PandasExecutionEngine().get_batch_data(RuntimeDataBatchSpec())
 
 
-def test_get_batch_with_split_on_whole_table_runtime(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df, splitter_method="_split_on_whole_table"
-        )
-    )
-    assert split_df.dataframe.shape == (120, 10)
-
-
-def test_get_batch_with_split_on_whole_table_filesystem(
-    test_folder_connection_path_csv,
-):
-    test_df = PandasExecutionEngine().get_batch_data(
-        PathBatchSpec(
-            path=os.path.join(test_folder_connection_path_csv, "test.csv"),
-            reader_method="read_csv",
-            splitter_method="_split_on_whole_table",
-        )
-    )
-    assert test_df.dataframe.shape == (5, 2)
-
-
-def test_get_batch_with_split_on_whole_table_s3(
-    batch_with_split_on_whole_table_s3, test_df_small
-):
-    df = PandasExecutionEngine().get_batch_data(
-        batch_spec=batch_with_split_on_whole_table_s3
-    )
-    assert df.dataframe.shape == test_df_small.shape
-
-
-def test_get_batch_with_split_on_whole_table_s3_with_configured_asset_s3_data_connector(
-    test_s3_files, test_df_small
-):
-    bucket, _keys = test_s3_files
-    expected_df = test_df_small
-
-    execution_engine: ExecutionEngine = PandasExecutionEngine()
-
-    my_data_connector = ConfiguredAssetS3DataConnector(
-        name="my_data_connector",
-        datasource_name="FAKE_DATASOURCE_NAME",
-        bucket=bucket,
-        execution_engine=execution_engine,
-        prefix="",
-        assets={"alpha": {}},
-        default_regex={
-            "pattern": "alpha-(.*)\\.csv",
-            "group_names": ["index"],
-        },
-    )
-    batch_def = BatchDefinition(
-        datasource_name="FAKE_DATASOURCE_NAME",
-        data_connector_name="my_data_connector",
-        data_asset_name="alpha",
-        batch_identifiers=IDDict(index=1),
-        batch_spec_passthrough={
-            "reader_method": "read_csv",
-            "splitter_method": "_split_on_whole_table",
-        },
-    )
-    test_df = execution_engine.get_batch_data(
-        batch_spec=my_data_connector.build_batch_spec(batch_definition=batch_def)
-    )
-    assert test_df.dataframe.shape == expected_df.shape
-
-    # if key does not exist
-    batch_def_no_key = BatchDefinition(
-        datasource_name="FAKE_DATASOURCE_NAME",
-        data_connector_name="my_data_connector",
-        data_asset_name="alpha",
-        batch_identifiers=IDDict(index=9),
-        batch_spec_passthrough={
-            "reader_method": "read_csv",
-            "splitter_method": "_split_on_whole_table",
-        },
-    )
-    with pytest.raises(ge_exceptions.ExecutionEngineError):
-        execution_engine.get_batch_data(
-            batch_spec=my_data_connector.build_batch_spec(
-                batch_definition=batch_def_no_key
-            )
-        )
-
-
 def test_get_batch_s3_compressed_files(test_s3_files_compressed, test_df_small):
     bucket, keys = test_s3_files_compressed
     path = keys[0]
@@ -748,152 +495,6 @@ def test_get_batch_with_no_s3_configured():
         execution_engine_no_s3.get_batch_data(batch_spec=batch_spec)
 
 
-def test_get_batch_with_split_on_column_value(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_column_value",
-            splitter_kwargs={
-                "column_name": "batch_id",
-                "batch_identifiers": {"batch_id": 2},
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (12, 10)
-    assert (split_df.dataframe.batch_id == 2).all()
-
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_column_value",
-            splitter_kwargs={
-                "column_name": "date",
-                "batch_identifiers": {"date": datetime.date(2020, 1, 30)},
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (3, 10)
-
-
-def test_get_batch_with_split_on_converted_datetime(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_converted_datetime",
-            splitter_kwargs={
-                "column_name": "timestamp",
-                "batch_identifiers": {"timestamp": "2020-01-30"},
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (3, 10)
-
-
-def test_get_batch_with_split_on_divided_integer(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_divided_integer",
-            splitter_kwargs={
-                "column_name": "id",
-                "divisor": 10,
-                "batch_identifiers": {"id": 5},
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (10, 10)
-    assert split_df.dataframe.id.min() == 50
-    assert split_df.dataframe.id.max() == 59
-
-
-def test_get_batch_with_split_on_mod_integer(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_mod_integer",
-            splitter_kwargs={
-                "column_name": "id",
-                "mod": 10,
-                "batch_identifiers": {"id": 5},
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (12, 10)
-    assert split_df.dataframe.id.min() == 5
-    assert split_df.dataframe.id.max() == 115
-
-
-def test_get_batch_with_split_on_multi_column_values(test_df):
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_multi_column_values",
-            splitter_kwargs={
-                "column_names": ["y", "m", "d"],
-                "batch_identifiers": {
-                    "y": 2020,
-                    "m": 1,
-                    "d": 5,
-                },
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (4, 10)
-    assert (split_df.dataframe.date == datetime.date(2020, 1, 5)).all()
-
-    with pytest.raises(ValueError):
-        # noinspection PyUnusedLocal
-        split_df = PandasExecutionEngine().get_batch_data(
-            RuntimeDataBatchSpec(
-                batch_data=test_df,
-                splitter_method="_split_on_multi_column_values",
-                splitter_kwargs={
-                    "column_names": ["I", "dont", "exist"],
-                    "batch_identifiers": {
-                        "y": 2020,
-                        "m": 1,
-                        "d": 5,
-                    },
-                },
-            )
-        )
-
-
-def test_get_batch_with_split_on_hashed_column(test_df):
-    with pytest.raises(ge_exceptions.ExecutionEngineError):
-        # noinspection PyUnusedLocal
-        split_df = PandasExecutionEngine().get_batch_data(
-            RuntimeDataBatchSpec(
-                batch_data=test_df,
-                splitter_method="_split_on_hashed_column",
-                splitter_kwargs={
-                    "column_name": "favorite_color",
-                    "hash_digits": 1,
-                    "batch_identifiers": {
-                        "hash_value": "a",
-                    },
-                    "hash_function_name": "I_am_not_valid",
-                },
-            )
-        )
-
-    split_df = PandasExecutionEngine().get_batch_data(
-        RuntimeDataBatchSpec(
-            batch_data=test_df,
-            splitter_method="_split_on_hashed_column",
-            splitter_kwargs={
-                "column_name": "favorite_color",
-                "hash_digits": 1,
-                "batch_identifiers": {
-                    "hash_value": "a",
-                },
-                "hash_function_name": "sha256",
-            },
-        )
-    )
-    assert split_df.dataframe.shape == (8, 10)
-
-
 ### Sampling methods ###
 
 
@@ -964,7 +565,6 @@ def test_sample_using_md5(test_df):
     ).all()
 
 
-### Splitting + Sampling methods ###
 def test_get_batch_with_split_on_divided_integer_and_sample_on_list(test_df):
     split_df = PandasExecutionEngine().get_batch_data(
         RuntimeDataBatchSpec(
@@ -988,6 +588,7 @@ def test_get_batch_with_split_on_divided_integer_and_sample_on_list(test_df):
     assert split_df.dataframe.id.max() == 59
 
 
+# noinspection PyUnusedLocal
 @mock.patch(
     "great_expectations.execution_engine.pandas_execution_engine.BlobServiceClient",
 )