Use pytest instead of nosetests

Nose has been in maintenance mode for the past several years
and pytest is a good replacement.

Other changes:
- Replace deprecated assertRegexpMatches with assertRegex
- Replace deprecated assertRaisesRegexp with assertRaisesRegex
- Replace deprecated SafeConfigParser with ConfigParser
- Force reinstall pytest and mock in tox virtualenv. This is because
  the globally installed packages may not work as expected(occured in
  jenkins job).

JIRA: RHELCMP-1619
Signed-off-by: Haibo Lin <hlin@redhat.com>
This commit is contained in:
Haibo Lin 2020-07-28 09:23:53 +08:00
parent 495a4c48b2
commit 3c72755814
13 changed files with 51 additions and 54 deletions

View File

@ -9,7 +9,7 @@ PKGRPMFLAGS=--define "_topdir ${PWD}" --define "_specdir ${PWD}" --define "_sour
RPM="noarch/${PKGNAME}-$(VERSION)-$(RELEASE).noarch.rpm"
SRPM="${PKGNAME}-$(VERSION)-$(RELEASE).src.rpm"
NOSE=nosetests
PYTEST=pytest
all: help
@ -95,10 +95,10 @@ clean:
test:
$(NOSE) --exe $(NOSE_OPTS)
$(PYTEST) $(PYTEST_OPTS)
test-coverage:
$(NOSE) --exe --with-cov --cov-report html --cov-config tox.ini $(NOSE_OPTS)
$(PYTEST) --cov=pungi --cov-report term --cov-report html --cov-config tox.ini $(PYTEST_OPTS)
test-data:
./tests/data/specs/build.sh

View File

@ -42,8 +42,8 @@ These packages will have to installed:
For running unit tests, these packages are recommended as well:
* python-mock
* python-nose
* python-nose-cov
* python-pytest
* python-pytest-cov
* python-unittest2
* rpmdevtools
* python-parameterized
@ -61,7 +61,7 @@ packages above as they are used by calling an executable. ::
$ for pkg in _deltarpm krbV _selinux deltarpm sqlitecachec _sqlitecache; do ln -vs "$(deactivate && python -c 'import os, '$pkg'; print('$pkg'.__file__)')" "$(virtualenvwrapper_get_site_packages_dir)"; done
$ pip install -U pip
$ PYCURL_SSL_LIBRARY=nss pip install pycurl --no-binary :all:
$ pip install beanbag jsonschema 'kobo>=0.6.0' lockfile lxml mock nose nose-cov productmd pyopenssl python-multilib requests requests-kerberos setuptools sphinx ordered_set koji PyYAML dogpile.cache parameterized
$ pip install beanbag jsonschema 'kobo>=0.6.0' lockfile lxml mock pytest pytest-cov productmd pyopenssl python-multilib requests requests-kerberos setuptools sphinx ordered_set koji PyYAML dogpile.cache parameterized
Now you should be able to run all existing tests.
@ -149,7 +149,7 @@ Testing
You must write unit tests for any new code (except for trivial changes). Any
code without sufficient test coverage may not be merged.
To run all existing tests, suggested method is to use *nosetests*. With
To run all existing tests, suggested method is to use *pytest*. With
additional options, it can generate code coverage. To make sure even tests from
executable files are run, don't forget to use the ``--exe`` option. ::

View File

@ -7,7 +7,7 @@ Group: Development/Tools
License: GPLv2
URL: https://pagure.io/pungi
Source0: https://pagure.io/releases/%{name}/%{name}-%{version}.tar.bz2
BuildRequires: python-nose, python-mock
BuildRequires: python-pytest, python-mock
BuildRequires: python-devel, python-setuptools, python2-productmd
BuildRequires: python-lockfile, kobo, kobo-rpmlib, python-kickstart, createrepo_c
BuildRequires: python-lxml, libselinux-python, yum-utils, lorax
@ -106,7 +106,7 @@ rm -rf %{buildroot}
%{_bindir}/%{name}-wait-for-signed-ostree-handler
%check
nosetests --exe
pytest
./tests/data/specs/build.sh
cd tests && ./test_compose.sh

View File

@ -66,5 +66,5 @@ setup(
"dogpile.cache",
],
extras_require={':python_version=="2.7"': ["enum34", "lockfile"]},
tests_require=["mock", "nose", "nose-cov"],
tests_require=["mock", "pytest", "pytest-cov"],
)

View File

@ -96,7 +96,7 @@ class CheckDependenciesTestCase(unittest.TestCase):
exists.side_effect = self.dont_find(["/usr/bin/isohybrid"])
result = checks.check(conf)
self.assertRegexpMatches(out.getvalue(), r"^Not checking.*Expect failures.*$")
self.assertRegex(out.getvalue(), r"^Not checking.*Expect failures.*$")
self.assertTrue(result)
def test_isohybrid_not_needed_in_runroot(self):
@ -215,7 +215,7 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 1)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'product_name' is deprecated and now an alias to 'release_name'.*", # noqa: E501
)
@ -268,7 +268,7 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 1)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'product_name' is deprecated and now an alias to 'release_name'.*", # noqa: E501
)
@ -295,12 +295,12 @@ class TestSchemaValidator(unittest.TestCase):
config = self._load_conf_from_string(string)
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 1)
self.assertRegexpMatches(
self.assertRegex(
errors[0],
r"^ERROR: Config option 'product_name' is an alias of 'release_name', only one can be used.*", # noqa: E501
)
self.assertEqual(len(warnings), 1)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'product_name' is deprecated and now an alias to 'release_name'.*", # noqa: E501
)
@ -337,11 +337,11 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 2)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option '.+' is deprecated and now an alias to '.+'.*",
)
self.assertRegexpMatches(
self.assertRegex(
warnings[1],
r"^WARNING: Config option '.+' is deprecated and now an alias to '.+'.*",
)
@ -382,11 +382,11 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 2)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'repo_from' is deprecated, its value will be appended to option 'repo'.*", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[1],
r"^WARNING: Value from config option 'repo_from' is now appended to option 'repo'", # noqa: E501
)
@ -424,11 +424,11 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 2)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'repo_from' is deprecated, its value will be appended to option 'repo'.*", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[1],
r"^WARNING: Config option 'repo' is not found, but 'repo_from' is specified,", # noqa: E501
)
@ -470,19 +470,19 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 4)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'repo_from' is deprecated, its value will be appended to option 'repo'.*", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[1],
r"^WARNING: Config option 'repo' is not found, but 'repo_from' is specified,", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[2],
r"^WARNING: Config option 'source_repo_from' is deprecated, its value will be appended to option 'repo'", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[3],
r"^WARNING: Value from config option 'source_repo_from' is now appended to option 'repo'.", # noqa: E501
)
@ -532,11 +532,11 @@ class TestSchemaValidator(unittest.TestCase):
errors, warnings = checks.validate(config)
self.assertEqual(len(errors), 0)
self.assertEqual(len(warnings), 2)
self.assertRegexpMatches(
self.assertRegex(
warnings[0],
r"^WARNING: Config option 'repo_from' is deprecated, its value will be appended to option 'repo'.*", # noqa: E501
)
self.assertRegexpMatches(
self.assertRegex(
warnings[1],
r"^WARNING: Config option 'repo' is not found, but 'repo_from' is specified, value from 'repo_from' is now added as 'repo'.*", # noqa: E501
)

View File

@ -56,6 +56,7 @@ class ComposeTestCase(unittest.TestCase):
def test_setup_logger(self, ci):
conf = {}
logger = logging.getLogger("test_setup_logger")
logger.setLevel(logging.DEBUG)
compose = Compose(conf, self.tmp_dir, logger=logger)
self.assertEqual(len(logger.handlers), 2)

View File

@ -1341,7 +1341,7 @@ class TestGetProductIds(PungiTestCase):
get_productids_from_scm(self.compose)
self.assertEqual(get_dir_from_scm.call_args_list, [mock.call(cfg, mock.ANY)])
self.assertRegexpMatches(
self.assertRegex(
str(ctx.exception),
r"No product certificate found \(arch: amd64, variant: (Everything|Client)\)", # noqa: E501
)
@ -1365,6 +1365,4 @@ class TestGetProductIds(PungiTestCase):
get_productids_from_scm(self.compose)
self.assertEqual(get_dir_from_scm.call_args_list, [mock.call(cfg, mock.ANY)])
self.assertRegexpMatches(
str(ctx.exception), "Multiple product certificates found.+"
)
self.assertRegex(str(ctx.exception), "Multiple product certificates found.+")

View File

@ -244,9 +244,7 @@ class TestCopyFiles(helpers.PungiTestCase):
self.compose, [cfg], "x86_64", self.variant, package_sets, self.metadata
)
self.assertRegexpMatches(
str(ctx.exception), r"No.*package.*matching bad-server\*.*"
)
self.assertRegex(str(ctx.exception), r"No.*package.*matching bad-server\*.*")
self.assertEqual(len(get_file_from_scm.call_args_list), 0)
self.assertEqual(get_dir_from_scm.call_args_list, [])

View File

@ -363,7 +363,7 @@ class TestLiveMediaPhase(PungiTestCase):
phase = LiveMediaPhase(compose)
with self.assertRaisesRegexp(
with self.assertRaisesRegex(
RuntimeError, r"no.+Missing.+when building.+Server"
):
phase.run()
@ -393,7 +393,7 @@ class TestLiveMediaPhase(PungiTestCase):
phase = LiveMediaPhase(compose)
with self.assertRaisesRegexp(
with self.assertRaisesRegex(
RuntimeError, r"There is no variant Missing to get repo from."
):
phase.run()

View File

@ -550,9 +550,7 @@ class OSBSThreadTest(helpers.PungiTestCase):
with self.assertRaises(RuntimeError) as ctx:
self.t.process((self.compose, self.compose.variants["Server"], cfg), 1)
self.assertRegexpMatches(
str(ctx.exception), r"task 12345 failed: see .+ for details"
)
self.assertRegex(str(ctx.exception), r"task 12345 failed: see .+ for details")
@mock.patch("pungi.phases.osbs.kojiwrapper.KojiWrapper")
def test_failing_task_with_failable(self, KojiWrapper):

View File

@ -301,7 +301,7 @@ class TestKojiPkgset(PkgsetCompareMixin, helpers.PungiTestCase):
r"^RPM\(s\) not found for sigs: .+Check log for details.+bash-4\.3\.42-4\.fc24.+bash-debuginfo-4\.3\.42-4\.fc24$", # noqa: E501
re.DOTALL,
)
self.assertRegexpMatches(str(ctx.exception), figure)
self.assertRegex(str(ctx.exception), figure)
def test_can_not_find_signed_package_allow_invalid_sigkeys(self):
pkgset = pkgsets.KojiPackageSet(
@ -326,7 +326,7 @@ class TestKojiPkgset(PkgsetCompareMixin, helpers.PungiTestCase):
r"^RPM\(s\) not found for sigs: .+Check log for details.+bash-4\.3\.42-4\.fc24.+bash-debuginfo-4\.3\.42-4\.fc24$", # noqa: E501
re.DOTALL,
)
self.assertRegexpMatches(str(ctx.exception), figure)
self.assertRegex(str(ctx.exception), figure)
def test_can_not_find_any_package(self):
pkgset = pkgsets.KojiPackageSet(
@ -341,7 +341,7 @@ class TestKojiPkgset(PkgsetCompareMixin, helpers.PungiTestCase):
[mock.call.listTaggedRPMS("f25", event=None, inherit=True, latest=True)],
)
self.assertRegexpMatches(
self.assertRegex(
str(ctx.exception),
r"^RPM\(s\) not found for sigs: .+Check log for details.+",
)

View File

@ -4,7 +4,7 @@ import mock
import os
import shutil
import six
from six.moves.configparser import SafeConfigParser
from six.moves.configparser import ConfigParser
from tests.helpers import PungiTestCase, FIXTURE_DIR, touch, mk_boom
from pungi_utils import unified_isos
@ -24,7 +24,7 @@ class TestUnifiedIsos(PungiTestCase):
compose_path = os.path.join(self.topdir, COMPOSE_ID, "compose")
isos = unified_isos.UnifiedISO(compose_path)
self.assertEqual(isos.compose_path, compose_path)
self.assertRegexpMatches(
self.assertRegex(
isos.temp_dir, "^%s/" % os.path.join(self.topdir, COMPOSE_ID, "work")
)
@ -33,7 +33,7 @@ class TestUnifiedIsos(PungiTestCase):
self.assertEqual(
isos.compose_path, os.path.join(self.topdir, COMPOSE_ID, "compose")
)
self.assertRegexpMatches(
self.assertRegex(
isos.temp_dir, "^%s/" % os.path.join(self.topdir, COMPOSE_ID, "work")
)
@ -399,7 +399,7 @@ class TestCreaterepo(PungiTestCase):
# treeinfo checksums
for arch in self.isos.treeinfo.keys():
parser = SafeConfigParser()
parser = ConfigParser()
parser.optionxform = str
parser.read(os.path.join(self.isos.temp_dir, "trees", arch, ".treeinfo"))
checksums[arch] = [k for k, v in parser.items("checksums")]
@ -489,7 +489,7 @@ class TestCreaterepo(PungiTestCase):
# treeinfo checksums
for arch in self.isos.treeinfo.keys():
parser = SafeConfigParser()
parser = ConfigParser()
parser.optionxform = str
parser.read(os.path.join(self.isos.temp_dir, "trees", arch, ".treeinfo"))
checksums[arch] = [k for k, v in parser.items("checksums")]

16
tox.ini
View File

@ -36,15 +36,18 @@ deps =
mmdzanata
parameterized
dict.sorted
urlgrabber
mock
nose
nose-cov
unittest2
pytest
pytest-cov
whitelist_externals =
sh
make
coverage
commands =
sh -c 'find . -name "*.pyc" -exec rm -f \{\} +'
pip install --force-reinstall pytest mock
make test-coverage
coverage xml
@ -68,12 +71,13 @@ deps =
parameterized
dict.sorted
mock
nose
pytest
whitelist_externals =
sh
make
commands =
sh -c 'find . -name "__pycache__" -exec rm -rf \{\} +'
pip install --force-reinstall pytest mock
make test
[flake8]
@ -89,7 +93,5 @@ max-line-length = 88
# E203: whitespace before ':'
ignore = E402,H301,H306,E226,W503,E203
[run]
omit =
tests/*
.tox/*
[pytest]
addopts = --ignore=tests/_composes