diff --git a/.coveragerc b/.coveragerc index fa9bab4..f5684cc 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,5 +1,4 @@ [report] include = - setup.py tests/* xmlrunner/* diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 6d220fc..662fd74 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -11,21 +11,29 @@ jobs: runs-on: ubuntu-latest strategy: matrix: + name: [ + "py310", + "py311", + "py312", + "py313", + "py314", + ] include: - - python-version: 3.7 - toxenv: py37 - - python-version: 3.8 - toxenv: py38 - - python-version: 3.8 - toxenv: py38-djangolts - - python-version: 3.8 - toxenv: py38-djangocurr - - python-version: 3.8 - toxenv: py38-quality - - python-version: 3.9 - toxenv: py39 - - python-version: "3.10" - toxenv: py310 + - name: py310 + python-version: "3.10" + tox_env: py310 + - name: py311 + python-version: "3.11" + tox_env: py311 + - name: py312 + python-version: "3.12" + tox_env: py312 + - name: py313 + python-version: "3.13" + tox_env: py313 + - name: py314 + python-version: "3.14" + tox_env: py314 steps: - name: Checkout uses: actions/checkout@v2 @@ -40,19 +48,21 @@ jobs: lsb_release -a - name: Install env: - TOXENV: ${{ matrix.toxenv }} + TOXENV: ${{ matrix.tox_env }} run: | pip install tox-gh-actions codecov coveralls pip --version tox --version - name: Script run: | - tox -v - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + tox run -v - name: After Failure if: ${{ failure() }} run: | more .tox/log/* | cat more .tox/*/log/* | cat + - name: Upload to Codecov + run: | + tox -e uploadcodecov + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index ee411f2..b580a49 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ dist/* .tox .coverage htmlcov/ + +# autogenerated +xmlrunner/version.py diff --git a/Makefile b/Makefile index eef0abf..95f83ab 100644 --- a/Makefile +++ b/Makefile @@ -12,8 +12,7 @@ checkversion: git show-ref --tags | grep -q $$(git log -1 --pretty=%H) || (echo "DID NOT TAG VERSION"; exit 1) dist: checkversion build/publish/bin - build/publish/bin/python setup.py sdist - build/publish/bin/python setup.py bdist_wheel + build/publish/bin/python -m build publish: dist/ build/publish/bin build/publish/bin/twine upload dist/* diff --git a/README.md b/README.md index b9d3102..4cba42f 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ If you use Git and want to get the latest *development* version: ````bash $ git clone https://github.com/xmlrunner/unittest-xml-reporting.git $ cd unittest-xml-reporting -$ sudo python setup.py install +$ sudo python -m pip install . ```` Or get the latest *development* version as a tarball: @@ -115,7 +115,7 @@ Or get the latest *development* version as a tarball: $ wget https://github.com/xmlrunner/unittest-xml-reporting/archive/master.zip $ unzip master.zip $ cd unittest-xml-reporting -$ sudo python setup.py install +$ sudo python -m pip install . ```` Or you can manually download the latest released version from diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..d4b6678 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,61 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = [ + "setuptools>=77", + "setuptools-scm[toml]>=6.2.3", +] + + +[project] +name = "unittest-xml-reporting" +license = "BSD-2-Clause" +license-files = [ "LICENSE" ] +dynamic = [ + "version", +] +description = "unittest-based test runner with Ant/JUnit like XML reporting." +keywords = [ + "pyunit", + "unittest", + "junit xml", + "xunit", + "report", + "testrunner", + "xmlrunner", +] +readme = "README.md" +authors = [ + {name = "Daniel Fernandes Martins"}, + {name = "Damien Nozay"}, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", + "Topic :: Software Development :: Libraries :: Python Modules", + "Topic :: Software Development :: Testing", +] +requires-python = ">=3.10" +dependencies = [ + "lxml", +] + +[project.urls] +Homepage = "http://github.com/xmlrunner/unittest-xml-reporting/tree/master/" + + +[tool.setuptools_scm] +write_to = "xmlrunner/version.py" + +[tool.distutils.bdist_wheel] +universal = 1 +python-tag = "py3" diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 65bed92..0000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[bdist_wheel] -universal = 1 -python-tag = py3 diff --git a/setup.py b/setup.py deleted file mode 100755 index c524ed4..0000000 --- a/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python - -from setuptools import setup, find_packages -from distutils.util import convert_path -import codecs - -# Load version information -main_ns = {} -ver_path = convert_path('xmlrunner/version.py') -with codecs.open(ver_path, 'rb', 'utf8') as ver_file: - exec(ver_file.read(), main_ns) - -# Load README.md -readme_path = convert_path('README.md') -with codecs.open(readme_path, 'rb', 'utf8') as readme_file: - long_description = readme_file.read() - -# this is for sdist to work. -import sys -if sys.version_info < (3, 7): - raise RuntimeError('This version requires Python 3.7+') # pragma: no cover - -setup( - name = 'unittest-xml-reporting', - version = main_ns['__version__'], - author = 'Daniel Fernandes Martins, Damien Nozay', - description = 'unittest-based test runner with Ant/JUnit like XML reporting.', - long_description = long_description, - long_description_content_type = 'text/markdown', - data_files = [('', ['LICENSE'])], - install_requires = ['lxml'], - license = 'BSD', - platforms = ['Any'], - python_requires='>=3.7', - keywords = [ - 'pyunit', 'unittest', 'junit xml', 'xunit', 'report', 'testrunner', 'xmlrunner' - ], - url = 'http://github.com/xmlrunner/unittest-xml-reporting/tree/master/', - classifiers = [ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3 :: Only', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: Implementation :: CPython', - 'Programming Language :: Python :: Implementation :: PyPy', - 'Topic :: Software Development :: Libraries :: Python Modules', - 'Topic :: Software Development :: Testing' - ], - packages = ['xmlrunner', 'xmlrunner.extra'], - zip_safe = False, - include_package_data = True, - test_suite = 'tests' -) diff --git a/tests/discovery_test.py b/tests/discovery_test.py new file mode 100644 index 0000000..19f0018 --- /dev/null +++ b/tests/discovery_test.py @@ -0,0 +1,6 @@ +import unittest + + +class DiscoveryTest(unittest.TestCase): + def test_discovery_pass(self): + pass diff --git a/tests/testsuite.py b/tests/testsuite.py index 76db902..68616e3 100755 --- a/tests/testsuite.py +++ b/tests/testsuite.py @@ -796,16 +796,22 @@ def test_xmlrunner_error_in_call(self): testsuite_output = self.stream.getvalue() self.assertIn('Exception: Massive fail', testsuite_output) + @unittest.skipIf(not unittest.BaseTestSuite._cleanup, + 'skip - do not cleanup') @unittest.skipIf(not hasattr(sys, 'getrefcount'), 'skip - PyPy does not have sys.getrefcount.') @unittest.skipIf((3, 0) <= sys.version_info < (3, 4), 'skip - test not garbage collected. ' 'https://bugs.python.org/issue11798.') def test_xmlrunner_hold_traceback(self): + import gc + suite = unittest.TestSuite() suite.addTest(self.DummyRefCountTest('test_fail')) countBeforeTest = sys.getrefcount(self.DummyRefCountTest.dummy) runner = self._test_xmlrunner(suite) + + gc.collect() countAfterTest = sys.getrefcount(self.DummyRefCountTest.dummy) self.assertEqual(countBeforeTest, countAfterTest) diff --git a/tox.ini b/tox.ini index c290205..279fdf5 100644 --- a/tox.ini +++ b/tox.ini @@ -4,32 +4,55 @@ testpaths = tests norecursedirs = tests/django_example [tox] -envlist = begin,py{py3,37,38,39,310},pytest,py38-django{lts,curr},end,quality +envlist = begin,py{py3,310,311,312,313,314},pytest,py314-django{lts,curr},end,quality [gh-actions] python = - 3.7: py37,pytest - 3.8: begin,py38,py38-django{lts,curr},end,quality - 3.9: py39 3.10: py310 + 3.11: py311 + 3.12: py312 + 3.13: py313 + 3.14: begin,py314,py314-django{tls,curr},end,quality [testenv] deps = coverage codecov>=1.4.0 coveralls - djangolts,pytest: django~=3.2.0 - djangocurr: django~=4.0.0 - pytest: pytest + djangolts: django~=4.2.0 + djangocurr: django~=5.2.0 + pytest lxml>=3.6.0 commands = - coverage run --append setup.py test - coverage report --omit='.tox/*' - python -m xmlrunner discover -p test_xmlrunner_output + python -m coverage run --append -m pytest + python -m coverage report --omit='.tox/*' + python -m xmlrunner discover -p "discovery_test.py" +passenv = + CI + TRAVIS + TRAVIS_* + CODECOV_TOKEN + COVERALLS_REPO_TOKEN + COVERALLS_* + GITHUB_ACTION + GITHUB_HEAD_REF + GITHUB_REF + GITHUB_REPOSITORY + GITHUB_RUN_ID + GITHUB_SHA + GITHUB_TOKEN + +[testenv:uploadcodecov] +commands = codecov -e TOXENV - -coveralls -passenv = CI TRAVIS_BUILD_ID TRAVIS TRAVIS_BRANCH TRAVIS_JOB_NUMBER TRAVIS_PULL_REQUEST TRAVIS_JOB_ID TRAVIS_REPO_SLUG TRAVIS_COMMIT CODECOV_TOKEN COVERALLS_REPO_TOKEN GITHUB_ACTION GITHUB_HEAD_REF GITHUB_REF GITHUB_REPOSITORY GITHUB_RUN_ID GITHUB_SHA +[testenv:uploadcoveralls] +commands = + -coveralls --service=github + +[testenv:finishcoveralls] +commands = + -coveralls --service=github --finish [testenv:pytest] commands = pytest diff --git a/xmlrunner/__init__.py b/xmlrunner/__init__.py index d244bb6..89253cd 100644 --- a/xmlrunner/__init__.py +++ b/xmlrunner/__init__.py @@ -6,7 +6,10 @@ """ # Allow version to be detected at runtime. -from .version import __version__ +try: + from .version import __version__ +except ImportError: + __version__ = "unknown" from .runner import XMLTestRunner diff --git a/xmlrunner/result.py b/xmlrunner/result.py index 96fc675..a759555 100644 --- a/xmlrunner/result.py +++ b/xmlrunner/result.py @@ -92,8 +92,14 @@ def __init__(self, first, second): self._second = second def flush(self): - self._first.flush() - self._second.flush() + try: + self._first.flush() + except ValueError: + pass + try: + self._second.flush() + except ValueError: + pass def writable(self): return True @@ -188,6 +194,9 @@ def get_error_info(self): """ return self.test_exception_info + def shortDescription(self): + return self.test_description + class _XMLTestResult(TextTestResult): """ @@ -673,3 +682,8 @@ def generate_reports(self, test_runner): def _exc_info_to_string(self, err, test): """Converts a sys.exc_info()-style tuple of values into a string.""" return super(_XMLTestResult, self)._exc_info_to_string(err, test) + + def getDescription(self, test): + if isinstance(test, tuple): + test = test[0] + return super().getDescription(test) diff --git a/xmlrunner/version.py b/xmlrunner/version.py deleted file mode 100644 index bb42b14..0000000 --- a/xmlrunner/version.py +++ /dev/null @@ -1,2 +0,0 @@ - -__version__ = '3.2.0'