Django使用Postgres进行测试 - 重置序列

4
到目前为止,开发和测试都是在SQLite上进行的,而生产环境是在Postgres上运行的。现在一切都需要在Postgres上运行,结果大量的测试失败了。原因是每个测试的ID不是从1开始,而是在各个测试之间继续增长。
解决这个问题的一种方法是使用TransactionTestCase,所以需要修改。
class FooCase(APITestCase):

使用

class FooCase(APITransactionTestCase):
    reset_sequences = True 

这个方法可以实现功能,但是速度变慢了。

虽然我可以尝试修复测试,但是由于许多测试具有模拟方法,所以这很困难。有没有另一种方法,可以重置序列并保持所有内容快速且整洁?


1
为什么你的测试特别依赖于以1开始的序列? - Daniel Roseman
1
你做出了明智的选择!你的应用程序不应该依赖于没有间隙的序列! - e4c5
@DanielRoseman 当我创建测试用户时,我知道他们的主键。我在JSON中使用该主键,以便在另一个文件中更易读的@mock.patch中使用。 - Bojan Kogoj
1个回答

1
您可以使用SQL在测试前重置序列:
SELECT setval(sequence_name, 1), sequence_name FROM information_schema.sequences;

但请记住以下内容:
SELECT currval('my_sequence'); --Returns 1
SELECT nextval('my_sequence'); --Returns 2

因此,如果您直接在代码中调用nextval,序列将返回2,而不是1。
此外,在Postgres中,序列类似于表格。
SELECT last_value FROM my_sequence; --Returns 1

但是这种方法绕过了currval的ACID保护,这意味着它不具备并发安全性。

但这似乎并不是一个“简洁”的解决方案。在最好的情况下,我需要创建一个Mixin并添加到所有测试中。但它可能有效。 - Bojan Kogoj
你可以将这段代码添加到创建测试用户的方法中。 - e4c5
你说得对,这不是一个干净的解决方案。但我想“问题”在于需要在单元测试中知道用户ID。在测试之前无法发现这个ID吗? - Michel Milezzi
@michel.milezzi 我在测试之前就知道ID(我在setUp中获取它),但我需要以某种方式将其传递给模拟响应,这就成为问题了,所有事情开始变得过于复杂。 - Bojan Kogoj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接