Selenium登录测试不接受pytest固定装置登录或拒绝连接 [英] Selenium login test doesn't accept pytest fixtures for login or refuses to connect
问题描述
我感到绝望,因为我似乎无法找到我认为所有人都可以使用的解决方案.
I'm getting desperate because I can't seem to find a solution for what I thought would be used by everyone out there.
我想使用selenium和livetest服务器url测试pytest的简单登录.根据pytest-django文档,一个名为 live_server
的简单灯具应该可以解决问题(
I want to test a simple login with selenium and pytest with a live_server url. According to pytest-django doc, a simple fixture called live_server
should do the trick (https://pytest-django.readthedocs.io/en/latest/helpers.html#live-server).
不幸的是,当我通过此固定装置进行测试并尝试访问它的网站时,我得到了:
Unfortunately when I pass this fixture to my test and try to visit my website with it I get:
本地主机拒绝连接
localhost refused to connect
例如:
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查看器中看到我的网站.
Leveraging this question Selenium unable to login to Django LiveServerTestCase I am trying to use a different server-fixture which then connects me and I can see my website in my VNC viewer.
@pytest.fixture
def test_server() -> LiveServer:
addr = socket.gethostbyname(socket.gethostname())
server = LiveServer(addr)
yield server
server.stop()
但是,如果我使用夹具在数据库中创建用户,则现在无法登录到我的网站.即使看起来实际上是在创建用户.所以我的测试现在看起来像:
But with this I am now not able to login to my website if I create users in the db with my fixtures. Even though it seems like users are actually created. So my test now looks like:
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%确信我使用的是正确的凭据.
The tests visits my login page and fails to log in. I am 100% certain that I am using the right credentials.
如果我打印出来进行调试,我还可以验证我的用户是否在数据库中:
If I print out for debugging I also can verify that my user is in my db:
print(u.username) ==> testuserstaff
print(u.password) ==> igetthehashofthepassword
print(User.objects.count()) ==> 1
因此,我假设pytest创建的数据库已填充了我作为fixture传递的该用户.现在,以某种方式,我的实时服务器要么不使用数据库,要么不识别固定装置.
Thus I assume the db that is being created by pytest is filled with this user I pass as fixture. Now somehow my live server is either not using the db or not recognising the fixtures.
它必须连接到live_server/test_server装置.我将不胜感激.我觉得我已经很近了,但是我似乎无法找出为什么它没有登录.
It must be connected to the live_server/test_server fixture. I would be supergrateful for any help. I feel like I am so close but I just can't seem to find out why it doesn't log in.
我还尝试了什么:1)使用我的开发数据库中的用户登录.没有成功所以我想知道:那么使用什么数据库?
What else have I tried: 1) Login in with users that are in my development db. No success. So I am wondering: What db is then be used?
2)我尝试设置pytest-selenium库.如果我尝试加载页面,则会出现 selenium.common.exceptions.SessionNotCreatedException:消息:无法创建会话
2) I tried to setup pytest-selenium library. If I try to load a page I get selenium.common.exceptions.SessionNotCreatedException: Message: Unable to create session
3)我尝试使用StaticLiveServerCase,但这不是一个选择,因为我需要传递夹具作为参数.
3) I tried to work with StaticLiveServerCase, but this is not an option since I need to pass fixtures as an argument.
4)我搜索了网络上的所有地方,但找不到其他东西
4) I searched everywhere on the web and cannot find anything else
也很高兴知道:
我正在docker环境中运行它(如果有帮助,很乐意分享)
I am running this in a docker environment (happy to share if it helps)
所以我的堆栈基本上是:Docker,Django,Pytest,硒
So my stack is basically: Docker, Django, Pytest, selenium
再次,非常感谢您的帮助.提前非常感谢
Again, would really appreciate a hand here. Thanks so much in advance
我的docker-compose文件:
My docker-compose file:
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
不写入数据库.为了确保数据库提交,请在测试中使用 @ pytest.mark.django_db(transaction = True)
标记,或者在您的装置中使用 transactional_db
装置:
Turning the comment into an answer: by default, the tests avoid running db queries to not to slow down the test run, so User.objects.create_user
doesn't write to database. To ensure db commits, use the @pytest.mark.django_db(transaction=True)
marker in tests or the transactional_db
fixture in your fixtures:
@pytest.fixture()
def create_staff_user_in_db(transactional_db):
staff_user = User.objects.create_user(...)
...
我假设django的
live_server
固定装置自动使用transactional_db
,但是test_server
不使用吗?
I assume that the
live_server
fixture of django usestransactional_db
automatically but that thetest_server
doesn't?
完全是- live_server
暗含了事务处理模式,但 test_server
的自定义隐含则没有.在 test_server
中明确请求 transactional_db
固定装置应该对其进行修复:
Exactly - live_server
implies the transactional mode, but the custom impl of test_server
doesn't. Explicitly requesting the transactional_db
fixture in test_server
should fix it:
@pytest.fixture
def test_server(request) -> LiveServer:
request.getfixturevalue("transactional_db")
...
顺便说一句,如果您只是想动态地应用实时服务器地址,则无需定义自己的灯具;编写配置值就足够了.示例:
BTW if you just want to apply the live server address dynamically, you shouldn't need to define your own fixture; writing config values should suffice. Example:
# conftest.py
def pytest_configure(config):
config.option.liveserver = socket.gethostbyname(socket.gethostname())
然后,内置的 live_server
固定装置将使用此值.将 conftest.py
放入您的项目或测试根目录,以使 pytest
尽早找到hookimpl以便应用.
This value will then be used by the builtin live_server
fixture. Put the conftest.py
into your project or tests root dir to make pytest
find the hookimpl early enough for it to be applied.
这篇关于Selenium登录测试不接受pytest固定装置登录或拒绝连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!