Skip to content

Commit

Permalink
Refactor Jupyter magic unit tests (#3599)
Browse files Browse the repository at this point in the history
* move fixture to conftest

Signed-off-by: Nok <nok.lam.chan@quantumblack.com>

* move fixture

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

* move dummy function out

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

* refactor multiline functions

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

* remove unncessary mock

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

* remove functions

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

* update docstring

Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>

---------

Signed-off-by: Nok <nok.lam.chan@quantumblack.com>
Signed-off-by: Nok Lam Chan <nok.lam.chan@quantumblack.com>
  • Loading branch information
noklam authored Feb 7, 2024
1 parent 9b11c59 commit 670eb09
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 166 deletions.
117 changes: 117 additions & 0 deletions tests/ipython/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import inspect

import pytest
from IPython.testing.globalipapp import get_ipython

from kedro.framework.startup import ProjectMetadata
from kedro.ipython import (
load_ipython_extension,
)
from kedro.pipeline import node
from kedro.pipeline.modular_pipeline import pipeline as modular_pipeline

from . import dummy_function_fixtures # noqa It is needed for the inspect module
from .dummy_function_fixtures import (
dummy_function,
dummy_function_with_loop,
dummy_nested_function,
)

# Constants
PACKAGE_NAME = "fake_package_name"
PROJECT_NAME = "fake_project_name"
PROJECT_INIT_VERSION = "0.1"


# Fixture
@pytest.fixture(autouse=True)
def cleanup_pipeline():
yield
from kedro.framework.project import pipelines

pipelines.configure()


@pytest.fixture(scope="module", autouse=True) # get_ipython() twice will result in None
def ipython():
ipython = get_ipython()
load_ipython_extension(ipython)
return ipython


@pytest.fixture(autouse=True)
def fake_metadata(tmp_path):
metadata = ProjectMetadata(
source_dir=tmp_path / "src", # default
config_file=tmp_path / "pyproject.toml",
package_name=PACKAGE_NAME,
project_name=PROJECT_NAME,
kedro_init_version=PROJECT_INIT_VERSION,
project_path=tmp_path,
tools=None,
example_pipeline=None,
)
return metadata


@pytest.fixture(autouse=True)
def mock_kedro_project(mocker, fake_metadata):
mocker.patch("kedro.ipython.bootstrap_project", return_value=fake_metadata)
mocker.patch("kedro.ipython.configure_project")
mocker.patch("kedro.ipython.KedroSession.create")


@pytest.fixture
def dummy_pipelines(dummy_node):
# return a dict of pipelines
return {"dummy_pipeline": modular_pipeline([dummy_node])}


def _get_function_definition_literal(func):
source_lines, _ = inspect.getsourcelines(func)
return "".join(source_lines)


@pytest.fixture
def dummy_function_defintion():
return _get_function_definition_literal(dummy_function)


@pytest.fixture
def dummy_nested_function_literal():
return _get_function_definition_literal(dummy_nested_function)


@pytest.fixture
def dummy_function_with_loop_literal():
return _get_function_definition_literal(dummy_function_with_loop)


@pytest.fixture
def dummy_module_literal():
# string representation of a dummy function includes imports, comments, and a
# file function
file_lines = inspect.getsource(dummy_function_fixtures)
return file_lines


@pytest.fixture
def dummy_node():
return node(
func=dummy_function,
inputs=["dummy_input", "extra_input"],
outputs=["dummy_output"],
name="dummy_node",
)


@pytest.fixture
def lambda_node():
return node(
func=lambda x: x,
inputs=[
"x",
],
outputs=["lambda_output"],
name="lambda_node",
)
39 changes: 39 additions & 0 deletions tests/ipython/dummy_function_fixtures.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""
This file serves as a fixture for the %load_node test_ipython.py in the testing suites.
It contains variations of import statements for testing purposes. The usage of the
`logging` library as a dummy library is intentional, as it is part of the standard
libraries, but it can be replaced with any other library for further testing scenarios.
"""

import logging # noqa
from logging import config # noqa

# this is a comment about the next import
import logging as dummy_logging # noqa


def dummy_function(dummy_input, my_input):
"""
Returns True if input is not
"""
# this is an in-line comment in the body of the function
random_assignment = "Added for a longer function"
random_assignment += "make sure to modify variable"
return not dummy_input


# Import that isn't defined at the top
import logging.config # noqa Dummy import


def dummy_nested_function(dummy_input):
def nested_function(input):
return not input

return nested_function(dummy_input)


def dummy_function_with_loop(dummy_list):
for x in dummy_list:
continue
return len(dummy_list)
Loading

0 comments on commit 670eb09

Please sign in to comment.