Django не может использовать SMTP-сервер в тестовой среде

Я запускаю приложение Django (4.1) в Docker. В рамках нашего набора тестов я хотел бы использовать SMTP-сервер разработки, который также запущен в контейнере Docker (см. docker-compose.yml ниже). Я использую драйвер Selenium для запуска тестов на экземпляре Django LiveServer. Я также использую 1secmail в качестве временного почтового ящика для тестов.

SMTP-сервер прекрасно работает с Django (т.е. Django может отправлять электронные письма с его помощью) только если Django не запущен из LiveServer. Всякий раз, когда я пытаюсь программно протестировать сценарий, в котором задействован SMTP (с помощью драйвера Selenium), электронное письмо никогда не отправляется (см. неудачный тест ниже).

Вопрос простой: как мне заставить Django и SMTP-сервер общаться друг с другом в тестовой среде?

Мой docker-compose.yml

version: '3.8'

services:
  myapp:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ./:/usr/src/app/
    ports:
      - 8009:8000
    env_file:
      - ./.env.dev
    links:
      - selenium-chrome
      - dev-smtp-server
  
  myapp-db:
    image: postgres:14-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=blabla
      - POSTGRES_PASSWORD=blabla
      - POSTGRES_DB=blabla
  
  selenium-chrome:
    image: selenium/standalone-chrome
    ports:
      - 4444:4444   # actual Selenium
      - 5900:5900   # VNC server
  
  dev-smtp-server:
    image: bytemark/smtp
    restart: always

volumes:
  postgres_data:

Мои тестовые приспособления

...
from pytest_django.live_server_helper import LiveServer

@pytest.fixture(scope="session")
def test_server() -> LiveServer:
    host = socket.gethostbyname(socket.gethostname())
    if host not in settings.ALLOWED_HOSTS:
        settings.ALLOWED_HOSTS.append(host)
    server = LiveServer(host)
    yield server
    server.stop()


@pytest.fixture
def driver():
    options = webdriver.ChromeOptions()
    driver = webdriver.Remote(
        command_executor="http://selenium-chrome:4444/wd/hub",  # connect to the Selenium container defined in docker-compose
        options=options,
    )
    yield driver
    driver.quit()


@pytest.fixture
def forgot_my_password_page_driver(driver: Remote, test_server: LiveServer):
    forgotMyPasswordURL = reverse("password_reset")
    driver.get(f"{test_server.url}{forgotMyPasswordURL}")
    return driver


@pytest.fixture
def email_address_for_which_forgotten_password_form_has_just_been_filed(
    forgot_my_password_page_driver, db
):
    emailInput = forgot_my_password_page_driver.find_element(By.NAME, "email")
    emailAddress = OneSecMailAPI.get_random_email_address()
    emailInput.send_keys(emailAddress)

    sendButton = forgot_my_password_page_driver.find_element(
        By.CSS_SELECTOR, "input[type='submit']"
    )
    sendButton.click()
    return emailAddress

Неудачный тест

def test_forgot_my_password_form_sends_an_email_to_actually_reset_your_password(
    email_address_for_which_forgotten_password_form_has_just_been_filed,
):
    emailAddress = email_address_for_which_forgotten_password_form_has_just_been_filed
    emailDomain = emailAddress.split("@")[1]

    emailReceived = False
    loopCounter = 0
    while not emailReceived and loopCounter < 5:
        messages = OneSecMailAPI.get_messages(login=emailAddress, domain=emailDomain)
        if len(messages) == 0:
            time.sleep(1)
            loopCounter = loopCounter + 1
        else:
            emailReceived = True

    assert emailReceived
Вернуться на верх