测试治具数据

发布于 2024-10-04 06:42:14 字数 1585 浏览 0 评论 0原文

我最近开始使用单元测试,到目前为止效果非常好。

然而,我遇到了一种情况,我的方法感觉完全错误,而且我无法集中精力找到“好的”解决方案。

代码的上下文是一个用 symfony 编写的用于查看电视广播时间表的应用程序,并使用 sfPHPUnit2Plugin 进行了测试。

public function testLoadChannelBroadcasts() {

    $Start = new DateTime();
    $End = new DateTime();

    $Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);

    foreach ($Channels as $Channel) {
      $Channel->loadBroadcastsTouchingTimeSpan($Start, $End);
    }

    // test data

    $Broadcasts = $Channels[0]->Broadcasts;

    $assertion = $Broadcasts[0]->getDateTimeObject('start') <= $Start
     && $Broadcasts[0]->getDateTimeObject('end') >= $Start;

    $this->assertTrue($assertion, 'starts before scope, ends inside scope');

    $assertion = $Broadcasts[1]->getDateTimeObject('start') >= $Start
     && $Broadcasts[1]->getDateTimeObject('end') <= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends inside scope');

    $assertion = $Broadcasts[2]->getDateTimeObject('start') >= $Start
     && $Broadcasts[2]->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends outside scope');

    $LongBroadcast = $Channels[1]->Broadcasts[0];

    $assertion = $LongBroadcast->getDateTimeObject('start') <= $Start
     && $LongBroadcast->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts before scope, ends after scope');
}

测试传达了方法的目的,但数据(夹具)的测试很大程度上依赖于对数据包含内容的假设。有更好的方法吗?

I've recently started using unit tests and it's been a blast so far.

However, I've bumped into a situation where my approach feels plain wrong and I can't wrap my head around a "good" solution.

The context for the code is an application for viewing tv broadcast schedules written in symfony, tested with sfPHPUnit2Plugin.

public function testLoadChannelBroadcasts() {

    $Start = new DateTime();
    $End = new DateTime();

    $Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);

    foreach ($Channels as $Channel) {
      $Channel->loadBroadcastsTouchingTimeSpan($Start, $End);
    }

    // test data

    $Broadcasts = $Channels[0]->Broadcasts;

    $assertion = $Broadcasts[0]->getDateTimeObject('start') <= $Start
     && $Broadcasts[0]->getDateTimeObject('end') >= $Start;

    $this->assertTrue($assertion, 'starts before scope, ends inside scope');

    $assertion = $Broadcasts[1]->getDateTimeObject('start') >= $Start
     && $Broadcasts[1]->getDateTimeObject('end') <= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends inside scope');

    $assertion = $Broadcasts[2]->getDateTimeObject('start') >= $Start
     && $Broadcasts[2]->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends outside scope');

    $LongBroadcast = $Channels[1]->Broadcasts[0];

    $assertion = $LongBroadcast->getDateTimeObject('start') <= $Start
     && $LongBroadcast->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts before scope, ends after scope');
}

The test communicates the purpose of the method, but the testing of data (fixtures) relies heavily on assumptions about what the data contains. Is there a better approach to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

み零 2024-10-11 06:42:14

这并不是真正的单元测试,因为它现在是这样,因为您正在通过调用 ChannelTable 来测试其边界之外的方法。

执行此操作的正确方法是将: 更改

$Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);

为:

$Channels = array('yourdata', 'etc');

这样,如果 ChannelTable 无法提供正确的数据,您的测试就不会失败,因为它不应该失败。

请记住,单元测试的目的是测试单元(方法)而不是其他。如果您的整个应用程序无法连接到数据库并提供数据,单元测试仍然会通过,因为该方法的行为符合其应有的行为。

This is not really a unit test as it is right now, because you are testing the method outside its boundaries, by calling ChannelTable.

The proper way of doing this would be to change:

$Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);

To:

$Channels = array('yourdata', 'etc');

This way, if ChannelTable fails to provide the correct data, your test doesn't fail, because it shouldn't.

Remember, a unit test purpose is to test the unit (method) and nothing else. If your whole application fails to connect to a database and provide data, the unit test still passes because the method behaves as it should.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文