Mar*_*ein 10 tdd cocoa animation design-patterns ios
现代用户界面,尤其是MacOS和iOS,具有大量"随意"动画 - 通过系统主要协调的简短动画序列显示的视图.
[[myNewView animator] setFrame: rect]
Run Code Online (Sandbox Code Playgroud)
偶尔,我们可能会有更精细的动画,有动画组和完成块.
现在,我可以想象这样的错误报告:
嘿 - myNewView出现的好动画在新版本中没有发生!
所以,我们希望单元测试做一些简单的事情:
但是,当然所有这些测试都必须易于编写,并且不能使代码变得更糟; 我们不想用大量的测试驱动的复杂性来破坏隐式动画的简单性!
那么,什么是TDD友好的方法来实现休闲动画的测试?
让我们举一个具体的例子来说明我们为什么要进行单元测试.假设我们有一个包含一堆WidgetViews的视图.当用户通过双击创建一个新的Widget时,它应该最初看起来很小且透明,在动画期间扩展到完整大小.
现在,我们确实不需要单元测试系统行为.但是有些事情可能会出错,因为我们犯了错误:
动画在错误的线程上调用,并且不会被绘制.但是在动画过程中,我们调用setNeedsDisplay,因此最终会得到小部件.
我们正在从废弃的WidgetControllers池中回收废弃的小部件.新的WidgetViews最初是透明的,但回收池中的某些视图仍然是不透明的.所以褪色不会发生.
在动画结束之前,在新窗口小部件上会启动一些额外的动画.结果,小部件开始出现,然后在它稳定下来之前开始猛拉和闪烁.
您对窗口小部件的drawRect:方法进行了更改,新的drawRect很慢.旧动画很好,但现在很糟糕.
所有这些都将在您的支持日志中显示为"创建窗口小部件动画不再起作用".我的经验是,一旦你习惯了动画,开发人员很难立即注意到一个不相关的变化打破了动画.这是单元测试的秘诀,对吧?
动画在错误的线程上调用,并且不会被绘制。但在动画过程中,我们调用 setNeedsDisplay,因此最终会绘制小部件。
不要直接对此进行单元测试。当动画位于不正确的线程上时,请使用断言和/或引发异常。单元测试断言将适当地引发异常。苹果公司在他们的框架上积极地做到了这一点。它可以防止你搬起石头砸自己的脚。当您使用有效参数之外的对象时,您会立即知道。
我们正在从废弃的 WidgetController 池中回收废弃的小部件。新的 WidgetView 最初是透明的,但回收池中的某些视图仍然是不透明的。所以不会发生褪色。
这就是为什么您会看到类似dequeueReusableCellWithIdentifierUITableView 中的方法。您需要一个公共方法来获取重用的 WidgetView,这是测试适当重置 alpha 等属性的绝佳机会。
在动画完成之前,新小部件上会启动一些附加动画。结果,小部件开始出现,然后开始抖动并短暂闪烁,然后才稳定下来。
与第 1 点相同。使用断言将规则强加于代码。可以触发断言的单元测试。
您对小部件的drawRect: 方法进行了更改,并且新的drawRect 速度很慢。以前的动画还不错,现在就乱了。
单元测试可以只是对方法进行计时。我经常通过计算来确保它们保持在合理的时间限制内。
-(void)testAnimationTime
{
NSDate * start = [NSDate date];
NSView * view = [[NSView alloc]init];
for (int i = 0; i < 10; i++)
{
[view display];
}
NSTimeInterval timeSpent = [start timeIntervalSinceNow] * -1.0;
if (timeSpent > 1.5)
{
STFail(@"View took %f seconds to calculate 10 times", timeSpent);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2484 次 |
| 最近记录: |