CakePHP3.4项目中PHPUnit无法识别Fixture变更,如何强制重载?
解决CakePHP 3.4 + PHPUnit 5.7 Fixture修改后不生效的问题
你遇到的这个问题确实是CakePHP的元数据缓存机制在搞鬼——为了提升测试运行效率,CakePHP会把Fixture对应的表结构元数据缓存起来,修改Fixture后缓存没更新,PHPUnit自然读不到新的字段。下面给你几个实用的解决办法,不用每次重启:
1. 手动清理CakePHP缓存目录
CakePHP的模型元数据缓存存在这两个目录:
tmp/cache/modelstmp/cache/persistent
直接删除这两个目录下的所有文件,就能强制CakePHP重新读取Fixture的新结构。如果嫌手动删麻烦,也可以用CakePHP的命令行工具一键清理:
bin/cake cache clear_all
2. 在PHPUnit配置中禁用持久化缓存
你可以修改项目的phpunit.xml文件,在测试环境下把缓存驱动改成数组缓存(完全不持久化,只在当前进程有效)。找到<php>节点,添加或修改这两个配置:
<php> <ini name="CACHE_DEFAULT" value="array"/> <ini name="CACHE_CAKE_MODEL" value="array"/> </php>
这样每次运行测试时,CakePHP都不会缓存元数据,修改Fixture后直接生效,缺点是测试启动速度会稍微慢一点,但换来了开发时的便捷。
3. 在测试类中主动刷新元数据
如果不想全局禁用缓存,也可以在单个测试类的setUp()方法里,手动刷新对应表的元数据。比如你修改了ArticlesFixture,就在测试类里加这段代码:
public function setUp() { parent::setUp(); // 清除连接的表结构缓存 $connection = ConnectionManager::get('test'); $connection->getSchemaCollection()->clear(); // 刷新对应表的 schema $articlesTable = $this->getTableLocator()->get('Articles'); $articlesTable->getSchema()->refresh(); }
这样每次执行这个测试类时,都会先清理缓存再加载新的Fixture结构。
4. 重启PHP-FPM(兜底方案)
如果你是用bin/cake server或者PHP-FPM运行测试,有时候缓存会存在PHP进程里,这时候清理文件可能没用,需要重启PHP-FPM或者关闭内置服务器再重新启动——不过这是最后的兜底方案,前面三个方法应该能解决大部分情况。
内容的提问来源于stack exchange,提问作者Arie B.
相关产品推荐
相关产品推荐

