首页 > 解决方案 > 如何避免偶然的测试通过

问题描述

我有以下测试用例:

it('is to show welcome message', () => {
    spyOnProperty(authServiceSpy, 'token').and.returnValue(environment.testAuthenticationToken);

    let teacher: Teacher = authServiceSpy.token.teacher;
    let welcome: HTMLElement = ne.querySelector('#welcome-msg');
    expect(welcome).toBeTruthy();
    expect(welcome.innerHTML).toEqual(`Welcome ${teacher.firstName}`);
});

改装environment.testAuthenticationToken

testAuthenticationToken: {
    "type": "teacher",
    "emailVerified": true,
    "teacher": {
        "_id": "0000000000000000000000000",
        "title": "Teacher-X",
        "firstName": "X",
        "lastName": "X",
        "locale": "en-US",
        ...
        "emailVerified": true,
        ...
    }
}

这是相应的模板html

<div id="welcome-msg">Welcome X</div>

如果我使用 TDD 并因此从测试开始,然后寻求使测试通过的最小实现,X在这种情况下,我将在 HTML 中硬编码教师的姓名。尽管在一般情况下实现被破坏,但测试通过了。如果我今天停止工作并在第二天来运行测试,我可能会认为既然测试通过了,代码中可能没有问题。

这是一个预期的结果,重构是可能检测到它的下一步,还是使用随机期望来规避这个结果?还是我以错误的方式解决这个问题?

谢谢。

标签: angularjasminetddbdd

解决方案


如果我今天停止工作并在第二天来运行测试,我可能会认为既然测试通过了,代码中可能没有问题。

对这一特定问题的一个常见答案是改变你的工作程序,这样当你回家一天的时候总是有一个失败的测试。第二天早上,失败的测试就像一个书签,把你带回到你工作的环境中。

当然,您通常不会在这种状态下发布代码。

当 Kent Beck 在他的书中描述 TDD 时,该过程包括他希望编写的测试清单。当他有了新的想法时,他可以花点时间把它写下来,然后继续他目前的工作。他后来发现不会有趣的测试将从列表中删除。

当列表中的所有项目都被划掉并且你想不出要添加的新项目时,就会完成。

如果您的测试也是为了成为文档而编写的,那么应该直接阅读已实施测试的列表以发现差距。Kevlin Henney 关于 MRU 列表/闰年计算/堆栈的演讲展示了当问题非常小时这可能会是什么样子。

而且,当然,您也可以通过...测试代码来发现缺陷。或者在 X 以外的人第一次使用代码时报告错误(假设错误导致失败


推荐阅读