From d94ccfee3d109a3d71eeca3ff884aee12bc71764 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 18:50:58 +0300 Subject: [PATCH 1/3] Replace Travis CI with GitHub Actions --- .github/workflows/test.yml | 47 ++++++++++++++++++++++++++++++++++++++ .travis.yml | 13 ----------- README.rst | 4 ++-- setup.py | 4 ++++ 4 files changed, 53 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/test.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..4a584f9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,47 @@ +name: Test + +on: [push, pull_request, workflow_dispatch] + +env: + FORCE_COLOR: 1 + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + python-version: ["3.4", "3.5", "3.6", "3.7.7", "3.8"] + os: [ubuntu-latest, macos-latest, windows-latest] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Get pip cache dir + id: pip-cache + run: | + echo "::set-output name=dir::$(pip cache dir)" + + - name: Cache + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache.outputs.dir }} + key: + ${{ matrix.os }}-${{ matrix.python-version }}-v1-${{ hashFiles('**/setup.py') }} + restore-keys: | + ${{ matrix.os }}-${{ matrix.python-version }}-v1- + + - name: Install dependencies + run: | + python -m pip install -U pip + python -m pip install -U wheel + python -m pip install -U tox + + - name: Test + run: | + tox -e py diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 1188768..0000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: python - -python: - - "3.4" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - -install: - - pip install . - -script: python -m pytest diff --git a/README.rst b/README.rst index f4793c9..dfb2b75 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ .. image:: https://badge.fury.io/py/nose2pytest.svg :target: https://badge.fury.io/py/nose2pytest -.. image:: https://img.shields.io/travis/pytest-dev/nose2pytest.svg - :target: https://img.shields.io/travis/pytest-dev/nose2pytest +.. image:: https://github.com/pytest-dev/nose2pytest/workflows/Test/badge.svg + :target: https://github.com/pytest-dev/nose2pytest/actions .. contents:: diff --git a/setup.py b/setup.py index 192de42..a482080 100644 --- a/setup.py +++ b/setup.py @@ -34,8 +34,12 @@ 'License :: OSI Approved :: BSD License', # Specify the Python versions you support here. + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', ], ) From d3f12c64d7cc74a24539b196b11a629572367570 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 18:52:57 +0300 Subject: [PATCH 2/3] Drop the dot https://twitter.com/pytestdotorg/status/753767547866972160 --- README.html | 22 +++++++++++----------- README.rst | 22 +++++++++++----------- nose2pytest/assert_tools.py | 4 ++-- tox.ini | 2 +- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.html b/README.html index 900327e..c33742d 100644 --- a/README.html +++ b/README.html @@ -357,7 +357,7 @@

Nose2pytest version 1.0.4 documentation

Overview

-

This package provides a Python script and py.test plugin to help convert Nose-based tests into py.test-based +

This package provides a Python script and pytest plugin to help convert Nose-based tests into pytest-based tests. Specifically, the script transforms nose.tools.assert_* function calls into raw assert statements, while preserving format of original arguments as much as possible. For example, the script

@@ -371,7 +371,7 @@ 

Overview

A small subset of nose.tools.assert_* function calls are not transformed because there is no raw assert statement equivalent, or the equivalent would be hard to -maintain. They are provided as functions in the pytest namespace via py.test's plugin system.

+maintain. They are provided as functions in the pytest namespace via pytest's plugin system.

Installation

@@ -399,15 +399,15 @@

Motivation

are not as convenient to use as raw assertions, since you have to decide before hand what type of assertion you are going to write: an identity comparison to None, a truth check, a falseness check, an identity comparison to another object, etc. Just being able to write a raw assertion, and still get good diagnostics on failure as done by -py.test, is really nice. This is a main reason for using py.test for me. Another reason is the design of fixtures -in py.test.

-

Switching an existing test suite from Nose to py.test is feasible even without nose2pytest, as it requires +pytest, is really nice. This is a main reason for using pytest for me. Another reason is the design of fixtures +in pytest.

+

Switching an existing test suite from Nose to pytest is feasible even without nose2pytest, as it requires relatively little work: relatively as in, you will probably only need a few modifications, all achievable manually, to get the same test coverage and results. A few gotchas:

  • test classes that have __init__ will be ignored, those will have to be moved (usually, into class's setup_class())
  • -
  • the setup.cfg may have to be edited since test discovery rules are slightly more strict with py.test
  • +
  • the setup.cfg may have to be edited since test discovery rules are slightly more strict with pytest
  • the order of tests may be different, but in general that should not matter
  • all test modules are imported up-front, so some test modules may need adjustment such as moving some code from the top of the test module into its setup_module()
  • @@ -415,13 +415,13 @@

    Motivation

    Once the above has been done to an existing code base, you don't really have to do anything else. However, your test suite now has an additional third-party test dependency (Nose), just because of those assert_* functions used all over the place. Moreover, there is no longer one obvious way to do things in your test suite: existing test code -uses nose.tools.assert_* functions, yet with py.test you can use raw assertions. If you add tests, which of +uses nose.tools.assert_* functions, yet with pytest you can use raw assertions. If you add tests, which of these two approaches should a developer use? If you modify existing tests, should new assertions use raw assert? Should the remaining test method, test class, or test module be updated? A test module can contain hundreds of calls to nose.tools.assert_* functions, is a developer to manually go through each one to convert it? Painful and error prone, in general not feasible to do manually.

    -

    This is why I developed nose2pytest: I wanted to migrate my pypubsub project's test suite from Nose to py.test, -but also have only py.test as a dependency, and have one obvious way to write assertions in the test suite.

    +

    This is why I developed nose2pytest: I wanted to migrate my pypubsub project's test suite from Nose to pytest, +but also have only pytest as a dependency, and have one obvious way to write assertions in the test suite.

Requirements

@@ -433,7 +433,7 @@

Requirements

Nose 1.3.7 on Windows 7 Pro 64. If you have successfully used nose2pytest with other combinations, please kindly let me know (via github).

The pytest package namespace will be extended with assert_ functions that are not converted by the script -only if, err, you have py.test installed!

+only if, err, you have pytest installed!

Status

@@ -583,7 +583,7 @@

Status

The nose2pytest distribution contains a module, assert_tools.py which defines these utility functions to contain the equivalent raw assert statement. Copy the module into your test folder or into the pytest package -and change your test code's from nose.tools import ... statements accordingly. Py.test introspection will +and change your test code's from nose.tools import ... statements accordingly. pytest introspection will provide error information on assertion failure.

  • Some Nose functions don't have a one-line assert statement equivalent, they have to remain utility functions:

    diff --git a/README.rst b/README.rst index dfb2b75..af4e0b2 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ Overview ------------ -This package provides a Python script and py.test plugin to help convert Nose-based tests into py.test-based +This package provides a Python script and pytest plugin to help convert Nose-based tests into pytest-based tests. Specifically, the script transforms ``nose.tools.assert_*`` function calls into raw assert statements, while preserving format of original arguments as much as possible. For example, the script: @@ -28,7 +28,7 @@ gets converted to: A small subset of ``nose.tools.assert_*`` function calls are not transformed because there is no raw assert statement equivalent, or the equivalent would be hard to -maintain. They are provided as functions in the pytest namespace via py.test's plugin system. +maintain. They are provided as functions in the pytest namespace via pytest's plugin system. Installation @@ -62,16 +62,16 @@ ought to use the ``assert_*()`` functions from ``nose.tools``. Although they pro are not as convenient to use as raw assertions, since you have to decide before hand what type of assertion you are going to write: an identity comparison to None, a truth check, a falseness check, an identity comparison to another object, etc. Just being able to write a raw assertion, and still get good diagnostics on failure as done by -py.test, is really nice. This is a main reason for using py.test for me. Another reason is the design of fixtures -in py.test. +pytest, is really nice. This is a main reason for using pytest for me. Another reason is the design of fixtures +in pytest. -Switching an existing test suite from Nose to py.test is feasible even without nose2pytest, as it requires +Switching an existing test suite from Nose to pytest is feasible even without nose2pytest, as it requires relatively little work: *relatively* as in, you will probably only need a few modifications, all achievable manually, to get the same test coverage and results. A few gotchas: - test classes that have ``__init__`` will be ignored, those will have to be moved (usually, into class's ``setup_class()``) -- the ``setup.cfg`` may have to be edited since test discovery rules are slightly more strict with py.test +- the ``setup.cfg`` may have to be edited since test discovery rules are slightly more strict with pytest - the order of tests may be different, but in general that should not matter - all test modules are imported up-front, so some test modules may need adjustment such as moving some code from the top of the test module into its ``setup_module()`` @@ -79,14 +79,14 @@ manually, to get the same test coverage and results. A few gotchas: Once the above has been done to an existing code base, you don't really have to do anything else. However, your test suite now has an additional third-party test dependency (Nose), just because of those ``assert_*`` functions used all over the place. Moreover, there is no longer one obvious way to do things in your test suite: existing test code -uses ``nose.tools.assert_*`` functions, yet with py.test you can use raw assertions. If you add tests, which of +uses ``nose.tools.assert_*`` functions, yet with pytest you can use raw assertions. If you add tests, which of these two approaches should a developer use? If you modify existing tests, should new assertions use raw assert? Should the remaining test method, test class, or test module be updated? A test module can contain hundreds of calls to ``nose.tools.assert_*`` functions, is a developer to manually go through each one to convert it? Painful and error prone, in general not feasible to do manually. -This is why I developed nose2pytest: I wanted to migrate my pypubsub project's test suite from Nose to py.test, -but also have only py.test as a dependency, and have one obvious way to write assertions in the test suite. +This is why I developed nose2pytest: I wanted to migrate my pypubsub project's test suite from Nose to pytest, +but also have only pytest as a dependency, and have one obvious way to write assertions in the test suite. Requirements @@ -102,7 +102,7 @@ Nose 1.3.7 on Windows 7 Pro 64. If you have successfully used nose2pytest with o kindly let me know (via github). The pytest package namespace will be extended with ``assert_`` functions that are not converted by the script -only if, err, you have py.test installed! +only if, err, you have pytest installed! Status @@ -187,7 +187,7 @@ Not every ``assert_*`` function from ``nose.tools`` is converted by nose2pytest: The nose2pytest distribution contains a module, ``assert_tools.py`` which defines these utility functions to contain the equivalent raw assert statement. Copy the module into your test folder or into the pytest package - and change your test code's ``from nose.tools import ...`` statements accordingly. Py.test introspection will + and change your test code's ``from nose.tools import ...`` statements accordingly. pytest introspection will provide error information on assertion failure. 3. Some Nose functions don't have a one-line assert statement equivalent, they have to remain utility functions: diff --git a/nose2pytest/assert_tools.py b/nose2pytest/assert_tools.py index 6afecf5..0a4a24e 100644 --- a/nose2pytest/assert_tools.py +++ b/nose2pytest/assert_tools.py @@ -5,7 +5,7 @@ This module's assert_ functions provide drop-in replacements for nose.tools.assert_ functions (many of which are pep-8-ized extractions from Python's unittest.case.TestCase methods). As such, it can be imported in a test -suite run by py.test, to replace the nose imports with functions that rely on py.test's assertion +suite run by pytest, to replace the nose imports with functions that rely on pytest's assertion introspection for error reporting. When combined with running nose2pytest.py on your test suite, this module may be sufficient to decrease your test suite's third-party dependencies by 1. """ @@ -93,7 +93,7 @@ def do_nothing(self): del _t -# py.test integration: add all assert_ function to the pytest package namespace +# pytest integration: add all assert_ function to the pytest package namespace # Use similar trick as Nose to bring in bound methods from unittest.TestCase as free functions: diff --git a/tox.ini b/tox.ini index 5a8dbb8..4219a4c 100644 --- a/tox.ini +++ b/tox.ini @@ -6,4 +6,4 @@ deps = pytest nose -commands = py.test +commands = pytest From b35d7b6ce2f34a164859c27441a2ea408765107b Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Mon, 20 Sep 2021 19:04:27 +0300 Subject: [PATCH 3/3] Drop support for EOL Python 3.4, not available on GHA CI --- .github/workflows/test.yml | 2 +- setup.py | 2 +- tox.ini | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4a584f9..f8135f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.4", "3.5", "3.6", "3.7.7", "3.8"] + python-version: ["3.5", "3.6", "3.7.7", "3.8"] os: [ubuntu-latest, macos-latest, windows-latest] steps: diff --git a/setup.py b/setup.py index a482080..dbf9e0b 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ description='Convert nose.tools.assert_ calls found in your Nose test modules into raw asserts for pytest', keywords='nose to pytest conversion', + python_requires='>=3.5', classifiers=[ # How mature is this project? Common values are # 3 - Alpha @@ -36,7 +37,6 @@ # Specify the Python versions you support here. 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', diff --git a/tox.ini b/tox.ini index 4219a4c..2ab35bf 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py34, py35, py36, py37, py38 +envlist = py35, py36, py37, py38 [testenv] deps =