在单元测试中测试污染

时间:2013-02-13 00:38:55

标签: python unit-testing

我有两个功能,apply_rulematch。每个都是独立定义的 - 它们不属于任何类。

match需要两个必需的参数和一个名为pairs的可选参数。它默认为空字典。以下是apply_rulematch的代码。请注意,系统会调用match,并且未指定可选参数pairs

def apply_rule(pat, rule):
  if not isrule(rule):
    return "Not a valid rule"

  subs = match(lhs(rule), pat)
  if subs == {}:
    return pat
  else:
    return substitute(rhs(rule), subs)


def match(pat, lst, pairs={}):
  if pat == [] and lst == []:
    return pairs
  elif isvariable(pat[0]):
    if pat[0] not in pairs.keys():
      pairs[pat[0]] = lst[0]
    elif pat[0] in pairs.keys() and lst[0] != pairs[pat[0]]:
      return False
  elif pat[0] != lst[0]:
    return False
  return match(pat[1:], lst[1:], pairs) 

目前,match的单位测试失败,因为它会记住" pairs,如apply_rule测试中所定义。

但是,如果我将apply_rule中的第3行更改为subs = match(lhs(rule), pat, {}),则测试会通过。 你知道为什么吗?据我所知,match无法记住pairs在其他地方调用时的价值测试

以下是单元测试,供参考。

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 I am fat".split(' ')
    expected = "do you think you are fat ?".split(' ')
    self.assertEqual(apply_rule(pattern1, self.r1), expected)

失败的消息......

Traceback (most recent 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'}

1 个答案:

答案 0 :(得分:1)

来自effbot

  

为什么会这样? #

     

默认参数值始终在且仅当时才计算   他们所属的“def”声明被执行;见:

     

http://docs.python.org/ref/function.html

     

用于语言参考中的相关部分。

     

该怎么做? #

     

正如其他人所提到的,解决方法是使用占位符   值而不是修改默认值。没有一个共同的价值: