单元测试数据应该简化还是现实?

时间:2017-10-31 22:06:28

标签: python unit-testing

假设我想为以下Python函数编写单元测试:

def multiply(dict_1, dict_2):
    result = {}
    for (key_1, key_2) in dict_1:
        result[(key_1, key_2)] = dict_1[(key_1, key_2)] * dict_2[key_2]
    return result

dict_1dict_2是其他功能的输出。他们不长,但看起来有点复杂:

dict_1 = {
        ('Nietzsche', 'USR1'): Decimal('0E-8'),
        ('Nietzsche', 'PKILL'): Decimal('1.49177787'),
        ('Nietzsche', 'RM'): Decimal('10971.22182930'),
        ('Nietzsche', 'LS'): Decimal('4.44771349'),
        ('Nietzsche', 'NCDU'): Decimal('5.14671343'),
        ('Nietzsche', 'SUDO'): Decimal('9.49572673'),
        ('Nietzsche', 'PS'): Decimal('0.57328494'),
        ('Hegel', 'USR1'): Decimal('0E-8'),
        ('Marx', 'NCDU'): Decimal('0E-8'),
        ('Marx', 'SUDO'): Decimal('0E-8'),
        ('Marx', 'PS'): Decimal('0E-8'),
        ('Marx', 'LS'): Decimal('0E-8'),
        ('Marx', 'PKILL'): Decimal('0E-8')
    }
dict_2 = {
        'USR1': Decimal('6357.48'),
        'PKILL': Decimal('307.277'),
        'RM': Decimal('88.232'),
        'LS': Decimal('71.1787'),
        'NCDU': Decimal('0.0389333'),
        'SUDO': Decimal('199.979'),
        'PS': Decimal('307.277')
    }

这些特定参数的此函数输出看起来有点复杂:

{
    ('Nietzsche', 'USR1'): Decimal('0E-10'),
    ('Nietzsche', 'PKILL'): Decimal('458.38902855999'),
    ('Nietzsche', 'RM'): Decimal('968012.84444279760'),
    ('Nietzsche', 'LS'): Decimal('316.582464190663'),
    ('Nietzsche', 'NCDU'): Decimal('0.200378537984219'),
    ('Nietzsche', 'SUDO'): Decimal('1898.94593573867'),
    ('Nietzsche', 'PS'): Decimal('176.15727650838'),
    ('Hegel', 'USR1'): Decimal('0E-10'),
    ('Marx', 'NCDU'): Decimal('0E-15'),
    ('Marx', 'SUDO'): Decimal('0E-11'),
    ('Marx', 'PS'): Decimal('0E-11'),
    ('Marx', 'LS'): Decimal('0E-12'),
    ('Marx', 'PKILL'): Decimal('0E-11')
}

所以我面对单元测试的两个选项。第一是通过复制粘贴所有内容来获得真实的数据:

def test_multiply_1(self):
    dict_1 = {
        ('Nietzsche', 'USR1'): Decimal('0E-8'),
        ('Nietzsche', 'PKILL'): Decimal('1.49177787'),
        ('Nietzsche', 'RM'): Decimal('10971.22182930'),
        ('Nietzsche', 'LS'): Decimal('4.44771349'),
        ('Nietzsche', 'NCDU'): Decimal('5.14671343'),
        ('Nietzsche', 'SUDO'): Decimal('9.49572673'),
        ('Nietzsche', 'PS'): Decimal('0.57328494'),
        ('Hegel', 'USR1'): Decimal('0E-8'),
        ('Marx', 'NCDU'): Decimal('0E-8'),
        ('Marx', 'SUDO'): Decimal('0E-8'),
        ('Marx', 'PS'): Decimal('0E-8'),
        ('Marx', 'LS'): Decimal('0E-8'),
        ('Marx', 'PKILL'): Decimal('0E-8')
    }
    dict_2 = {
        'USR1': Decimal('6357.48'),
        'PKILL': Decimal('307.277'),
        'RM': Decimal('88.232'),
        'LS': Decimal('71.1787'),
        'NCDU': Decimal('0.0389333'),
        'SUDO': Decimal('199.979'),
        'PS': Decimal('307.277')
    }
    expected = {
        ('Nietzsche', 'USR1'): Decimal('0E-10'),
        ('Nietzsche', 'PKILL'): Decimal('458.38902855999'),
        ('Nietzsche', 'RM'): Decimal('968012.84444279760'),
        ('Nietzsche', 'LS'): Decimal('316.582464190663'),
        ('Nietzsche', 'NCDU'): Decimal('0.200378537984219'),
        ('Nietzsche', 'SUDO'): Decimal('1898.94593573867'),
        ('Nietzsche', 'PS'): Decimal('176.15727650838'),
        ('Hegel', 'USR1'): Decimal('0E-10'),
        ('Marx', 'NCDU'): Decimal('0E-15'),
        ('Marx', 'SUDO'): Decimal('0E-11'),
        ('Marx', 'PS'): Decimal('0E-11'),
        ('Marx', 'LS'): Decimal('0E-12'),
        ('Marx', 'PKILL'): Decimal('0E-11')
    }
    actual = multiply(dict_1, dict_2)
    self.assertEqual(actual, expected)

第二个是简化使用虚拟数据:

def test_multiply_1(self):
    dict_1 = { ('Nietzsche', 'PKILL'): Decimal('1.49177787') }
    dict_2 = { 'PKILL': Decimal('307.277') }
    actual = multiply(dict_1, dict_2)
    expected = { ('Nietzsche', 'PKILL'): Decimal('458.38902855999') }
    self.assertEqual(actual, expected)

第二个更具可读性,但第一个更现实。哪一个是首选,为什么?

1 个答案:

答案 0 :(得分:3)

我赞成简化的单元测试。如果您决定更改此代码的功能,则更容易更新简化的单元测试,而不是长而复杂的测试。

除此之外,单元测试的目的是检查代码的小组件是否在其基本级别上工作以实现真实的预期输入,从而减少到最小的复杂度。如果您发现检查基本功能的单元测试过于复杂,您可能希望将该功能拆分为更小的组件本身。在这种情况下,我认为您的功能非常简单,您可以从简单的单元测试中获益,而不是复杂的单元测试。但是,这个问题肯定是基于意见的。