测试不变式

2006 年 1 月 5 日

在设计契约 (DbC) 和测试驱动开发 (TDD) 的倡导者之间,一直存在着一种长期存在的,尽管低调的争论。我现在不会深入探讨这个问题,但我将在与Daniel Jackson交谈时,传递一个将两者融合的想法。

在 DbC 中,您为每个类定义一个不变式。此不变式声明必须始终为真的类的属性。对象必须始终满足其不变式(除非它处于执行任何操作的中间阶段)。使用 Eiffel,类不变式在调用方法之前(在先决条件检查中)和之后(在后置条件检查中)自动检查。不变式中的失败会抛出异常。(如果需要提高性能,可以在生产使用中关闭此检查。)

将此想法应用于 TDD 意味着您定义一个通用方法来测试生产类中的不变式,并在测试代码中对其进行测试。

现在是时候进行通常的琐碎示例了。

public class Bowler ...
    int overs, runs, wickets;

保龄球运动员的简单不变式是这些值都应该是非负数。因此,您可以这样定义一个不变式。

    public boolean passesInvariant() {
        return (runs >= 0 && overs >= 0 && wickets >= 0);
    }

然后,您将在测试的设置和练习阶段之后使用它。

    public void testConcedingRunsAddsToRunsScore() {
        Bowler botham = new Bowler();       // setup - showing my age
        assert botham.passesInvariant();
        botham.concedeRuns(4);              //exercise
        assert botham.passesInvariant();
        assertEquals(4, botham.getRuns());  //verify
    }

我自己还没有尝试过这个,也不知道其他人是否尝试过。但我认为这是一个有趣的思想,值得一提。