Fix Python – unittest Vs pytest


Asked By – LuckyStarr

In unittest, I can setUp variables in a class and then the methods of this class can chose whichever variable it wants to use…

class test_class(unittest.TestCase):
    def setUp(self):        
        self.varA = 1
        self.varB = 2
        self.varC = 3
        self.modified_varA = 2

    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

So in unittest, it was easy to put bunch of tests together that could go under one class and then use many different variables (varA and varB) for different methods. In pytest, I created a fixture in instead of a class in unittest, like this…

def input1():
    varA = 1
    varB = 2
    return varA, varB

def input2():
    varA = 2
    varC = 3
    return varA, varC

I feed this input1 and input2 to my functions in a different file (let’s say for two different functions. Here are the questions based on information above…

  1. Since I can’t just declare local variables in as I can’t simply import this file. Is there a better way of declaring different variables here that can be used in different functions in ? I have five different configurations in my actual testing for these variables, defining that many different fixtures in and use them as function argument in five different functions in sounds painful, I would rather go back to unittest class structure, define my variables and pick and choose what I want.

  2. Should I just declare global variables in and use them in the functions the way I want ? Seems a bit not pythonic. This variables are only used by the functions in this file.

  3. Let’s say I have and as well. If I have some shared variables between these different files, how would I declare them ? just create a file called in the directory where all these test files are and do an import whenever I need ? This way I can keep all data in a separate.

  4. Is it my impression that pytest discourages using a class to organize your functions? Every example I read online, it all seem to employ bunch of functions with fixtures only. What is a configuration of defining class and methods and organize tests in pytest?

  5. I have a test scenario where I have to use result of one function into another. With pytest, I have an assert that is at the end of a function not a return so I won’t be able to use this function as a fixture. How do I accomplish this? I know this is not a good practice that my one test relies on another but is there a work around?

Now we will see solution for issue: unittest Vs pytest


1) First of all, you can declare those fixtures not only in, but in every Python module you want. And you can import that module.
Also you can use fixtures in the same way as you used setUp method:

def input(request):
    request.cls.varA = 1
    request.cls.varB = 2
    request.cls.varC = 3
    request.cls.modified_varA = 2

class TestClass:
    def test_1(self):
        do_something_with_self.varA, self.varB

    def test_2(self):
        do_something_with_self_modified_varA, self.varC

or you can define separate variables in separate fixtures:

def fixture_a():
    return varA

def fixture_b():
    return varB

def fixture_c():
    return varC

def fixture_mod_A():
    return modified_varA

or make one fixture which returns all the variables (why not?)
or even make indirect parametrized fixture which returns variables by your choice (quite confusing way):

def parametrized_input(request):
   vars = {'varA': 1, 'varB': 2, 'varC': 3}
   var_names = request.param
   return (vars[var_name] for var_name in var_names)

@pytest.mark.parametrize('parametrized_input', [('varA', 'varC')], indirect=True)
def test_1(parametrized_input)
   varA, varC = parametrized_input

Or even you can make fixture factory which will make fixtures for you on the fly. Sounds curiously when you have only 5 tests and 5 configurations of variables, but when you get hundreds of both, it can be useful.

3) Of course you can. But I recommend you not to import this file directly, but use command line option pointing what file to import. In this case you can choose another file with variables without changing your code.

4) I use classes in my tests because I migrated from nosetest. I didn’t mention any problem with using classes in pytest.

5) In that case I propose you to do the following:
fist make the function with desired actions:

def some_actions(a, b):
    # some actions here
    return c

then use it both in test and fixture:

def test():
    assert some_actions(1,2) == 10

def some_fixture():
     return some_actions(1,2)

This question is answered By – Ilya Karpeev

This answer is collected from stackoverflow and reviewed by FixPython community admins, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0