diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a8aa85a8f..1ee57d948 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: GitHub Actions +name: Unit Tests on: pull_request: branches: @@ -55,7 +55,7 @@ jobs: TO_TEST="test_no_passport.py or test_datetime.py or test_defaults.py or test_jobqueue.py or test_applicationbuilder.py or test_ratelimiter.py or test_updater.py or test_callbackdatacache.py or test_request.py" pytest -v --cov -k "${TO_TEST}" # Rerun only failed tests (--lf), and don't run any tests if none failed (--lfnf=none) - pytest -v --cov --cov-append -k "${TO_TEST}" --lf --lfnf=none + pytest -v --cov --cov-append -k "${TO_TEST}" --lf --lfnf=none --junit-xml=.test_report_no_optionals.xml # No tests were selected, convert returned status code to 0 opt_dep_status=$(( $? == 5 ? 0 : $? )) @@ -66,7 +66,7 @@ jobs: # worker. Increasing number of workers has little effect on test duration, but it seems # to increase flakyness, specially on python 3.7 with --dist=loadgroup. pytest -v --cov --cov-append -n auto --dist loadfile - pytest -v --cov --cov-append -n auto --dist loadfile --lf --lfnf=none + pytest -v --cov --cov-append -n auto --dist loadfile --lf --lfnf=none --junit-xml=.test_report_optionals.xml main_status=$(( $? == 5 ? 0 : $? )) # exit with non-zero status if any of the two pytest runs failed exit $(( ${opt_dep_status} || ${main_status} )) @@ -77,12 +77,22 @@ jobs: TEST_BUILD: "true" shell: bash --noprofile --norc {0} + - name: Test Summary + id: test_summary + uses: test-summary/action@v2.1 + if: always() # always run, even if tests fail + with: + paths: | + .test_report_no_optionals.xml + .test_report_optionals.xml + - name: Submit coverage uses: codecov/codecov-action@v3 with: env_vars: OS,PYTHON name: ${{ matrix.os }}-${{ matrix.python-version }} fail_ci_if_error: true + test_official: name: test-official runs-on: ${{matrix.os}} @@ -105,8 +115,15 @@ jobs: python -W ignore -m pip install -r requirements-dev.txt - name: Compare to official api run: | - pytest -v tests/test_official.py + pytest -v tests/test_official.py --junit-xml=.test_report_official.xml exit $? env: TEST_OFFICIAL: "true" shell: bash --noprofile --norc {0} + + - name: Test Summary + id: test_summary + uses: test-summary/action@v2.1 + if: always() # always run, even if tests fail + with: + paths: .test_report_official.xml diff --git a/tests/auxil/plugin_github_group.py b/tests/auxil/plugin_github_group.py deleted file mode 100644 index 7f4c7291d..000000000 --- a/tests/auxil/plugin_github_group.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -# -# A library that provides a Python interface to the Telegram Bot API -# Copyright (C) 2015-2023 -# Leandro Toledo de Souza -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser Public License for more details. -# -# You should have received a copy of the GNU Lesser Public License -# along with this program. If not, see [http://www.gnu.org/licenses/]. -import _pytest.config -import pytest - -fold_plugins = {"_cov": "Coverage report", "flaky": "Flaky report"} - - -def terminal_summary_wrapper(original, plugin_name): - text = fold_plugins[plugin_name] - - def pytest_terminal_summary(terminalreporter): - terminalreporter.write(f"##[group] {text}\n") - original(terminalreporter) - terminalreporter.write("##[endgroup]") - - return pytest_terminal_summary - - -@pytest.mark.trylast() -def pytest_configure(config): - for hookimpl in config.pluginmanager.hook.pytest_terminal_summary._nonwrappers: - if hookimpl.plugin_name in fold_plugins: - hookimpl.function = terminal_summary_wrapper(hookimpl.function, hookimpl.plugin_name) - - -class PytestPluginHelpers: - terminal = None - previous_name = None - - -def _get_name(location): - if location[0].startswith("tests/"): - return location[0][6:] - return location[0] - - -@pytest.mark.trylast() -def pytest_itemcollected(item): - item._nodeid = item._nodeid.split("::", 1)[1] - - -@pytest.hookimpl(hookwrapper=True, tryfirst=True) -def pytest_runtest_protocol(item, nextitem): - # This is naughty but pytests' own plugins does something similar too, so who cares - if PytestPluginHelpers.terminal is None: - PytestPluginHelpers.terminal = _pytest.config.create_terminal_writer(item.config) - - name = _get_name(item.location) - - if PytestPluginHelpers.previous_name is None or PytestPluginHelpers.previous_name != name: - PytestPluginHelpers.previous_name = name - PytestPluginHelpers.terminal.write(f"\n##[group] {name}") - - yield - - if nextitem is None or _get_name(nextitem.location) != name: - PytestPluginHelpers.terminal.write("\n##[endgroup]") diff --git a/tests/conftest.py b/tests/conftest.py index 1f8171eda..a26433888 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -39,7 +39,7 @@ from telegram.ext.filters import MessageFilter, UpdateFilter from tests.auxil.build_messages import DATE from tests.auxil.ci_bots import BOT_INFO_PROVIDER from tests.auxil.constants import PRIVATE_KEY -from tests.auxil.envvars import GITHUB_ACTION, TEST_WITH_OPT_DEPS +from tests.auxil.envvars import TEST_WITH_OPT_DEPS from tests.auxil.files import data_file from tests.auxil.networking import NonchalantHttpxRequest from tests.auxil.pytest_classes import PytestApplication, PytestBot, make_bot @@ -87,10 +87,6 @@ def pytest_collection_modifyitems(items: List[pytest.Item]): parent.add_marker(pytest.mark.no_req) -if GITHUB_ACTION: - pytest_plugins = ["tests.auxil.plugin_github_group"] - - # Redefine the event_loop fixture to have a session scope. Otherwise `bot` fixture can't be # session. See https://github.com/pytest-dev/pytest-asyncio/issues/68 for more details. @pytest.fixture(scope="session")