简体   繁体   中英

Can I run unittest / pytest with python Optimization on?

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 assert s 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 assert s 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 assert s 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 assert s.

assert s 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.

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.

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.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM