diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f3a2bccfc..b1bae1c18 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,7 @@ -# evaluating GitHub actions for CI, disconsider failures when evaluating PRs +# evaluating GitHub actions for CI, disregard failures when evaluating PRs # # this is still missing: # - deploy -# - coverage # - upload github notes # name: main @@ -17,7 +16,6 @@ on: jobs: build: - runs-on: ${{ matrix.os }} strategy: @@ -86,6 +84,8 @@ jobs: python: "3.7" os: ubuntu-latest tox_env: "py37-freeze" + # coverage does not apply for freeze test, skip it + skip_coverage: true - name: "ubuntu-py38" python: "3.8" os: ubuntu-latest @@ -94,6 +94,8 @@ jobs: python: "pypy3" os: ubuntu-latest tox_env: "pypy3-xdist" + # coverage too slow with pypy3, skip it + skip_coverage: true - name: "macos-py37" python: "3.7" @@ -118,6 +120,37 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install tox - - name: Test - run: tox -e ${{ matrix.tox_env }} + pip install tox coverage + + - name: Test without coverage + if: "matrix.skip_coverage" + run: "tox -e ${{ matrix.tox_env }}" + + - name: Test with coverage + if: "! matrix.skip_coverage" + env: + _PYTEST_TOX_COVERAGE_RUN: "coverage run -m" + COVERAGE_PROCESS_START: ".coveragerc" + _PYTEST_TOX_EXTRA_DEP: "coverage-enable-subprocess" + run: "tox -e ${{ matrix.tox_env }}" + + - name: Prepare coverage token + if: success() && !matrix.skip_coverage && ( github.repository == 'pytest-dev/pytest' || github.event_name == 'pull_request' ) + run: | + python scripts/append_codecov_token.py + + - name: Combine coverage + if: success() && !matrix.skip_coverage + run: | + python -m coverage combine + python -m coverage xml + + - name: Codecov upload + if: success() && !matrix.skip_coverage + uses: codecov/codecov-action@v1 + with: + token: ${{ secrets.codecov }} + file: ./coverage.xml + flags: ${{ runner.os }} + fail_ci_if_error: false + name: ${{ matrix.name }} diff --git a/.travis.yml b/.travis.yml index 35ca8a69c..5b67f15dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,8 +52,10 @@ jobs: - env: TOXENV=pypy3-xdist python: 'pypy3' - - env: TOXENV=py35-xdist - python: '3.5' + # Coverage for Python 3.5.{0,1} specific code, mostly typing related. + - env: TOXENV=py35 PYTEST_COVERAGE=1 PYTEST_ADDOPTS="-k test_raises_cyclic_reference" + python: '3.5.1' + dist: trusty # Specialized factors for py37. - env: TOXENV=py37-pluggymaster-xdist diff --git a/scripts/append_codecov_token.py b/scripts/append_codecov_token.py new file mode 100644 index 000000000..8eecb0fa5 --- /dev/null +++ b/scripts/append_codecov_token.py @@ -0,0 +1,36 @@ +""" +Appends the codecov token to the 'codecov.yml' file at the root of the repository. + +This is done by CI during PRs and builds on the pytest-dev repository so we can upload coverage, at least +until codecov grows some native integration like it has with Travis and AppVeyor. + +See discussion in https://github.com/pytest-dev/pytest/pull/6441 for more information. +""" +import os.path +from textwrap import dedent + + +def main(): + this_dir = os.path.dirname(__file__) + cov_file = os.path.join(this_dir, "..", "codecov.yml") + + assert os.path.isfile(cov_file), "{cov_file} does not exist".format( + cov_file=cov_file + ) + + with open(cov_file, "a") as f: + # token from: https://codecov.io/gh/pytest-dev/pytest/settings + # use same URL to regenerate it if needed + text = dedent( + """ + codecov: + token: "1eca3b1f-31a2-4fb8-a8c3-138b441b50a7" + """ + ) + f.write(text) + + print("Token updated:", cov_file) + + +if __name__ == "__main__": + main() diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index c566a39e8..9eec0aeda 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -382,7 +382,7 @@ class CaptureAndPassthroughIO(CaptureIO): return self._other.write(s) -if sys.version_info < (3, 5, 2): # pragma: no cover +if sys.version_info < (3, 5, 2): def overload(f): # noqa: F811 return f diff --git a/src/_pytest/config/findpaths.py b/src/_pytest/config/findpaths.py index f06c9cfff..728246dfc 100644 --- a/src/_pytest/config/findpaths.py +++ b/src/_pytest/config/findpaths.py @@ -108,7 +108,7 @@ CFG_PYTEST_SECTION = "[pytest] section in {filename} files is no longer supporte def determine_setup( - inifile: str, + inifile: Optional[str], args: List[str], rootdir_cmd_arg: Optional[str] = None, config: Optional["Config"] = None, diff --git a/testing/python/raises.py b/testing/python/raises.py index 1c701796a..cfdbe6748 100644 --- a/testing/python/raises.py +++ b/testing/python/raises.py @@ -166,7 +166,7 @@ class TestRaises: # Early versions of Python 3.5 have some bug causing the # __call__ frame to still refer to t even after everything # is done. This makes the test pass for them. - if sys.version_info < (3, 5, 2): # pragma: no cover + if sys.version_info < (3, 5, 2): del self raise ValueError diff --git a/testing/test_config.py b/testing/test_config.py index 9735fc176..29bd45c6c 100644 --- a/testing/test_config.py +++ b/testing/test_config.py @@ -859,7 +859,7 @@ class TestRootdir: assert get_common_ancestor([no_path.join("a")]) == tmpdir @pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split()) - def test_with_ini(self, tmpdir, name): + def test_with_ini(self, tmpdir, name) -> None: inifile = tmpdir.join(name) inifile.write("[pytest]\n" if name != "setup.cfg" else "[tool:pytest]\n") @@ -874,7 +874,7 @@ class TestRootdir: assert inifile == inifile @pytest.mark.parametrize("name", "setup.cfg tox.ini".split()) - def test_pytestini_overrides_empty_other(self, tmpdir, name): + def test_pytestini_overrides_empty_other(self, tmpdir, name) -> None: inifile = tmpdir.ensure("pytest.ini") a = tmpdir.mkdir("a") a.ensure(name) @@ -882,7 +882,7 @@ class TestRootdir: assert rootdir == tmpdir assert inifile == inifile - def test_setuppy_fallback(self, tmpdir): + def test_setuppy_fallback(self, tmpdir) -> None: a = tmpdir.mkdir("a") a.ensure("setup.cfg") tmpdir.ensure("setup.py") @@ -891,14 +891,14 @@ class TestRootdir: assert inifile is None assert inicfg == {} - def test_nothing(self, tmpdir, monkeypatch): + def test_nothing(self, tmpdir, monkeypatch) -> None: monkeypatch.chdir(str(tmpdir)) rootdir, inifile, inicfg = determine_setup(None, [tmpdir]) assert rootdir == tmpdir assert inifile is None assert inicfg == {} - def test_with_specific_inifile(self, tmpdir): + def test_with_specific_inifile(self, tmpdir) -> None: inifile = tmpdir.ensure("pytest.ini") rootdir, inifile, inicfg = determine_setup(inifile, [tmpdir]) assert rootdir == tmpdir @@ -1039,7 +1039,7 @@ class TestOverrideIniArgs: result = testdir.runpytest("--override-ini", "python_files=unittest_*.py") result.stdout.fnmatch_lines(["*1 passed in*"]) - def test_with_arg_outside_cwd_without_inifile(self, tmpdir, monkeypatch): + def test_with_arg_outside_cwd_without_inifile(self, tmpdir, monkeypatch) -> None: monkeypatch.chdir(str(tmpdir)) a = tmpdir.mkdir("a") b = tmpdir.mkdir("b") @@ -1047,7 +1047,7 @@ class TestOverrideIniArgs: assert rootdir == tmpdir assert inifile is None - def test_with_arg_outside_cwd_with_inifile(self, tmpdir): + def test_with_arg_outside_cwd_with_inifile(self, tmpdir) -> None: a = tmpdir.mkdir("a") b = tmpdir.mkdir("b") inifile = a.ensure("pytest.ini") @@ -1056,13 +1056,13 @@ class TestOverrideIniArgs: assert inifile == parsed_inifile @pytest.mark.parametrize("dirs", ([], ["does-not-exist"], ["a/does-not-exist"])) - def test_with_non_dir_arg(self, dirs, tmpdir): + def test_with_non_dir_arg(self, dirs, tmpdir) -> None: with tmpdir.ensure(dir=True).as_cwd(): rootdir, inifile, inicfg = determine_setup(None, dirs) assert rootdir == tmpdir assert inifile is None - def test_with_existing_file_in_subdir(self, tmpdir): + def test_with_existing_file_in_subdir(self, tmpdir) -> None: a = tmpdir.mkdir("a") a.ensure("exist") with tmpdir.as_cwd(): diff --git a/tox.ini b/tox.ini index d33a62224..c26b7cf82 100644 --- a/tox.ini +++ b/tox.ini @@ -26,7 +26,7 @@ passenv = USER USERNAME COVERAGE_* TRAVIS PYTEST_ADDOPTS TERM setenv = _PYTEST_TOX_DEFAULT_POSARGS={env:_PYTEST_TOX_POSARGS_LSOF:} {env:_PYTEST_TOX_POSARGS_XDIST:} - # Configuration to run with coverage similar to Travis/Appveyor, e.g. + # Configuration to run with coverage similar to CI, e.g. # "tox -e py37-coverage". coverage: _PYTEST_TOX_COVERAGE_RUN=coverage run -m coverage: _PYTEST_TOX_EXTRA_DEP=coverage-enable-subprocess @@ -53,7 +53,7 @@ deps = skip_install = True basepython = python3 deps = pre-commit>=1.11.0 -commands = pre-commit run --all-files --show-diff-on-failure +commands = pre-commit run --all-files --show-diff-on-failure {posargs:} [testenv:docs] basepython = python3