.gitlab-ci.yml 管道中的 Plotly-Dash 测试因 NameError 失败:未定义名称“DashComposite”

Posted

技术标签:

【中文标题】.gitlab-ci.yml 管道中的 Plotly-Dash 测试因 NameError 失败:未定义名称“DashComposite”【英文标题】:Plotly-Dash Testing in .gitlab-ci.yml pipeline fails with NameError: name 'DashComposite' is not defined 【发布时间】:2021-11-14 05:41:33 【问题描述】:

我在为我创建的 plotly-dash 应用程序运行集成测试时遇到问题。我正在尝试使用 pytest 和 Dash 测试 (https://dash.plotly.com/testing) 使用 selenium 远程运行集成测试

我能够使用 selenium chrome webdriver 在本地(Windows 10)运行实现测试。

但是,它不能远程工作。 gitlab-ci 管道失败,报错如下:

============================= test session starts ==============================
platform linux -- Python 3.8.0, pytest-6.2.5, py-1.10.0, pluggy-1.0.0
rootdir: /builds/jwinter/dash_testing_in_gitlab_ci
plugins: dash-2.0.0
collected 1 item
test_app.py E                                                            [100%]
==================================== ERRORS ====================================
________________________ ERROR at setup of test_example ________________________
request = <SubRequest 'dash_duo' for <Function test_example>>
dash_thread_server = <dash.testing.application_runners.ThreadedRunner object at 0x7f12b8d2a130>
tmpdir = local('/tmp/pytest-of-root/pytest-0/test_example0')
    @pytest.fixture
    def dash_duo(request, dash_thread_server, tmpdir):
>       with DashComposite(
            dash_thread_server,
            browser=request.config.getoption("webdriver"),
            remote=request.config.getoption("remote"),
            remote_url=request.config.getoption("remote_url"),
            headless=request.config.getoption("headless"),
            options=request.config.hook.pytest_setup_options(),
            download_path=tmpdir.mkdir("download").strpath,
            percy_assets_root=request.config.getoption("percy_assets"),
            percy_finalize=request.config.getoption("nopercyfinalize"),
            pause=request.config.getoption("pause"),
        ) as dc:
E       NameError: name 'DashComposite' is not defined
/usr/local/lib/python3.8/site-packages/dash/testing/plugin.py:141: NameError
=========================== short test summary info ============================
ERROR test_app.py::test_example - NameError: name 'DashComposite' is not defined
=============================== 1 error in 0.09s ===============================

我基于https://dash.plotly.com/layout 上的示例应用创建了一个最小示例。 它失败并显示给定的错误消息。

app.py 基于https://dash.plotly.com/layout示例

from dash import dcc, html
import dash
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

df = pd.DataFrame(
   "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
   "Amount": [4, 1, 2, 2, 4, 5],
   "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
)

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
   html.H1(children='Hello Dash'),

   html.Div(children='''
       Dash: A web application framework for your data.
   '''),

   dcc.Graph(
       id='example-graph',
       figure=fig
   )
])

if __name__ == '__main__':
   app.run_server(debug=True)

gitlab-ci.yml

stages:
  - test
test:dashboard:
  stage: test
  image: python:3.8.0
  services:
    - selenium/standalone-chrome :latest
  before_script:
    - pip install -r requirements_for_testing.txt
    - pip install pytest
  script: |
    export PYTHONPATH=$PYTHONPATH:$PWD
    pytest

conftest.py

from selenium.webdriver.chrome.options import Options

def pytest_setup_options():
    options = Options()
    options.add_argument('--headless')
    return options

test_app.py


from dash.testing.application_runners import import_app
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions


def test_example(dash_duo):
    app = import_app(
        app_file='app')
    dash_duo.start_server(app)
    WebDriverWait(dash_duo.driver, 10).until(
        expected_conditions.visibility_of_element_located(
            (By.CSS_SELECTOR, "#example-graph")))
    assert dash_duo.driver.find_element_by_css_selector(
        "#example-graph").is_displayed()

requirements_for_testing.txt

dash >= 2.0.0
dash[testing]
pytest
selenium
pandas
plotly
requests

我尝试了什么

我尝试包含我在Running plotly dash selenium tests in gitlab CI 中找到的 selenium/standalone-chrome 但不管我加了没有

services:
 - selenium/standalone-chrome : latest

services:
 - selenium__standalone-chrome : latest

或完全删除 gitlab-ci.yml 中的服务部分, 没有任何改变。

非常感谢您考虑我的问题。我无法找到有关此 DashComposite 错误的任何内容。

【问题讨论】:

【参考方案1】:

我遇到了同样的问题,我想我找到了原因。 DashComposite(以及一般 Dash 应用程序的测试)将需要安装 dash[testing]。也就是说,dash 包和 testing 附加功能。

我看到您的requirements_for_testing.txt 中列出了dash[testing],您在gitlab-ci.yml 中使用了它。现在看来,pip20.2.1 和其他人)中存在一个 错误,例如 here,这使得 pip not 安装 somepackage[extras] if你已经安装了somepackage

解决 pip 的问题

要解决 pip 的问题,您需要使用 --use-feature 2020-resolver 选项。在你的情况下,而不是

pip install -r requirements_for_testing.txt

你会使用

pip install -r requirements_for_testing.txt --use-feature 2020-resolver

gitlab-ci.yml

另一种选择是使用较新的 pip 版本,默认使用 2020 解析器。从here 和here 来看,似乎从pip 20.3 开始,新的依赖解析器是默认的。要将 pip 更新到最新版本,您可以运行

python -m pip install --upgrade pip

【讨论】:

以上是关于.gitlab-ci.yml 管道中的 Plotly-Dash 测试因 NameError 失败:未定义名称“DashComposite”的主要内容,如果未能解决你的问题,请参考以下文章

.gitlab-ci.yml配置参数

gitlab yaml管道内的while循环

gitlab-ci.yml 仅在 master 分支上

获取使用 .gitlab-ci.yml 运行的 Windows Docker 容器

从 Jenkins Ci 服务迁移到 gitlab-ci.yml

如何创建一个工件,以便它可以在 .gitlab-ci.yml 中下载