我有一个django应用,正在对其进行一些单元测试。因此,我遇到的问题不是当一个测试插入到测试数据库中时。这是随后的测试。由于每个测试都没有保存事务,因此很好不会显示来自先前测试的条目,尽管自动增量ID的增加似乎就好像数据库中还有条目一样。我需要解决此问题,因为我在无法控制为其分配ID的地方插入了更多数据,因此需要能够获取此特定数据进行测试。如果我对要捕获对象的代码进行硬编码,则每次添加新测试时都必须更改代码,这是不理想的。
我正在运行多个测试,但为简单起见,我将显示两个。
from django.test import TestCase
from app.models import Model
class VersionMerge(TestCase):
fixtures = ['initial_test_data.json']
def test_model_test1(self):
*Insert new data*
*grab new data in*
*Check data*
def test_model_test2(self):
*Insert new data*
*grab new data*
*Check data*
问题出现在 test_model_test2 中,当我尝试获取新数据时,我必须打印出该对象以查看ID才能获取它。
对于如何在实际数据库上解决此问题,我没有解决方案,但对于测试数据库却没有解决方案。对于我来说,我需要能够连接到Docker容器并运行psql命令以重置table_id_seq。
docker exec -t $CONTAINER_ID psql --dbname=test_database_name -username=user -c "SELECT setval('modelName_appName_id_seq', 2, true)"
这将转到表并将最后一个id值设置为2,以使下一个id为3。但是,每当我尝试使用
从python内部运行命令时,cmd = "command above"
os.system(cmd)
,当我运行它时,出现以下错误。
sh: 1: docker: not found
sh: 1: docker: not found
在此方面寻求任何帮助,无论是解决问题的新方法还是我的改进。
TLDR;我需要能够修改django单元测试创建的数据库中的数据。
答案 0 :(得分:0)
与数据库有交互作用的测试不称为单元测试。它们称为集成测试。 如果您希望每次都重置数据库,建议使用django测试用例:
from django.test import TestCase
答案 1 :(得分:0)
您正在使用Fixtures文件-将所需的任何数据放入其中;然后根据需要在测试中对其进行编辑。
尽管如此,这很难维护。我认为-还有更好的选择,可能会更符合您的预期。
最好使用factory_boy
之类的东西,并在实例化您提供的伪数据时生成模型(和相关的外键)。
这样,您就可以准确地确切知道正在测试什么,并且它完全独立于其他所有内容。令人高兴的是,有了factory_boy
,您将拥有一个factories.py
文件,与使用某些灯具相比,您可以更轻松地保持最新状态。
还有其他选项,例如Mixer
或model_mommy
,尽管我只有factory_boy
和mixer
的经验。
使用factory_boy
可能看起来像这样:
def test_model_test1(self):
factory.ModelFactory(
some_specific_attribute='some_specific_value'
)
model = Model.objects.all().first()
# Test against your model
答案 2 :(得分:0)
如果需要测试以重置主键序列,则可以发出RawSQL查询。 this StackOverflow question给出了确切的操作方法。
如果您使用的是pytest,则可以使用一个更简单的选项。我们在所有Django项目中都使用pytest和pytest-django,这使测试变得轻而易举。 pytest-django提供a database fixture that can take a boolean parameter to reset the sequences。像这样使用它:
@pytest.mark.django_db(transaction=True, reset_sequences=True)
def mytest():
[...]
答案 3 :(得分:0)
我通过将 TestCase
替换为 TransactionTestCase 并设置 reset_sequences=True
来实现此目的。但是测试运行速度较慢。
from django.test import TransactionTestCase
class ViewTest(TransactionTestCase):
reset_sequences = True
def test_view_redirects(self):
...
这是doc