python - Test pollution in unittest -
this question has reply here:
“least astonishment” in python: mutable default argument 28 answersi have 2 functions, apply_rule
, match
. each defined independently - don't belong class.
match
takes 2 required paramters, , optional parameter, called pairs
. defaults empty dictionary. below code apply_rule
, match
. note match
called, , optional parameter pairs
isn't specified.
def apply_rule(pat, rule): if not isrule(rule): homecoming "not valid rule" subs = match(lhs(rule), pat) if subs == {}: homecoming pat else: homecoming substitute(rhs(rule), subs) def match(pat, lst, pairs={}): if pat == [] , lst == []: homecoming pairs elif isvariable(pat[0]): if pat[0] not in pairs.keys(): pairs[pat[0]] = lst[0] elif pat[0] in pairs.keys() , lst[0] != pairs[pat[0]]: homecoming false elif pat[0] != lst[0]: homecoming false homecoming match(pat[1:], lst[1:], pairs)
right now, unittest match
fails, because "remembers" pairs
, defined in test apply_rule
.
however, if alter 3rd line in apply_rule
subs = match(lhs(rule), pat, {})
then tests pass. do know why? far can tell, there shouldn't way match
remembers value of pairs
when called in other tests.
below unit tests, reference.
def test_match(self): self.assertequal({}, match(['a', 'b', 'c'], ['a', 'b', 'c'])) self.assertequal(self.dict_with_x, match(['a', '_x', 'c'], ['a', '5', 'c'])) self.assertequal(self.dict_with_x, match(self.pat_with_xx, self.list_with_55)) self.assertequal(self.dict_with_xy, match(self.pat_with_xy, self.list_with_5hi)) self.assertfalse(match(self.pat_with_xx, ['a', 'b', 'c', 'd'])) self.assertfalse(match(['a', 'b', 'c'], ['a', 'b', 'd'])) def test_apply_and_firerule(self): pattern1 = "my mother thinks fat".split(' ') expected = "do think fat ?".split(' ') self.assertequal(apply_rule(pattern1, self.r1), expected)
and failure message...
traceback (most recent phone call last): file "pattern_matcher_tests.py", line 65, in test_match self.assertequal({}, match(['a', 'b', 'c'], ['a', 'b', 'c'])) assertionerror: {} != {'_y': 'fat', '_x': 'mother'} - {} + {'_x': 'mother', '_y': 'fat'}
from effbot
why happen? #
default parameter values evaluated when, , when, “def” statement belong executed; see:
http://docs.python.org/ref/function.html
for relevant section in language reference.
what instead? #
the workaround is, others have mentioned, utilize placeholder value instead of modifying default value. none mutual value:
python unit-testing
No comments:
Post a Comment