python - Selenium 登录测试不接受 pytest 固定装置进行登录或拒绝连接
问题描述
我越来越绝望,因为我似乎无法为我认为所有人都会使用的东西找到解决方案。
我想用 selenium 和 pytest 用 live_server url 测试一个简单的登录。根据 pytest-django doc,一个名为的简单夹具live_server
应该可以解决问题(https://pytest-django.readthedocs.io/en/latest/helpers.html#live-server)。
不幸的是,当我将此夹具传递给我的测试并尝试使用它访问我的网站时,我得到:
本地主机拒绝连接
例如:
def test_selenium(self, live_server, create_staff_user_in_db):
browser = webdriver.Remote(
command_executor='http://selenium:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME,
)
browser.get(live_server.url)
利用这个问题Selenium 无法登录到 Django LiveServerTestCase我正在尝试使用不同的服务器装置,然后连接我,我可以在我的 VNC 查看器中看到我的网站。
@pytest.fixture
def test_server() -> LiveServer:
addr = socket.gethostbyname(socket.gethostname())
server = LiveServer(addr)
yield server
server.stop()
但是有了这个,如果我用我的装置在数据库中创建用户,我现在无法登录到我的网站。尽管看起来用户实际上是被创建的。所以我的测试现在看起来像:
def test_selenium(self, test_server, create_staff_user_in_db):
browser = webdriver.Remote(
command_executor='http://selenium:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME,
)
browser.get(f"{live_server.url}/login")
input_username = browser.find_element_by_name('username')
input_password = browser.find_element_by_name('password')
input_username.send_keys('testuserstaff')
input_password.send_keys('mypasswordstaff')
browser.find_element_by_xpath(
'//*[@id="page-top"]/div[1]/div/div/div/div/form/button'
).click()
我的用户装置是:
@pytest.fixture()
def create_staff_user_in_db():
User = get_user_model()
staff_user = User.objects.create_user(
username="testuserstaff",
password="mypasswordstaff",
)
staff_user.is_staff = True
staff_user.save()
return staff_user
测试访问我的登录页面但无法登录。我 100% 确定我使用了正确的凭据。
如果我打印出来进行调试,我还可以验证我的用户是否在我的数据库中:
print(u.username) ==> testuserstaff
print(u.password) ==> igetthehashofthepassword
print(User.objects.count()) ==> 1
因此,我假设由 pytest 创建的数据库填充了我作为夹具传递的这个用户。现在不知何故,我的实时服务器要么不使用数据库,要么不识别灯具。
它必须连接到 live_server/test_server 固定装置。如果有任何帮助,我将不胜感激。我觉得我很接近,但我似乎无法找出它为什么不登录。
我还尝试了什么:1)使用我的开发数据库中的用户登录。没有成功。所以我想知道:然后使用什么数据库?
2)我尝试设置 pytest-selenium 库。如果我尝试加载一个页面,我会得到selenium.common.exceptions.SessionNotCreatedException: Message: Unable to create session
3) 我尝试使用 StaticLiveServerCase,但这不是一个选项,因为我需要将固定装置作为参数传递。
4)我在网上到处搜索,找不到其他任何东西
也很高兴知道:
我在 docker 环境中运行它(如果有帮助,很高兴分享)
所以我的堆栈基本上是:Docker、Django、Pytest、selenium
再次,真的很感激在这里。非常感谢提前
编辑:
我的码头工人撰写文件:
version: '3'
volumes:
local_postgres_data: {}
local_postgres_data_backups: {}
services:
django:
build:
context: .
dockerfile: ./compose/local/django/Dockerfile
image: mywebsite_local_django
depends_on:
- postgres
volumes:
- .:/app
env_file:
- ./.envs/.local/.django
- ./.envs/.local/.postgres
ports:
- "8000:8000"
command: /start
selenium:
image: selenium/standalone-chrome-debug
ports:
- 4444:4444
- 5900:5900
postgres:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
image: mywebsite_production_postgres
volumes:
- local_postgres_data:/var/lib/postgresql/data
- local_postgres_data_backups:/backups
env_file:
- ./.envs/.local/.postgres
解决方案
将评论变成答案:默认情况下,测试避免运行 db 查询以不减慢测试运行速度,因此User.objects.create_user
不写入数据库。为了确保 db 提交,请@pytest.mark.django_db(transaction=True)
在测试中使用标记或transactional_db
在您的固定装置中使用固定装置:
@pytest.fixture()
def create_staff_user_in_db(transactional_db):
staff_user = User.objects.create_user(...)
...
我假设
live_server
django 的夹具会transactional_db
自动使用,但test_server
不是吗?
完全正确 -live_server
暗示事务模式,但自定义 impltest_server
没有。明确请求transactional_db
固定装置test_server
应该修复它:
@pytest.fixture
def test_server(request) -> LiveServer:
request.getfixturevalue("transactional_db")
...
顺便说一句,如果您只想动态应用实时服务器地址,则不需要定义自己的夹具;编写配置值就足够了。例子:
# conftest.py
def pytest_configure(config):
config.option.liveserver = socket.gethostbyname(socket.gethostname())
然后,该值将由内置live_server
夹具使用。将其conftest.py
放入您的项目或测试根目录,以便pytest
尽早找到 hookimpl 以便应用它。
推荐阅读
- python - 将列表与 JSON 进行比较并计算出现次数
- android - 如何在 Kotlin 库中使用协程
- python - 在 Pandas DataFrame 中解析 JSON
- python - 我如何将循环打印值存储在变量或列表中
- swift - Swift 谷歌地图标记信息窗口中心到地图视图
- git - url https://raw.githubusercontent.com/path-to-my-file 是 github 中公共存储库的永久链接吗?
- java - Intellij 对 de-lombok 源使用错误的行号
- azure-devops - Azure DevOps YAML 阶段模板
- java - 使用 Java Stream 获取串联的 Enum long 值的字符串
- python - 使用 GEKKO 求解约束 x(0) + x(2) =0 的最优控制问题