nteract / testbook

🧪 📗 Unit test your Jupyter Notebooks the right way
https://testbook.readthedocs.io
BSD 3-Clause "New" or "Revised" License
416 stars 37 forks source link

Testbook fails when using pytest test-classes #132

Open bytinbit opened 3 years ago

bytinbit commented 3 years ago

If I want to group my tests using regular pytest test classes, testbook is unable to execute and fails. It might be because the self argument of the test class method is erroneously filled in by the fixture.

Code cell to be tested (just for the record):

def reverse(items):
    reversed = []
    for item in items:
        reversed.insert(0, item)
    return reversed

fruits = ['apple', 'pear', 'cherry', 'lemon', 'mango']
print(reverse(fruits))

Test code that reproduces the error:

from pathlib import Path
from testbook import testbook

path = Path("lists.ipynb")

class TestReversingLists:
    @testbook(path, execute="reversing_lists")  # tag set in notebook
    def test_reversing_lists_output(self, tb):  # note the self
        reverse = tb.get("reverse")
        result = reverse(["alpha", "beta", "gamma", "delta", "epsilon", "zeta"])
        assert result == ["zeta", "epsilon", "delta", "gamma", "beta", "alpha"]

Error output when executing pytest + the file that contains the above code:

======================================================= FAILURES ========================================================
____________________________________ TestReversingLists.test_reversing_lists_output _____________________________________

self = <testbook.client.TestbookNotebookClient object at 0x7f787991b5b0>
tb = <test_reversing_lists.TestReversingLists object at 0x7f787748b0d0>

    @testbook(path, execute="reversing_lists")
    def test_reversing_lists_output(self, tb):
>       reverse = tb.get("reverse")
E       AttributeError: 'TestReversingLists' object has no attribute 'get'

04-lists/tests/test_reversing_lists.py:9: AttributeError
================================================ short test summary info ================================================
FAILED 04-lists/tests/test_reversing_lists.py::TestReversingLists::test_reversing_lists_output - AttributeError: 'Test...
=================================================== 1 failed in 1.29s ===================================================

Without a test class, the code works perfectly fine when executing pytest + the file that contains the above code:

from pathlib import Path
from testbook import testbook

path = Path("lists.ipynb")

@testbook(path, execute="reversing_lists")  # tag set in notebook
def test_reversing_lists_output(tb):
    reverse = tb.get("reverse")
    result = reverse(["alpha", "beta", "gamma", "delta", "epsilon", "zeta"])
    assert result == ["zeta", "epsilon", "delta", "gamma", "beta", "alpha"]

Output:

================================================== test session starts ==================================================
# details edited for privacy
collected 1 item                                                                                                        

04-lists/tests/test_reversing_lists.py .                                                                          [100%]

=================================================== 1 passed in 1.28s ===================================================
BugDiver commented 2 years ago

This issue happens when using testbook with unittest module as well. I can think of two passible aproaches to mitigate this issue (without breaking backward comapatiblity)

@rohitsanj

BugDiver commented 2 years ago

@bytinbi Here is the workaround which worked for me

Use the testbook method as context manager instead of as a decorator


import unitest
from testbook import testbook

class TestFoo(unittest.TestCase):
    def test_foo(self):
        with testbook(path, execute=True) as nb:
            foo = nb.ref("foo")
            res = foo();
            self.asssertIsNotNone(res)

Altough the implementation is for unittest but I guess it applies to pytest as well.