要设计合理的过滤策略来忽略某些测试。我们很容易在项目中发现只能在特定环境下通过的测试,这个特定环境可能是特定的操作系统,也可能是特定的浏览器等,之所以会产生这些测试通常是开发者需要在源码中进行一些特定环境的hack,它们并不适合在所有环境下运行,也无法在所有环境中稳定的通过,因此应该设计一套机制可以有选择的运行这些测试,junit的assumeThat的机制让我再次有点失望,本着自己动手丰衣足食的原则,在junit-ext我添加了利用标注来过滤测试的机制,标注了RunIf的测试仅当条件满足时才会运行,除了内置一些Checker,开发者也可以很方便的开发自己的Checker来适应项目的需要。
@RunWith(JunitExtRunner.class) public class PlatformIsWindows implements Checker { |
要充分利用计算资源而不是人力资源来加快测试。对于加快测试,最普遍也最脆弱的方法是利用多线程来同时运行多个测试,这个方法之所以脆弱,是因为它会让编写测试/分析失败测试变的异常复杂,开发者必须考虑到当前线程在使用资源时,可能有另一个线程正要销毁同一个资源,而测试失败时,也会由于线程的不确定性,导致问题难于重现而增加了解决问题的成本。我认为一个更好的实践是在多台机器上并发运行测试,每台机器只需要运行(总测试数/机器数)个测试,这样所花费时间会近似减少为(原本测试时间/机器数)。相对与购置机器的一次性投入,手工优化的不断投入成本更高,而且很多公司都会有闲置的计算资源,利用旧机器或者在多核的机器上安装虚拟机的方式,可以很经济的增加计算资源。在项目开发的业余时间,我和我的同事们一起开发了开源的测试辅助工具test-load-balancer。在我们的项目中,通过它将需要90分钟的测试自动划分为数个10分钟左右的测试在多台虚拟机上并发运行,很好的解决了速度问题。
对mock追本溯源,我们会发现它更多扮演的是设计工具的角色而不是测试工具的角色,mock框架在设计方面的局限性李晓在《不要把Mock当作你的设计利器》一文中已经谈的很透彻,在此不再赘述。Mock不是测试的银弹,世上也并无银弹存在,测试实践能否正常开展的决定性因素是团队成员对测试流程,测试方法的不断改进而不是先进的测试框架。不要去依赖mock框架,它的强制约定常常是你改进设计和添加功能的绊脚石,改善设计,依赖一个简洁的代码环境,依赖一套可靠的测试方法才是正途。从意识到mock测试带来的负面影响,到从滥用mock的泥潭中挣扎出来,我们花费了很多时间和经历,希望这些经验可以对同行们能有所借鉴,有所启发。
Mock,还请慎用。