Giter VIP home page Giter VIP logo

Comments (3)

MSeal avatar MSeal commented on September 17, 2024 1

To be more specific:

We should have a decorator pattern to add a testbook Client object to a test:

@testbook.notebook(path_to_notebook)
def test_notebooks_func(notebook):
  notebook.execute_cell(1)
  notebook.assert_cell_text_output(1, "Hello World")
  notebook.execute_cell(2) # Should use the same kernel without shutting it down until the test completes
  notebook.assert_cell_text_output(2, "Hello World 2")

and to support a fixture pattern something like this:

@pytest.fixture()
def notebook_tester():
  def notebook_loader(nb_path):
    nb = testbook.NotebookClient(nb_path)
    with nb.setup_kernel(**kwargs):
      yield nb
....

from testbook import notebook_tester

def test_notebooks_func(notebook_tester):
  with notebook_tester(nb_path) as notebook:
    notebook.execute_cell(1)
    notebook.assert_cell_text_output(1, "Hello World")
    notebook.execute_cell(2) # Should use the same kernel without shutting it down until the test completes
    notebook.assert_cell_text_output(2, "Hello World 2")

from testbook.

MSeal avatar MSeal commented on September 17, 2024 1

Yeah... there is a few hacks to get around this. Here's some useful links on the topic:

https://stackoverflow.com/questions/52060950/how-to-use-pytest-capsys-on-tests-that-have-mocking-decorators/52065289#52065289
pytest-dev/pytest#2424
https://docs.python.org/3/library/inspect.html#types-and-members (for how to hack globals)

Here's a global hack pattern I just tried out quickly and it works for python 3 with pytest:

import functools
import inspect

def wrap_test(input):
    parent_scope = inspect.stack()[1][0].f_globals  # Hack alert, needed to setup pytest fixture variables in the same scope as the test :/
    @pytest.fixture(scope='module')
    def added(): # Can make the function name dynamic or whatever is needed
        return input + '_added'

    def wrapper(func):
        @functools.wraps(func)
        def inner_wrapper(*args, **kwargs):
            if 'added' in parent_scope:
                raise RuntimeError(
                    "Can't assign fixture {name} to test because the name is already in use".format(name='added'))
            parent_scope['added'] = added
            try:
                return func(*args, **kwargs) # Can also inspect the function to get the name of the first argument if you want the name assignment to be positional instead of by name
            finally:
                # Cleanup definition if it's still present
                if 'added' in parent_scope:
                    del parent_scope['added']
        return inner_wrapper
    return wrapper

then in a test file you can do:

@wrap_test('foo')
def test_something(added):
  print(added)  # 'foo_added'

from testbook.

rohitsanj avatar rohitsanj commented on September 17, 2024
@testbook.notebook(path_to_notebook)
def test_notebooks_func(notebook):
  notebook.execute_cell(1)
  notebook.assert_cell_text_output(1, "Hello World")
  notebook.execute_cell(2) # Should use the same kernel without shutting it down until the test completes
  notebook.assert_cell_text_output(2, "Hello World 2")

The above test will not work when we run it using pytest.
It will throw an error: fixture 'notebook' not found

How do we work around this?
If there is no way, seems like we will be restricted to implementing only the fixture pattern.

from testbook.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.