测试数据库在 Django Channels Pytest 测试期间不保留数据

Vin*_*Vin 2 python django pytest python-3.x django-channels

我正在按照文档为 Django Channels 应用程序编写测试。我可以成功测试与 WebSocket 使用者的连接和通信。但是,在其中一项测试中我需要创建一个用户。

这是我的测试方法:

@pytest.mark.django_db
@pytest.mark.asyncio
async def test_1():
    my_user = get_user_model().objects.create_user(username='my_user', email='user@user.com', password='123456')
    my_user.save()

    print(User.objects.all())

    communicator = WebsocketCommunicator(MyConsumer, '/websocket/')
    communicator.instance.scope['user'] = my_user
    connected, subprotocol = await communicator.connect()
    assert connected
    await communicator.send_json_to({
        'command': 'test',
    })
    response = await communicator.receive_json_from(timeout=5)
    await communicator.disconnect()
Run Code Online (Sandbox Code Playgroud)

该错误发生在处理该案例的方法内部'command' == 'test'。当它尝试保存另一个以 User 作为外键的模型实例时,测试失败。

client = Client(user=scope['user'])
client.save()
Run Code Online (Sandbox Code Playgroud)

如果我将 a 添加print(User.objects.all())到使用者内部的方法(前两行之间),它将返回一个空的 QuerySet,而print测试方法本身中的第一个返回创建的用户。当然,由于没有用户,测试失败并显示:

django.db.utils.IntegrityError: insert or update on table "chat_client" violates foreign key constraint "chat_client_user_id_d10928fc_fk_auth_user_id"
DETAIL:  Key (user_id)=(1) is not present in table "auth_user".
Run Code Online (Sandbox Code Playgroud)

我尝试将用户创建转换为另一个异步方法并await对其进行 ing,但没有任何改变。为什么User在测试执行期间表被清空?如何保留测试开始时创建的数据?

Vin*_*Vin 5

正如 @hoefling 在评论中指出的,唯一缺少的是使测试具有事务性,如这个问题所示。

就我而言,我只需将测试装饰器更改为:

@pytest.mark.django_db(transaction=True)
Run Code Online (Sandbox Code Playgroud)