1

I had a problem running an integration test for a plotly-dash app I created. I am trying to run an integration test with selenium remote using pytest and Dash Testing (https://dash.plotly.com/testing)

I was able to run an implementation test locally (Windows 10) using the selenium chrome webdriver.

However, it does not work remotely. The gitlab-ci pipeline fails, giving the following error message:

============================= 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 ===============================

I created a minimum example based on the example app on https://dash.plotly.com/layout. It fails with the given error message.

app.py Based on https://dash.plotly.com/layout example

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

What I tried

I tried to include selenium/standalone-chrome as I found it in Running plotly dash selenium tests in gitlab CI But no matter if I added

services:
 - selenium/standalone-chrome : latest

or

services:
 - selenium__standalone-chrome : latest

or deleted the services section in gitlab-ci.yml completely, nothing changed.

Thank you so much for considering my question. I was not able to find anything on this DashComposite error.

juliausp
  • 11
  • 1

1 Answers1

0

I faced the same issue, and I think I found the reason. The DashComposite (and testing of Dash apps in general) will require the dash[testing] to be installed. That is, the dash package with the testing extras.

I see that you have the dash[testing] listed in your requirements_for_testing.txt, which you use in your gitlab-ci.yml. Now it appears that there is a bug in pip (20.2.1 and others) discussed for example here which makes pip not install somepackage[extras] if you have already somepackage installed.

Fixing problems with pip

To fix the problems with pip, you want to use the --use-feature 2020-resolver option. In your case, instead of

pip install -r requirements_for_testing.txt

you would use

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

in the gitlab-ci.yml.

Another option is to use newer pip version, that has the 2020 resolver as default. Looking from here and here it seems that from pip 20.3 onwards the new dependency resolver is the default. To update pip to the newest version, you would run

python -m pip install --upgrade pip
Niko Föhr
  • 28,336
  • 10
  • 93
  • 96