mirror of
https://github.com/python-telegram-bot/python-telegram-bot.git
synced 2024-11-25 00:27:46 +01:00
Rework pytest
Integration into GitHub Actions (#3776)
This commit is contained in:
parent
b0cff31fc1
commit
62a8cfc395
3 changed files with 22 additions and 83 deletions
25
.github/workflows/test.yml
vendored
25
.github/workflows/test.yml
vendored
|
@ -1,4 +1,4 @@
|
||||||
name: GitHub Actions
|
name: Unit Tests
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
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"
|
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}"
|
pytest -v --cov -k "${TO_TEST}"
|
||||||
# Rerun only failed tests (--lf), and don't run any tests if none failed (--lfnf=none)
|
# 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
|
# No tests were selected, convert returned status code to 0
|
||||||
opt_dep_status=$(( $? == 5 ? 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
|
# 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.
|
# 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
|
||||||
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 : $? ))
|
main_status=$(( $? == 5 ? 0 : $? ))
|
||||||
# exit with non-zero status if any of the two pytest runs failed
|
# exit with non-zero status if any of the two pytest runs failed
|
||||||
exit $(( ${opt_dep_status} || ${main_status} ))
|
exit $(( ${opt_dep_status} || ${main_status} ))
|
||||||
|
@ -77,12 +77,22 @@ jobs:
|
||||||
TEST_BUILD: "true"
|
TEST_BUILD: "true"
|
||||||
shell: bash --noprofile --norc {0}
|
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
|
- name: Submit coverage
|
||||||
uses: codecov/codecov-action@v3
|
uses: codecov/codecov-action@v3
|
||||||
with:
|
with:
|
||||||
env_vars: OS,PYTHON
|
env_vars: OS,PYTHON
|
||||||
name: ${{ matrix.os }}-${{ matrix.python-version }}
|
name: ${{ matrix.os }}-${{ matrix.python-version }}
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
|
|
||||||
test_official:
|
test_official:
|
||||||
name: test-official
|
name: test-official
|
||||||
runs-on: ${{matrix.os}}
|
runs-on: ${{matrix.os}}
|
||||||
|
@ -105,8 +115,15 @@ jobs:
|
||||||
python -W ignore -m pip install -r requirements-dev.txt
|
python -W ignore -m pip install -r requirements-dev.txt
|
||||||
- name: Compare to official api
|
- name: Compare to official api
|
||||||
run: |
|
run: |
|
||||||
pytest -v tests/test_official.py
|
pytest -v tests/test_official.py --junit-xml=.test_report_official.xml
|
||||||
exit $?
|
exit $?
|
||||||
env:
|
env:
|
||||||
TEST_OFFICIAL: "true"
|
TEST_OFFICIAL: "true"
|
||||||
shell: bash --noprofile --norc {0}
|
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
|
||||||
|
|
|
@ -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 <devs@python-telegram-bot.org>
|
|
||||||
#
|
|
||||||
# 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]")
|
|
|
@ -39,7 +39,7 @@ from telegram.ext.filters import MessageFilter, UpdateFilter
|
||||||
from tests.auxil.build_messages import DATE
|
from tests.auxil.build_messages import DATE
|
||||||
from tests.auxil.ci_bots import BOT_INFO_PROVIDER
|
from tests.auxil.ci_bots import BOT_INFO_PROVIDER
|
||||||
from tests.auxil.constants import PRIVATE_KEY
|
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.files import data_file
|
||||||
from tests.auxil.networking import NonchalantHttpxRequest
|
from tests.auxil.networking import NonchalantHttpxRequest
|
||||||
from tests.auxil.pytest_classes import PytestApplication, PytestBot, make_bot
|
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)
|
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
|
# 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.
|
# session. See https://github.com/pytest-dev/pytest-asyncio/issues/68 for more details.
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
|
|
Loading…
Reference in a new issue