我正在编写一个项目的单元测试(用PHP编写,使用PHPUnit),它的整个环境(加载的组件,事件,配置,缓存,每个环境单例等)保存在一个对象中,所有组件都使用它来进行交互彼此(使用中介模式).
为了使单元测试运行得更快,我正在共享环境对象和一些其他对象(例如,在我的测试用例中用于视图对象[如在MVC的V中],视图管理器对象[充当工厂用于视图对象并负责实际渲染])在同一测试用例中的测试中(使用PHPUnit setUpBeforeClass()
和静态属性).
尽管如此,据我所知,我共享的对象不应影响测试的完整性(例如,在视图的情况下,环境和视图管理器对象是共享的,但是为每个对象创建了一个单独的视图对象测试 - 这是测试用例实际测试的对象),它对我来说感觉越来越不对.
如果每个测试使用完全隔离的环境并且不能以任何方式影响同一测试用例中的其他测试,我宁愿使用它.然而,这会使测试运行得慢得多,感觉价格很高,我无法确切地指出其缺点,主要是"感觉不对".
你怎么看?你能否指出任何缺点,以便我可以说服自己值得更长的执行时间?或者我只是过度反应而且完全没问题?
我分享你的感受,所以也许我只是在遇到这个问题时陈述我的目标和解决方案:
开发人员应该拥有一个运行速度非常快的测试套件
至少单个测试用例应该在不到一秒的时间内执行
我真的想确定我的测试用例中没有相互依赖性
我假设您正在运行Continuous Integration Server.如果不是cronjob可能会考虑设置jenkins,那真的很容易.
只需分享尽可能多的灯具即可获得所需的速度.它可能不是很漂亮,可能会有更好的解决方案,但如果你有一些昂贵的东西,只需要做一次.
我建议帮助方法getFoo() { if(!self::$foo) .... create ... return $foo;}
,setUpBeforeClass
因为它可以使共享更容易,但主要是因为以下几点.
使用--process-isolation运行测试套件,并在该引导程序中重新创建完整的数据库和所有内容.
它可能会运行6个小时(禁用代码覆盖率!)但是如何关心.您的夹具将为每个测试用例重新创建,因为它是一个新的php进程,并且静态变量不存在.
使用这种方式,您可以确保每天都没有创建依赖项.这足以记住你做了什么(如果你需要修复一些东西,你可以运行--filter和--process-isolation).