简体   繁体   English

如何使用 Github 操作让 Selenium 测试在 python 中运行?

[英]How can I get Selenium tests to run in python with Github actions?

I'm having trouble getting my python Selenium running in github actions.我无法让我的 python Selenium 在 github 操作中运行。

I have been using Circle CI for the past year, but recently began migrating over to github actions.过去一年我一直在使用 Circle CI,但最近开始迁移到 github 操作。

For Circle CI to run selenium in a chrome browser, I had the following lines in my config.yml:为了让 Circle CI 在 chrome 浏览器中运行 selenium,我的 config.yml 中有以下几行:

docker:
    # includes chrome browser for selenium testing
  - image: circleci/python:3.7.4-browsers

and there didn't seem to be a need to install a chromedriver.而且似乎不需要安装chromedriver。

I am using the following in my githubs action.yml file:我在我的 githubs action.yml 文件中使用以下内容:

jobs:
  build:
    runs-on: ubuntu-latest
    services:
      selenium:
        image: selenium/standalone-chrome
    steps:
    - uses: actions/checkout@v1
    - name: Set up Python 3.7
      uses: actions/setup-python@v1
      with:
        python-version: 3.7
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pipenv
        pipenv install
    - name: Prepare Selenium
      # https://github.com/marketplace/actions/setup-chromedriver
      uses: nanasess/setup-chromedriver@master
    - name: Launch browser
      run: |
        google-chrome --version
        export DISPLAY=:99
        chromedriver --url-base=/wd/hub &
        sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional, disables headless mode
    - name: Run tests
      run: pipenv run python manage.py test functional_tests.tests.test_selenium.test_exams -v 2

But I get the following error when in my python code I try to run:但是当我尝试运行 python 代码时出现以下错误:

from selenium import webdriver
driver = webdriver.Chrome()
  File "/home/runner/.local/share/virtualenvs/lang-EMCZ4oUT/lib/python3.7/site-packages/selenium/webdriver/chrome/webdriver.py", line 81, in __init__
    desired_capabilities=desired_capabilities)
  File "/home/runner/.local/share/virtualenvs/lang-EMCZ4oUT/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 157, in __init__
    self.start_session(capabilities, browser_profile)
  File "/home/runner/.local/share/virtualenvs/lang-EMCZ4oUT/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 252, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/home/runner/.local/share/virtualenvs/lang-EMCZ4oUT/lib/python3.7/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "/home/runner/.local/share/virtualenvs/lang-EMCZ4oUT/lib/python3.7/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally.
  (unknown error: DevToolsActivePort file doesn't exist)
  (The process started from chrome location /usr/bin/google-chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)

From what I can read online, I should need just the uses: nanasess/setup-chromedriver@master and shouldn't need image: selenium/standalone-chrome , but switching either in or out doesn't make any difference, the python tests still cannot find chrome browser.从我可以在线阅读的内容来看,我应该只需要uses: nanasess/setup-chromedriver@master并且不需要image: selenium/standalone-chrome ,但是切换进或出没有任何区别,python 测试还是找不到chrome浏览器。

Am I supposed to set up a port to listen to?我应该设置一个端口来监听吗?

I'm going to answer your question first and then I'm going to offer an alternative approach.我将首先回答您的问题,然后我将提供另一种方法。 I'm going to use a unified diff format to highlight the changes I would make to your workflow.我将使用统一的差异格式来突出我将对您的工作流程所做的更改。 If you're not familiar with the format, ignore the first three lines, and then imagine that I'm deleting the lines starting with “ - ” from your workflow and adding the lines starting with “ + ”.如果您不熟悉格式,请忽略前三行,然后想象我正在从您的工作流程中删除以“ - ”开头的行并添加以“ + ”开头的行。 Lines starting with “以“开头的行 ” are left as-is. ”保持原样。

When you posted your question, the action nanasess/setup-chromedriver downloaded Chrome Browser along with chromedriver (that was v1.0.1).当您发布问题时,操作nanasess/setup-chromedriver下载了 Chrome 浏览器以及 chromedriver(即 v1.0.1)。 As of this writing, it still does the same (v1.0.5).在撰写本文时,它仍然执行相同的操作 (v1.0.5)。 Because of this, you don't need an extra service container to run Chrome Browser and chromedriver – they are already in your primary container.因此,您不需要额外的服务容器来运行 Chrome 浏览器和 chromedriver——它们已经在您的主容器中。

--- original.yml    2020-06-13 20:42:25 +0000
+++ step1.yml   2021-04-23 00:01:00 +0000
@@ -1,9 +1,6 @@
 jobs:
   build:
     runs-on: ubuntu-latest
-    services:
-      selenium:
-        image: selenium/standalone-chrome
     steps:
     - uses: actions/checkout@v1
     - name: Set up Python 3.7

You also don't need your “Launch browser” step.您也不需要“启动浏览器”步骤。 Selenium library will do it for you. Selenium 库将为您完成。 It executes local chromedriver binary by default, which in turn executes Chrome Browser binary by default.它默认执行本地 chromedriver 二进制文件,而后者又默认执行 Chrome 浏览器二进制文件。 If you don't want to use headless mode, you still have to start the virtual framebuffer (but nothing else):如果您不想使用无头模式,您仍然必须启动虚拟帧缓冲区(但没有别的):

--- step1.yml   2021-04-23 00:01:00 +0000
+++ step2.yml   2021-04-23 00:02:00 +0000
@@ -15,11 +15,10 @@
     - name: Prepare Selenium
       # https://github.com/marketplace/actions/setup-chromedriver
       uses: nanasess/setup-chromedriver@master
-    - name: Launch browser
+    - name: Start XVFB
       run: |
-        google-chrome --version
-        export DISPLAY=:99
-        chromedriver --url-base=/wd/hub &
         sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional, disables headless mode
     - name: Run tests
       run: pipenv run python manage.py test functional_tests.tests.test_selenium.test_exams -v 2
+      env:
+        DISPLAY: :99

And this should do the trick.这应该可以解决问题。 Notice addition of env with the same DISPLAY port as was passed when starting XVFB.注意添加了与启动 XVFB 时传递的具有相同DISPLAY端口的env

My guess is that the error you shared here occurs due to conflict between chromedriver and Google Chrome you've started and the ones your test suite is trying to start and control.我的猜测是,您在此处共享的错误是由于您已启动的 chromedriver 和 Google Chrome 与您的测试套件试图启动和控制的那些之间的冲突而发生的。

What is my alternative approach?我的替代方法是什么? I'm personally a bit cautious when introducing third-party dependencies.在引入第三方依赖时,我个人还是比较谨慎的。 Especially for things which should be just about couple lines of code.特别是对于应该只是几行代码的事情。 And when looking for inspiration, I try to look as close to the source as possible.而在寻找灵感时,我会尽量靠近源头。 So, how is Selenium testing their code?那么,Selenium 是如何测试他们的代码的呢?

Interestingly, Selenium project is using GitHub Actions to test the libraries themselves and they have quite extensive integration test suite which requires running browsers.有趣的是,Selenium 项目正在使用 GitHub 操作来测试库本身,并且它们具有相当广泛的集成测试套件,需要运行浏览器。 They don't use third-party action to setup the browser environment.他们不使用第三方操作来设置浏览器环境。 Their tests are pretty complex, but you can take a hint, take individuals actions and steps, and apply them based on your needs.他们的测试非常复杂,但您可以采取提示,采取个人行动和步骤,并根据您的需要应用它们。

The important part is the action to setup Chrome and chromedriver .重要的部分是设置 Chrome 和 chromedriver 的操作 Straightforward and pretty much the same compared to the action from Kentaro Ohkouchi (aka nanasess) which you're using.与您正在使用的大口健太郎(又名 nanases)的动作相比,直截了当且几乎相同。

The next important part is starting the virtual framebuffer.下一个重要部分是启动虚拟帧缓冲区。 Again, you don't need it if you are using headless mode.同样,如果您使用无头模式,则不需要它。 They are starting it very simply compared to you or Ohkouchi's example:与您或 Ohkouchi 的示例相比,他们开始非常简单:

--- step2.yml   2021-04-23 00:02:00 +0000
+++ step3.yml   2021-04-23 00:03:00 +0000
@@ -18,3 +18,3 @@
     - name: Start XVFB
       run: |
-        sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 & # optional, disables headless mode
+        Xvfb :99 &

No sudo , no extra arguments, just the DISPLAY port.没有sudo ,没有额外的 arguments,只有DISPLAY端口。

PS: When using a third-party action, use tags. PS:使用第三方动作时,使用标签。 You never know what kind of change squeezes into someone else's code.你永远不知道什么样的变化会挤进别人的代码中。 Rather let the test fail during CI, investigate what changed and then bump the version, than blindly trust that someone is always going to make the right change for you…与其在 CI 期间让测试失败,调查发生了什么变化,然后修改版本,而不是盲目相信总有人会为你做出正确的改变……

--- step3.yml   2021-04-23 00:03:00 +0000
+++ step4.yml   2021-04-23 00:04:00 +0000
@@ -15,3 +15,3 @@
     - name: Prepare Selenium
       # https://github.com/marketplace/actions/setup-chromedriver
-      uses: nanasess/setup-chromedriver@master
+      uses: nanasess/setup-chromedriver@v1.0.5

Use headless Chromedriver使用无头 Chromedriver

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

chrome_options = Options()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(options=chrome_options)

If you need Chrome with GUI - you can use macos or windows instead of ubuntu如果您需要带有 GUI 的 Chrome - 您可以使用macoswindows而不是 ubuntu

MacOS苹果系统

jobs:
  build:
    runs-on: macos-latest
    ...

Windows Windows

jobs:
  build:
    runs-on: windows-latest
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM