Testing for side-effects in python

旧城冷巷雨未停 提交于 2019-12-08 08:12:23

问题


I want to check that my function has no side-effects, or only side-effects affecting precise variables. Is there a function to check that it actually has no side-effects (or side-effects on only certain variables)?

If not, how can I go about writing my own as follows:

My idea would be something like this, initialising, calling the function under test, and then calling the final method:

class test_side_effects(parents_scope, exclude_variables=[]):
    def __init__():
        for variable_name, variable_initial in parents_scope.items():
            if variable_name not in exclude_variables:
                setattr(self, "test_"+variable_name, variable_initial)
    def final(self, final_parents_scope):
        for variable_name, variable_final in final_parents_scope.items():
            if variable_name[:5] is "test_" and variable_name not in exclude_variables:
                assert getattr(self, "test_"+variable_name) is variable_final, "Unexpected side effect of %s from %s to %s" % (variable_name, variable_initial, variable_final)

#here parents_scope should be inputted as dict(globals(),**locals())

I'm unsure if this is precisely the dictionary I want...

Finally, should I be doing this? If not, why not?


回答1:


I'm not familiar with the nested function testing library that you might be writing a test with, but it seems like you should really be using classes here (i.e. TestCase in many frameworks).

If your question then, is relating to getting the parent variables in your TestCase, you could get the __dict__ (It wasn't clear to me what the "Parent" variables you were referring to.

UPDATE: @hayden posted a gist to show the use of parent variables:

def f():
    a = 2
    b = 1
    def g():
        #a = 3
        b = 2
        c = 1
        print dict(globals(), **locals()) #prints a=1, but we want a=2 (from f)
    g()
a = 1
f()

If this is converted to a dictionary, then the problem is solvable with:

class f(object): # could be unittest TestCase
    def setUp(self, a=2, b=1):
        self.a = a
        self.b = b

    def g(self):
        #a = 3
        b = 2
        c = 1
        full_scope = globals().copy()
        full_scope.update(self.__dict__)
        full_scope.update(locals())
        full_scope.pop('full_scope')
        print full_scope # print a = 1

my_test = f()
my_test.setUp(a=1)
my_test.g()

You are right to look for a tool which has already implemented this. I am hopeful that somebody else will have an already implemented solution.



来源:https://stackoverflow.com/questions/11559401/testing-for-side-effects-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!