Home > Back-end >  Can I run unittest / pytest with python Optimization on?
Can I run unittest / pytest with python Optimization on?

Time:12-13

I just added a few assert statements to the constructor of a class.

This has had the immediate effect of making about 10 tests fail.

Rather than fiddle with those tests I'd just like to run pytest in Python's Optimization switched on (-O switch, which means the asserts are all ignored). But looking at the docs and searching I can't find a way to do this.

I'm slightly wondering whether this might be bad practice, as arguably the time to see whether asserts fail may be during testing.

On the other hand, another thought is that you might have certain tests (integration tests, etc.) which should be run without optimisation, so that the asserts take effect, and other tests where you are being less scrupulous about the objects you are creating, where it might be justifiable to ignore the asserts.

asserts obviously qualify as "part of testing"... I'd like to add more to some of my constructors and other methods, typically to check parameters, but without making hundreds of tests fail, or have to become much more complicated.

CodePudding user response:

The best way in this case would be to move all assert statements inside your test code. Maybe even switch to https://pytest.org/ as it is already using assert for test evaluation.

CodePudding user response:

I'm assuming you can't in fact do this.

Florin and chepner have both made me wonder whether and to what extent this is desirable. But one can imagine various ways of simulating something like this, for example a Verifier class:

class ProjectFile():
    def __init__(self, project, file_path, project_file_dict=None):
        self.file_path = file_path
        self.project_file_dict = project_file_dict
        if __debug__:
            Verifier.check(self, inspect.stack()[0][3]) # gives name of method we're in

class Verifier():
    @staticmethod
    def check(object, method, *args, **kwargs):
        print(f'object {object} method {method}')
        if type(object) == ProjectFile:
            project_file = object
            if method == '__init__':
                # run some real-world checks, etc.:
                assert project_file.file_path.is_file()
                assert project_file.file_path.suffix.lower() == '.docx'
                assert isinstance(project_file.file_path, pathlib.Path)
                if project_file.project_file_dict != None:
                    assert isinstance(project_file.project_file_dict, dict)

Then you can patch out the Verifier.check method easily enough in the testing code:

def do_nothing(*args, **kwargs):
    pass
verifier_class.Verifier.check = do_nothing

... so you don't even have to clutter your methods up with another fixture or whatever. Obviously you can do this on a module-by-module basis so, as I said, some modules might choose not to do this (integration tests, etc.)

  • Related