Skip to content

Commit

Permalink
Nose to pytest transition (#183)
Browse files Browse the repository at this point in the history
* Use mock from the standard lib if available.

* Migrate nose raises to pytest.raises.

This touches a lot of code because pytest.raises
is used in a context manager, so indentation
has to be changed.

Replacement happened with regex from
@raises\((.*)\) to @pytest.mark.xfail(raises=$1)
then from @pytest.mark.xfail\(raises=(.*)\)\ndef(.*)
to def$2\n    with pytest.raises($1):
then manual correction of indentation.

* Replace nose eq_ by assert, remove nottest.

* Move CI from nosetests to pytest, adapt docs.

Pin astroid version, too, to avoid wrong errors on CI.

* Fix some introduced errors flagged by pylint.

* Specify minimum pyserial requirement (see #58).
  • Loading branch information
bilderbuchi authored and scasagrande committed Mar 24, 2018
1 parent ffe0a45 commit bb4ab21
Show file tree
Hide file tree
Showing 40 changed files with 1,513 additions and 1,512 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pip-log.txt
.coverage
.tox
nosetests.xml
.pytest_cache

#Translations
*.mo
Expand Down
7 changes: 4 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@ install:
- "pip install -r dev-requirements.txt"
- pip install python-coveralls
- pip install coverage
- pip install pytest-cov
before_script:
# We use before_script to report version and path information in a way
# that can be easily hidden by Travis' log folding. Moreover, a nonzero
# exit code from this block kills the entire job, meaning that if we can't
# even sensibly get version information, we correctly abort.
- which python
- python --version
- which nosetests
- nosetests --version
- which pytest
- pytest --version
- which pylint
- pylint --version
script:
- nosetests --with-coverage -w instruments
- pytest --cov=instruments
- pylint --py3k instruments
- pylint --disable=I instruments
after_success:
Expand Down
3 changes: 2 additions & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mock
nose
pytest
hypothesis
pylint==1.7.1
astroid==1.5.3
4 changes: 2 additions & 2 deletions doc/source/devguide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ InstrumentKit Development Guide
code_style
testing
util_fns

Introduction
============

Expand All @@ -34,7 +34,7 @@ provided ``dev-requirements.txt``::
$ pip install -r dev-requirements.txt

- mock
- nose
- pytest
- pylint

Optional Development Dependencies
Expand Down
10 changes: 5 additions & 5 deletions doc/source/devguide/testing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ of InstrumentKit will not, in general, have access to each instrument that
is supported--- we rely on automated testing to ensure that future changes
do not cause invalid or undesired operation.

For InstrumentKit, we rely heavily on `nose`_, a mature and flexible
For InstrumentKit, we rely heavily on `pytest`_, a mature and flexible
unit-testing framework for Python. When run from the command line via
``nosetests``, or when run by Travis CI, nose will automatically execute
``pytest``, or when run by Travis CI, pytest will automatically execute
functions and methods whose names start with ``test`` in packages, modules
and classes whose names start with ``test`` or ``Test``, depending. (Please
see the `nose`_ documentation for full details, as this is not intended
to be a guide to nose so much as a guide to how we use it in IK.)
see the `pytest`_ documentation for full details, as this is not intended
to be a guide to pytest so much as a guide to how we use it in IK.)
Because of this, we keep all test cases in the ``instruments.tests``
package, under a subpackage named for the particular manufacturer,
such as ``instruments.tests.test_srs``. The tests for each instrument should
Expand Down Expand Up @@ -88,4 +88,4 @@ Protocol Assertion Functions

.. autofunction:: expected_protocol

.. _nose: https://nose.readthedocs.org/en/latest/
.. _pytest: https://docs.pytest.org/en/latest/
9 changes: 5 additions & 4 deletions instruments/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@

from builtins import bytes, str

from nose.tools import nottest, eq_
try:
from unittest import mock # from Python 3.3 onward, this is in the stdlib
except ImportError:
import mock

# FUNCTIONS ##################################################################

Expand Down Expand Up @@ -90,7 +93,6 @@ def expected_protocol(ins_class, host_to_ins, ins_to_host, sep="\n"):
# """Only read {} bytes out of {}""".format(current, end)


@nottest
def unit_eq(a, b, msg=None, thresh=1e-5):
"""
Asserts that two unitful quantites ``a`` and ``b``
Expand All @@ -103,13 +105,12 @@ def unit_eq(a, b, msg=None, thresh=1e-5):
assert a.units == b.units, "{} and {} have different units".format(a, b)


@nottest
def make_name_test(ins_class, name_cmd="*IDN?"):
"""
Given an instrument class, produces a test which asserts that the instrument
correctly reports its name in response to a standard command.
"""
def test():
with expected_protocol(ins_class, name_cmd + "\n", "NAME\n") as ins:
eq_(ins.name, "NAME")
assert ins.name == "NAME"
return test

0 comments on commit bb4ab21

Please sign in to comment.