使用 Rails Minitest,测试如何通过但在重新测试时失败?

With Rails Minitest, how do tests pass but fail when retested?

我在 Minitest 中使用事务固定装置,我的测试 运行 在我第一次 运行 时成功(并通过):

rake test test/models/number_test.rb
Run options: --seed 31462
# Running:
..
Finished in 0.271344s, 7.3707 runs/s, 7.3707 assertions/s.
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips

然而,当我再次运行时,他们失败了:

rake test test/models/number_test.rb
Run options: --seed 22968
# Running:
EE
Finished in 0.058652s, 34.0997 runs/s, 0.0000 assertions/s.

  1) Error:
  NumberTest#test_to_param_is_number:
  ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  insert or update on table "calls" violates foreign key constraint "fk_calls_extension_id"
  DETAIL:  Key (extension_id)=(760421015) is not present in table "extensions".
  : COMMIT

  2) Error: 
  NumberTest#test_twilio's_API_is_configured_to_come_to_this_number's_URL:
  ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR:  insert or update on table "calls" violates foreign key constraint "fk_calls_extension_id"
  DETAIL:  Key (extension_id)=(760421015) is not present in table "extensions".
  : COMMIT

2 runs, 0 assertions, 0 failures, 2 errors, 0 skips

我正在使用 schema_plus gem 将外键添加到我的表中。

因为固定装置是按字母顺序加载的,所以我使用了 deferrable: :initially_deferred 选项,它只在事务结束时进行参照完整性检查,因此所有数据都在检查之前加载到所有表中。这就是第一个 运行 测试起作用的原因……但是我不确定为什么第二个 运行 有什么不同。

运行重新测试时,难道不应该清空所有数据库表并使用可延迟选项重新加载固定装置吗?就像 deferrable 在第一次之后没有兑现。

为了让它工作,我总是必须在 运行 测试之间 运行 rake db:reset,这看起来很疯狂。

更新 1: 如果我注释掉 calls 的所有固定装置(实际上与 number_test.rb 中的任何测试无关),所有工作正常……我可以随心所欲地重新运行 数字测试,它们仍然通过。所以,这似乎确实与延期有关。

这是一个真正的参照完整性问题。 numberscalls 最终都 link 回到 users

事实证明,users 夹具在测试服务器上不存在。这样就可以了。

Rails 将尝试禁用数据库中的约束触发器以对其进行清理。您需要拥有超级用户角色才能完成此操作。也是:

我输入 sudo -u postgres psql 并输入:

ALTER USER yourdbusername SUPERUSER;