测试治具数据
我最近开始使用单元测试,到目前为止效果非常好。
然而,我遇到了一种情况,我的方法感觉完全错误,而且我无法集中精力找到“好的”解决方案。
代码的上下文是一个用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这并不是真正的单元测试,因为它现在是这样,因为您正在通过调用 ChannelTable 来测试其边界之外的方法。
执行此操作的正确方法是将: 更改
为:
这样,如果
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:
To:
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.