Как сохранить данные django db в середине теста плейсхолдера?
Я не могу понять, как вызвать "синхронизацию" create_user()
.
Сообщение об ошибке:
django.core.exceptions.SynchronousOnlyOperation:
You cannot call this from an async context - use a thread or sync_to_async.
Однако, когда я использую sync_to_async, она не может быть ожидаемой, потому что это не асинхронная функция...
from functools import wraps
from django.test import TestCase
from playwright.sync_api import sync_playwright
def playwright_test(func):
@wraps(func)
def wrapper(self, *args, **kwargs):
with sync_playwright() as self.p:
self.browser = self.p.chromium.launch()
self.page = self.browser.new_page()
try:
result = func(self, *args, **kwargs)
finally:
self.browser.close()
return result
return wrapper
class TC(TestCase):
@playwright_test
def test_login(self):
self.page.goto(self.host)
self.page.fill('input[type="email"]', 'my@email.com')
self.page.fill('input[type="password"]', 'TestLogin')
self.page.click('text="Login"')
# expect "Incorrect Credentials" message (no user created yet)
assert "Incorrect Credentials" in self.page.content()
User = get_user_model()
User.objects.create_user('my@email.com', password='TestLogin')
# Login again, this time successfully
self.page.fill('input[type="email"]', 'my@email.com')
self.page.fill('input[type="password"]', 'TestLogin')
self.page.click('text="Login"')
assert "Login successful. Welcome back!" in self.page.content()
Если у вас есть предложение, пожалуйста, дайте мне знать, мои волосы начинают выпадать. 🙏
Вы можете избежать сообщения об ошибке следующим образом:
- https://github.com/microsoft/playwright-pytest/issues/29#issuecomment-731515676
- https://github.com/microsoft/playwright-python/issues/439
Возможно, этого будет достаточно, чтобы вы могли продолжить (я использую это обходное решение практически везде).
Что касается самого теста, вы можете попробовать что-то вроде этого:
Выполните два теста: один, где пользователь не был создан, и один, где он был создан (через приспособление create_user
).
# conftest.py
# https://github.com/microsoft/playwright-python/issues/439
# https://github.com/microsoft/playwright-pytest/issues/29#issuecomment-731515676
os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", "true")
# test_login.py
import pytest
from django.contrib.auth import get_user_model
@pytest.fixture
def user_email():
return "my@email.com"
@pytest.fixture
def user_password():
return "TestLogin"
@pytest.fixture
def create_user(user_email, user_password):
return get_user_model().objects.create_user(user_email, password=user_password)
@pytest.fixture
def host():
return "?"
class TestLogin:
def test_login_fail_no_user(self, page, host, user_email, user_password):
page.goto(host)
page.fill('input[type="email"]', user_email)
page.fill('input[type="password"]', user_password)
page.click('text="Login"')
# expect "Incorrect Credentials" message (no user created yet)
assert "Incorrect Credentials" in page.content()
def test_login_success(self, create_user, page, host, user_email, user_password):
page.goto(host)
page.fill('input[type="email"]', user_email)
page.fill('input[type="password"]', user_password)
page.click('text="Login"')
# Login again, this time successfully
assert "Login successful. Welcome back!" in page.content()
Или немного больше DRY:
@pytest.fixture
def try_login(page, host, user_email, user_password):
page.goto(host)
page.fill('input[type="email"]', user_email)
page.fill('input[type="password"]', user_password)
page.click('text="Login"')
return page
class TestLogin:
def test_login_fail_no_user(self, page, try_login):
# expect "Incorrect Credentials" message (no user created yet)
assert "Incorrect Credentials" in page.content()
def test_login_success(self, create_user, page, try_login):
# Login again, this time successfully
assert "Login successful. Welcome back!" in page.content()
Как щедро написал @CoffeeBasedLifeform в https://stackoverflow.com/a/78651148/1031191 , для django решением будет https://github.com/microsoft/playwright-pytest/issues/29#issuecomment-731515676
Копирование содержимого ссылки сюда:
Для запуска тестов Django с помощью playwright необходимо установить переменную окружения переменную DJANGO_ALLOW_ASYNC_UNSAFE = "true" django docs on this
. Это можно сделать следующим образом создав файл conftest.py в каталоге tests и установив переменную переменную окружения, используя# conftest.py import os os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE","true")