Repository: pyqtgraph/pyqtgraph

Issue:
[CI-fail] HDF5 big data
This test fails due to h5py missing. Probably we can change requisites to include h5py or skip this test if h5py is not found.
```
examples/test_examples.py::test_examples[PyQt4-f17] frontend = PyQt4. f = ('HDF5 big data', 'hdf5.py')
HDF5 big data.....................................FAILED
Python 2.7.16 |Anaconda, Inc.| (default, Mar 14 2019, 21:00:58) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> >>> ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
  File "hdf5.py", line 19, in <module>
    import h5py
ImportError: No module named h5py
>>> 
```


Discussion:
Let's skip it! It's really just an instructive example and doesn't touch on any unique features of the library as far as I know. It's also a really expensive test to run.
I just took a look at this, skipping this may be a bit tricky as this example (`hdf5.py`) is not dependent on pytest, but the function that grabs all the examples and runs them is.

So we can either write some code that checks for the presence of `h5py` and if it's not present, it skips `hdf5.py`, or we remove that file altogether.

Given that pyqtgraph supports this, I wouldn't suggest removing it, but the code in `test_examples.py` will get a bit more complicated.
Somewhat ugly idea: how about an `exclude` keyword argument for `utils.buildFileList` that takes a list of strings so if an example name/filename is found in the list, it's excluded from the returned file list? Then you can tack on `exclude=['hdf5.py']` in CI context. Kind of fragile and, like I said, ugly :man_shrugging: 
I was thinking we would have a dictionary; where the keys would be file names (`hdf5.py`), and the values would be a list of any non-standard dependencies required for that file.  When we get to a file has a dictionary key, we would check for the presence of those extra libraries, and skip it if we get an import error.

We could also just wrap the entire function call inside a try/except ImportError 🤷‍♂ 
This PR is exactly what @j9ac9k suggested.
Speaking of @j9ac9k's suggestions: I really like the latter (@Dschoni's?) one and only noticed it now. I will quickly give it 10 minutes.
There it is. I prefer the latter solution, as it has basically nothing to maintain, but it should be pointed out that in that solution no clean "Requirement ... is missing" is printed, but instead the (less clean looking) ImportError from Python.
https://docs.pytest.org/en/latest/reference.html#pytest-importorskip

This may be useful, though the constructions of these tests means it is less useful perhaps.
@ksunden that's what I first thought of using but presently all examples are treated as one test from what it looks like, so if this check fails, all examples are skipped.... That said there may be a way to implement that still.
@j9ac9k Currently, all examples are treated as different tests (that's what `@pytest.mark.parametrize` does in https://github.com/pyqtgraph/pyqtgraph/blob/develop/examples/test_examples.py#L55 ), they only always report success (the reason for pull request #890 ). An exemplary log to show this would be the one of #891, which now implements the idea of @ksunden: https://travis-ci.com/2xB/pyqtgraph/jobs/203397638 (skip of the h5py example can be seen in line 987).
Still, your remark holds: Using `pytest.importskip` for this currently requires importing `pytest` in `utils.py`, as long as `utils.py` contains some testing code.
I'm not that versed in pytest so I'm likely the last person to know of a clever pytest method we can use better.

Resolving patch:
diff --git a/examples/utils.py b/examples/utils.py
--- a/examples/utils.py
+++ b/examples/utils.py
@@ -4,6 +4,7 @@
 import os
 import sys
 import errno
+import copy
 from pyqtgraph.pgcollections import OrderedDict
 from pyqtgraph.python2_3 import basestring
 
@@ -91,6 +92,11 @@
     ('Custom Flowchart Nodes', 'FlowchartCustomNode.py'),
 ])
 
+not_tested = ['HDF5 big data']
+
+tested_examples = copy.deepcopy(examples)
+all(map(tested_examples.pop, not_tested))
+
 
 def buildFileList(examples, files=None):
     if files == None:


Test patch:
diff --git a/examples/test_examples.py b/examples/test_examples.py
--- a/examples/test_examples.py
+++ b/examples/test_examples.py
@@ -41,7 +41,7 @@ def flaky_print(*args):
           "pypi\n\npip install importlib\n\n")
     pass
 
-files = utils.buildFileList(utils.examples)
+files = utils.buildFileList(utils.tested_examples)
 frontends = {Qt.PYQT4: False, Qt.PYQT5: False, Qt.PYSIDE: False, Qt.PYSIDE2: False}
 # sort out which of the front ends are available
 for frontend in frontends.keys():