Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: test_suite() missing 2 required positional arguments: '________step_name_' and 'request' #40

Closed
IvanHrytskiv opened this issue Dec 22, 2020 · 15 comments

Comments

@IvanHrytskiv
Copy link

from pytest_steps import test_steps
from seleniumbase import BaseCase

class MMMM(BaseCase):

@test_steps('step_a', 'step_b', 'step_c')
def test_suite(self):
    # Step A
    print("step a")
    assert not False  # replace with your logic
    intermediate_a = 'hello'
    yield

    # Step B
    print("step b")
    assert not False  # replace with your logic
    yield

    # Step C
    print("step c")
    new_text = intermediate_a + " ... augmented"
    print(new_text)
    assert len(new_text) == 56
    yield
@IvanHrytskiv
Copy link
Author

When I am try pytest test_my_1111.py --html=4444444444.html
I have errors:

pytest test_my_1111.py --html=4444444444.html
(Running with --headless on Linux. Use --headed or --gui to override.)
============================================================================================ test session starts =============================================================================================
platform linux -- Python 3.6.9, pytest-6.2.1, py-1.10.0, pluggy-0.13.1
rootdir: /opt/PycharmProject/SelenBase/SeleniumBase, configfile: pytest.ini
plugins: html-profiling-1.0.0, html-reporter-0.2.3, xdist-2.2.0, forked-1.3.0, ordering-0.6, rerunfailures-9.1.1, steps-1.7.3, allure-pytest-2.8.29, metadata-1.11.0, cov-2.10.1, seleniumbase-1.51.4
collected 2 items

test_my_1111.py FF

================================================================================================== FAILURES ==================================================================================================
_____________________________________________________________________________________________ MMMM.test_my_12345 _____________________________________________________________________________________________

self = <examples.test_my_1111.MMMM testMethod=test_my_12345>

def test_my_12345(self):
    with allure.step('Моя перша алюра'):
        assert True

    with allure.step('Моя second алюра'):
      assert False

E AssertionError: assert False

test_my_1111.py:32: AssertionError
______________________________________________________________________________________________ MMMM.test_suite _______________________________________________________________________________________________

self = <unittest.case._Outcome object at 0x7f13e196ec18>, test_case = <examples.test_my_1111.MMMM testMethod=test_suite>, isTest = True

@contextlib.contextmanager
def testPartExecutor(self, test_case, isTest=False):
    old_success = self.success
    self.success = True
    try:
      yield

/usr/lib/python3.6/unittest/case.py:59:


self = <examples.test_my_1111.MMMM testMethod=test_suite>, result =

def run(self, result=None):
    orig_result = result
    if result is None:
        result = self.defaultTestResult()
        startTestRun = getattr(result, 'startTestRun', None)
        if startTestRun is not None:
            startTestRun()

    result.startTest(self)

    testMethod = getattr(self, self._testMethodName)
    if (getattr(self.__class__, "__unittest_skip__", False) or
        getattr(testMethod, "__unittest_skip__", False)):
        # If the class or method was skipped.
        try:
            skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                        or getattr(testMethod, '__unittest_skip_why__', ''))
            self._addSkip(result, self, skip_why)
        finally:
            result.stopTest(self)
        return
    expecting_failure_method = getattr(testMethod,
                                       "__unittest_expecting_failure__", False)
    expecting_failure_class = getattr(self,
                                      "__unittest_expecting_failure__", False)
    expecting_failure = expecting_failure_class or expecting_failure_method
    outcome = _Outcome(result)
    try:
        self._outcome = outcome

        with outcome.testPartExecutor(self):
            self.setUp()
        if outcome.success:
            outcome.expecting_failure = expecting_failure
            with outcome.testPartExecutor(self, isTest=True):
              testMethod()

E TypeError: test_suite() missing 2 required positional arguments: '_______step_name' and 'request'

/usr/lib/python3.6/unittest/case.py:605: TypeError
------------------------------------------------------ generated html file: file:///opt/PycharmProject/SelenBase/SeleniumBase/examples/4444444444.html -------------------------------------------------------
----------------------------------------------------------------- LogPath: /opt/PycharmProject/SelenBase/SeleniumBase/examples/latest_logs/ ------------------------------------------------------------------
========================================================================================== short test summary info ===========================================================================================
FAILED test_my_1111.py::MMMM::test_my_12345 - AssertionError: assert False
FAILED test_my_1111.py::MMMM::test_suite - TypeError: test_suite() missing 2 required positional arguments: '_______step_name' and 'request'
============================================================================================= 2 failed in 3.74s ==============================================================================================

@smarie
Copy link
Owner

smarie commented Jan 4, 2021

Hi @IvanHrytskiv , thanks for reaching out !

Does the bug appear when you run this outside of selenium, but still in a class ? I'm trying to figure out if this due to a conflict with the selenium framework, or to the fact that this is a test method inside a class (and not a module-level function)

What @test_steps does is that it wraps your function with a test function that requires two new arguments ('_______step_name' and 'request', as can be seen in the stack trace), and it decorates it with a @pytest.mark.parametrize if I remember well, in order to change the values for '_______step_name'. 'requests' is a fixture that pytest injects automatically when present in a test function signature. So both should be injected by pytest in the end.

@IvanHrytskiv
Copy link
Author

IvanHrytskiv commented Jan 4, 2021 via email

@smarie
Copy link
Owner

smarie commented Jan 5, 2021

I'm sorry but I cant' reproduce the error on my side. The following code works correctly:

from pytest_steps import test_steps

class TestClass:
    @test_steps('step_a', 'step_b', 'step_c')
    def test_suite(self):
        # Step A
        print("step a")
        assert not False  # replace with your logic
        intermediate_a = 'hello'
        yield

        # Step B
        print("step b")
        assert not False  # replace with your logic
        yield

        # Step C
        print("step c")
        new_text = intermediate_a + " ... augmented"
        print(new_text)
        assert len(new_text) == 19
        yield

Do you confirm ?

@IvanHrytskiv
Copy link
Author

IvanHrytskiv commented Jan 5, 2021 via email

@smarie
Copy link
Owner

smarie commented Jan 5, 2021

So this is an issue with seleniumbase apparently. I opened an issue there: seleniumbase/SeleniumBase#772

@IvanHrytskiv
Copy link
Author

IvanHrytskiv commented Jan 5, 2021 via email

@mdmintz
Copy link

mdmintz commented Jan 5, 2021

@IvanHrytskiv , @smarie See: seleniumbase/SeleniumBase#772 (comment)
It's an issue with pytest + unittest.TestCase compatibility, and there are 2 solutions (both mentioned in the link above). Either a small change needs to be made to pytest-steps, or users need to use SeleniumBase's sb fixture when creating tests with SeleniumBase that use parameter-passing fixtures that aren't set to autouse.

@smarie
Copy link
Owner

smarie commented Jan 5, 2021

So @IvanHrytskiv the following should work:

from pytest_steps import test_steps

class TestMMMM():

    @test_steps('step_a', 'step_b', 'step_c')
    def test_suite(self, sb):
        # Step A
        print("step a")
        assert not False  # replace with your logic
        intermediate_a = 'hello'
        yield
    
        # Step B
        print("step b")
        assert not False  # replace with your logic
        yield
    
        # Step C
        print("step c")
        new_text = intermediate_a + " ... augmented"
        print(new_text)
        assert len(new_text) == 19
        yield

Note the added sb parameter in the test function arguments, and the removed inheritance of BaseCase

@IvanHrytskiv
Copy link
Author

Thanks !!!!))))
Great job ))))

@mdmintz
Copy link

mdmintz commented Jan 5, 2021

The class line may need to be class Test_MMMM(): for pytest test discovery to pick it up during test collection. And if you use SeleniumBase methods inside, it would now start with sb. instead of self.. Example: sb.open(URL).

@smarie
Copy link
Owner

smarie commented Jan 5, 2021

I updated the example, thanks @mdmintz ! @IvanHrytskiv I close this ticket since it seems to solve the issue on your side. If this is not the case feel free to reopen. Thanks again for contributing !

@smarie smarie closed this as completed Jan 5, 2021
@IvanHrytskiv
Copy link
Author

IvanHrytskiv commented Jan 5, 2021 via email

@IvanHrytskiv
Copy link
Author

IvanHrytskiv commented Jan 8, 2021 via email

@smarie
Copy link
Owner

smarie commented Jan 10, 2021

Hi @IvanHrytskiv , unfortunately I have no experience with celery nor selenium :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants