Repository: Pyomo/pyomo

Issue:
`Pyomo.contrib.viewer.tests.test_qt` fails on GHA but passes locally
## Summary

In porting from `nosetests` to `pytest`, the `pyomo/contrib/viewer/tests/test_qt.py` file needed updating. It has now be updated, and the tests all pass swimmingly when run locally, but it fails when run on GHA. Rather than spending valuable time trying to fix this before the next release, I am going to simply skip these tests and try to troubleshoot afterwards.

### Steps to reproduce the issue

See here: https://github.com/mrmundt/pyomo/runs/5203838321?check_suite_focus=true 


### Error Message

None. Which is endlessly frustrating.

### Information on your system

Pyomo version: Pyomo 6.2.1 (devel {pytest-refactor})
Python version: 3.7.11
Operating system: Linux
How Pyomo was installed (PyPI, conda, source): source
Solver (if applicable):


### Additional information

<!-- If you have any additional information, please list it here. -->


<!-- We encourage you to try, as much as possible, to reduce your problem to the minimal example that still reproduces the issue. That would help us a lot in fixing it quickly and effectively!

If you want to ask a question (how to use Pyomo, what it can do, etc.), please refer to our [online documentation](https://github.com/Pyomo/pyomo#getting-help) on ways to get help. -->




Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -243,14 +243,10 @@ def __ne__(self, other):
     python_requires='>=3.8',
     install_requires=['ply'],
     extras_require={
-        'tests': [
-            #'codecov', # useful for testing infrastructures, but not required
-            'coverage',
-            'pytest',
-            'pytest-parallel',
-            'parameterized',
-            'pybind11',
-        ],
+        # There are certain tests that also require pytest-qt, but because those
+        # tests are so environment/machine specific, we are leaving these out of
+        # the dependencies.
+        'tests': ['coverage', 'parameterized', 'pybind11', 'pytest', 'pytest-parallel'],
         'docs': [
             'Sphinx>4',
             'sphinx-copybutton',
@@ -268,7 +264,7 @@ def __ne__(self, other):
             'matplotlib!=3.6.1',
             # network, incidence_analysis, community_detection
             # Note: networkx 3.2 is Python>-3.9, but there is a broken
-            # 3.2 package on conda-forgethat will get implicitly
+            # 3.2 package on conda-forge that will get implicitly
             # installed on python 3.8
             'networkx<3.2; python_version<"3.9"',
             'networkx; python_version>="3.9"',
@@ -279,6 +275,9 @@ def __ne__(self, other):
             'plotly',  # incidence_analysis
             'python-louvain',  # community_detection
             'pyyaml',  # core
+            # qtconsole also requires a supported Qt version (PyQt5 or PySide6).
+            # Because those are environment specific, we have left that out here.
+            'qtconsole',  # contrib.viewer
             'scipy',
             'sympy',  # differentiation
             'xlrd',  # dataportals
@@ -291,9 +290,7 @@ def __ne__(self, other):
             # The following optional dependencies are difficult to
             # install on PyPy (binary wheels are not available), so we
             # will only "require" them on other (CPython) platforms:
-            #
-            # DAE can use casadi
-            'casadi; implementation_name!="pypy"',
+            'casadi; implementation_name!="pypy"',  # dae
             'numdifftools; implementation_name!="pypy"',  # pynumero
             'pandas; implementation_name!="pypy"',
             'seaborn; implementation_name!="pypy"',  # parmest.graphics


Test patch:
diff --git a/.github/workflows/test_branches.yml b/.github/workflows/test_branches.yml
--- a/.github/workflows/test_branches.yml
+++ b/.github/workflows/test_branches.yml
@@ -75,7 +75,7 @@ jobs:
           python: 3.9
           TARGET: win
           PYENV: conda
-          PACKAGES: glpk
+          PACKAGES: glpk pytest-qt
 
         - os: ubuntu-latest
           python: '3.11'
@@ -83,7 +83,7 @@ jobs:
           skip_doctest: 1
           TARGET: linux
           PYENV: conda
-          PACKAGES:
+          PACKAGES: pytest-qt
 
         - os: ubuntu-latest
           python: 3.9
@@ -213,6 +213,15 @@ jobs:
         auto-update-conda: false
         python-version: ${{ matrix.python }}
 
+    # This is necessary for qt (UI) tests; the package utilized here does not
+    # have support for OSX.
+    - name: Set up UI testing infrastructure
+      if: ${{ matrix.TARGET != 'osx' }}
+      uses: pyvista/setup-headless-display-action@v2
+      with:
+        qt: true
+        pyvista: false
+
     # GitHub actions is very fragile when it comes to setting up various
     # Python interpreters, expecially the setup-miniconda interface.
     # Per the setup-miniconda documentation, it is important to always
@@ -309,7 +318,7 @@ jobs:
         fi
         # HACK: Remove problem packages on conda+Linux
         if test "${{matrix.TARGET}}" == linux; then
-            EXCLUDE="casadi numdifftools pint $EXCLUDE"
+            EXCLUDE="casadi numdifftools $EXCLUDE"
         fi
         EXCLUDE=`echo "$EXCLUDE" | xargs`
         if test -n "$EXCLUDE"; then
@@ -346,10 +355,11 @@ jobs:
                     | sed -r 's/\s+/ /g' | cut -d\  -f3) || echo ""
                 if test -n "$_BUILDS"; then
                     _ISPY=$(echo "$_BUILDS" | grep "^py") \
-                        || echo "No python build detected"
-                    _PYOK=$(echo "$_BUILDS" | grep "^$PYVER") \
-                        || echo "No python build matching $PYVER detected"
+                        || echo "INFO: No python build detected."
+                    _PYOK=$(echo "$_BUILDS" | grep -E "^($PYVER|pyh)") \
+                        || echo "INFO: No python build matching $PYVER detected."
                     if test -z "$_ISPY" -o -n "$_PYOK"; then
+                        echo ""
                         echo "... INSTALLING $PKG"
                         conda install -y "$PKG" || _BUILDS=""
                     fi
@@ -358,18 +368,6 @@ jobs:
                     echo "WARNING: $PKG is not available"
                 fi
             done
-            # TODO: This is a hack to stop test_qt.py from running until we
-            # can better troubleshoot why it fails on GHA
-            for QTPACKAGE in qt pyqt; do
-                # Because conda is insane, removing packages can cause
-                # unrelated packages to be updated (breaking version
-                # specifications specified previously, e.g., in
-                # setup.py).  There doesn't appear to be a good
-                # workaround, so we will just force-remove (recognizing
-                # that it may break other conda cruft).
-                conda remove --force-remove $QTPACKAGE \
-                    || echo "$QTPACKAGE not in this environment"
-            done
         fi
         # Re-try Pyomo (optional) dependencies with pip
         if test -n "$PYPI_DEPENDENCIES"; then
diff --git a/.github/workflows/test_pr_and_main.yml b/.github/workflows/test_pr_and_main.yml
--- a/.github/workflows/test_pr_and_main.yml
+++ b/.github/workflows/test_pr_and_main.yml
@@ -76,7 +76,7 @@ jobs:
         - os: windows-latest
           TARGET: win
           PYENV: conda
-          PACKAGES: glpk
+          PACKAGES: glpk pytest-qt
 
         - os: ubuntu-latest
           python: '3.11'
@@ -84,7 +84,7 @@ jobs:
           skip_doctest: 1
           TARGET: linux
           PYENV: conda
-          PACKAGES:
+          PACKAGES: pytest-qt
 
         - os: ubuntu-latest
           python: 3.9
@@ -243,6 +243,15 @@ jobs:
         auto-update-conda: false
         python-version: ${{ matrix.python }}
 
+    # This is necessary for qt (UI) tests; the package utilized here does not
+    # have support for OSX.
+    - name: Set up UI testing infrastructure
+      if: ${{ matrix.TARGET != 'osx' }}
+      uses: pyvista/setup-headless-display-action@v2
+      with:
+        qt: true
+        pyvista: false
+
     # GitHub actions is very fragile when it comes to setting up various
     # Python interpreters, expecially the setup-miniconda interface.
     # Per the setup-miniconda documentation, it is important to always
@@ -339,7 +348,7 @@ jobs:
         fi
         # HACK: Remove problem packages on conda+Linux
         if test "${{matrix.TARGET}}" == linux; then
-            EXCLUDE="casadi numdifftools pint $EXCLUDE"
+            EXCLUDE="casadi numdifftools $EXCLUDE"
         fi
         EXCLUDE=`echo "$EXCLUDE" | xargs`
         if test -n "$EXCLUDE"; then
@@ -376,10 +385,11 @@ jobs:
                     | sed -r 's/\s+/ /g' | cut -d\  -f3) || echo ""
                 if test -n "$_BUILDS"; then
                     _ISPY=$(echo "$_BUILDS" | grep "^py") \
-                        || echo "No python build detected"
-                    _PYOK=$(echo "$_BUILDS" | grep "^$PYVER") \
-                        || echo "No python build matching $PYVER detected"
+                        || echo "INFO: No python build detected."
+                    _PYOK=$(echo "$_BUILDS" | grep -E "^($PYVER|pyh)") \
+                        || echo "INFO: No python build matching $PYVER detected."
                     if test -z "$_ISPY" -o -n "$_PYOK"; then
+                        echo ""
                         echo "... INSTALLING $PKG"
                         conda install -y "$PKG" || _BUILDS=""
                     fi
@@ -388,18 +398,6 @@ jobs:
                     echo "WARNING: $PKG is not available"
                 fi
             done
-            # TODO: This is a hack to stop test_qt.py from running until we
-            # can better troubleshoot why it fails on GHA
-            for QTPACKAGE in qt pyqt; do
-                # Because conda is insane, removing packages can cause
-                # unrelated packages to be updated (breaking version
-                # specifications specified previously, e.g., in
-                # setup.py).  There doesn't appear to be a good
-                # workaround, so we will just force-remove (recognizing
-                # that it may break other conda cruft).
-                conda remove --force-remove $QTPACKAGE \
-                    || echo "$QTPACKAGE not in this environment"
-            done
         fi
         # Re-try Pyomo (optional) dependencies with pip
         if test -n "$PYPI_DEPENDENCIES"; then