【问题标题】:When writing negative unit tests, should one test for "environmental response"?在编写负面单元测试时,是否应该测试“环境响应”?
【发布时间】:2015-04-11 14:53:27
【问题描述】:

想象一下我有一个简单的“最好的不可变”结构类:

class Foobar(object):
    __slots__ = ('_foo', '_bar')

    def __init__(self, *, foo, bar):
        self._foo = foo
        self._bar = bar

    foo = property(lambda self: self._foo)
    bar = property(lambda self: self._bar)

    def woof(self):
        return self._foo + self._bar

我可以想到这些明显的测试来测试这个类:

  • Foobar(foo=-20, bar=62).foo == -20
  • Foobar(foo=-20, bar=62).bar == 62
  • Foobar(foo=-20, bar=62).woof() == 42
  • Foobar(foo=-20, bar=62).foo = 314 应该抛出 AttributeError
  • Foobar(foo=-20, bar=62).bar = 314 应该抛出 AttributeError

但是,这些测试仅适用于满意的情况。但是当涉及到测试不成功时,我被困住了:

  1. 我应该测试构造函数抛出无关的参数吗?抛出位置参数?抛出缺少关键字参数?
  2. 我是否应该测试不能为该实例分配其他属性?
  3. 我应该测试woof() 不接受参数吗?
  4. 我是否应该通过一些不适合上下文的类型(整数、浮点数、列表、元组、字典、无、集合、冻结集、字节、字符串、正则表达式、切片、帧、函数、绑定方法等)的笛卡尔积进行暴力破解on) 并尝试foobar 的每种可能组合?如果需要,如何将类型选择到该集合中?

“环境响应”是指运行时对代码所做的隐式工作。当给出的参数不足/无关的参数时,不是我的代码直接抛出 TypeError,而是基于我的代码的运行时检查。

通过类型列表的笛卡尔积进行暴力破解,我的意思是尝试以下操作:

Foobar(foo=0,         bar=0        ).woof()
Foobar(foo=0,         bar=None     ).woof()
Foobar(foo=0,         bar=lambda: 0).woof()
Foobar(foo=0,         bar=()       ).woof()
Foobar(foo=0,         bar=(10, )   ).woof()
Foobar(foo=0,         bar=""       ).woof()
Foobar(foo=0,         bar="test"   ).woof()
Foobar(foo=0,         bar=True     ).woof()
...
Foobar(foo=None,      bar=0        ).woof()
Foobar(foo=None,      bar=None     ).woof()
Foobar(foo=None,      bar=lambda: 0).woof()
Foobar(foo=None,      bar=()       ).woof()
Foobar(foo=None,      bar=(10, )   ).woof()
Foobar(foo=None,      bar=""       ).woof()
Foobar(foo=None,      bar="test"   ).woof()
Foobar(foo=None,      bar=True     ).woof()
...
Foobar(foo=lambda: 0, bar=0        ).woof()
Foobar(foo=lambda: 0, bar=None     ).woof()
Foobar(foo=lambda: 0, bar=lambda: 0).woof()
Foobar(foo=lambda: 0, bar=()       ).woof()
Foobar(foo=lambda: 0, bar=(10, )   ).woof()
Foobar(foo=lambda: 0, bar=""       ).woof()
Foobar(foo=lambda: 0, bar="test"   ).woof()
Foobar(foo=lambda: 0, bar=True     ).woof()
...

【问题讨论】:

    标签: python unit-testing tdd methodology


    【解决方案1】:

    一般来说,我会说不。 Python 的座右铭之一是“我们都是负责任的用户”。

    您应该测试超出规范的使用情况的唯一情况是,您是否可以为用户提供强有力的理由,让他们期望该功能能够正常工作。在这种情况下,您还应该考虑只实现该行为 - 毕竟这是预期的。

    【讨论】:

    • 好的,这可能会算作错误类型的喂养课程,因为这完全是成年人同意的失败,所以#4 已经出局了。但是#1#2 呢?根据测试驱动的方法,每一行代码都必须在编写之前进行测试。因此,为了“有权”向构造函数写入参数列表,以及“有权”限制__slots__something 必须在之前进行测试——但究竟是什么?跨度>
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    • 2013-08-11
    • 2022-12-01
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    相关资源
    最近更新 更多