2

I really couldn't find a solution for :

PytestCollectionWarning: cannot collect test class 'TestBlaBla' because it has a init constructor

Here is my testing module and it needs to take the arguments outside of this file because at the end of the day I'm gonna call all test modules in a single file and run them all over different names and there is a bunch of names. I have to init them but when I run pytest it always ignores these classes. Idk how to handle without initializing them. If there is any suggestions I would be glad to hear.

tests/test_bla_bla.py
class TestBlaBla():
    def __init__(self, **kwargs):
     
        self.name1 = kwargs.get("name1")
        self.name2 = kwargs.get("name2")

    @pytest.fixture(scope='session')
    def load_data_here(self): 
        return load_data(self.name1) # a function comes from a utils file. it only stands for load data and it needs take a name for path
..
"continue with test_ functions that use output of load_data_here"

tests/main.py
class TestingAll:
    def __init__(self, *args, **kwargs):
        self.name1 = kwargs.get("name1")
        self.name2 = kwargs.get("name2")
        self._process()
        
    def _process(self):
        TestBlaBla(name1 = self.name1, name2= self.name2)
        TestBlaBla2(name1 = self.name1, name2= self.name2)

        
        
if __name__ == "__main__":
    Test = TestingAll(name1 = "name1", name2= "name2")
4
  • 2
    Does this answer your question? py.test skips test class if constructor is defined Commented Mar 8, 2022 at 6:43
  • 1
    I've checked it before but it doesn't give many solutions I think or I really don't know how to implement them. Commented Mar 8, 2022 at 15:51
  • The standard pytest way is to put the code into an autouse fixture. Commented Mar 8, 2022 at 15:56
  • 1
    then how can i use its output? Commented Mar 8, 2022 at 22:55

1 Answer 1

-1

Python test modules cannot have init methods as python test instantiates the class itself and there is not any way (IMHO?) to extend the instantiation and add arguments.

Yes, it is a natural idea to want to make your tests flexible by passing in command-line arguments. But you can't :-P. So you need to find another way of doing this.

Note also the if name == 'main': can work if you call the test file with python and add some code to explicitly call a py test runner. Note you do not just call your test class. A python test runner needs to be instantiated itself and run tests in a particular way.

e.g. we can have this which will allow python to instantiate and run tests in a TestingAll class (as long as it doesn't have an init method).

This uses the unittest.TextTestRunner

Note there are all sorts of python test runners, also runners like nose2 or like py.test which use a different test library.

if __name__ == '__main__':
    unittest.main()
    suite = unittest.TestLoader().loadTestsFromTestCase(TestingAll)
    unittest.TextTestRunner(verbosity=3).run(suite)

You could maybe have an ArgsProcess class to process command line args. Then iterate and set a global var with each value to be used and call the test runner each time.

But it depends on how your tests will be used.

The answers on this question already mentioned in comments explain and link to documentation for this warning:

py.test skips test class if constructor is defined

The answer on this question shows how an init method is replaced by using fixture:

Pytest collection warning due to __init__ constructor

Maybe something like this would work for you.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.