Switch to using pytest (#1423)

Due to the recent deprecation of setup.py test, we should move with the
times, and switch to a non-deprecated test runner.

Add configuration for pytest, and switch tox to using it. Remove
AllTests, since it is no longer required to locate test classes, and
rewrite tests/__main__.py as a pytest conftest plugin.

Also drop the test function from manage.sh, tox does a much better job.
This commit is contained in:
Steve Kowalik
2020-03-07 12:43:49 +11:00
committed by GitHub
parent f2939eb731
commit c822dd1ce0
8 changed files with 31 additions and 269 deletions
+12 -6
View File
@@ -77,11 +77,10 @@ First you need to install the test dependencies:
pip install -r test-requirements.txt
```
Then you can run the tests through `python -m tests`.
Run a specific test with `python -m tests TestCase` or `python -m tests TestCase.testMethod`.
Then you can run the tests through `pytest`.
Run a specific test with `pytest tests/tests_filename.py` or `pytest tests/tests_filename.py -k testMethod` or `pytest -k TestClass.testMethod`.
If you add a new test, for example `Issue139.testCompletion`, you must add an import in `tests/AllTests.py`.
Then, you have to run `python -m tests Issue139.testCompletion --record` to create the `tests/ReplayData/*.txt` files needed for your new test.
If you add a new test, for example `Issue139.testCompletion`, you have to run `pytest -k Issue139.testCompletion --record` to create the `tests/ReplayData/*.txt` files needed for your new test.
Check them and commit them as well.
You will need a `GithubCredentials.py` file at the root of the project with the following contents:
@@ -93,9 +92,9 @@ jwt = "my_json_web_token" # Can be left empty if not used
```
If you use 2 factor authentication on your Github account, tests that require a login/password authentication will fail.
You can use `python -m tests Issue139.testCompletion --record --auth_with_token` to use the `oauth_token` field specified in `GithubCredentials.py` when recording a unit test interaction. Note that the `password = ""` (empty string is ok) must still be present in `GithubCredentials.py` to run the tests even when the `--auth_with_token` arg is used. (Also note that if you record your test data with `--auth_with_token` then you also need to be in token authentication mode when running the test. A simple alternative is to replace `token private_token_removed` with `Basic login_and_password_removed` in all your newly generated ReplayData files.)
You can use `pytest Issue139.testCompletion --record --auth_with_token` to use the `oauth_token` field specified in `GithubCredentials.py` when recording a unit test interaction. Note that the `password = ""` (empty string is ok) must still be present in `GithubCredentials.py` to run the tests even when the `--auth_with_token` arg is used. (Also note that if you record your test data with `--auth_with_token` then you also need to be in token authentication mode when running the test. A simple alternative is to replace `token private_token_removed` with `Basic login_and_password_removed` in all your newly generated ReplayData files.)
Similarly, you can use `python -m tests Issue139.testCompletion --record --auth_with_jwt` to use the `jwt` field specified in `GithubCredentials.py` to access endpoints that require JWT.
Similarly, you can use `pytest Issue139.testCompletion --record --auth_with_jwt` to use the `jwt` field specified in `GithubCredentials.py` to access endpoints that require JWT.
To run manual tests with external scripts that use the PyGithub package, you can install your development version with:
@@ -103,6 +102,13 @@ To run manual tests with external scripts that use the PyGithub package, you can
pip install --editable path/to/project
```
You may also want to investigate `tox` to run tests:
``
pip install tox
tox -epy36,flake8,black,isort
```
## Build documentation locally
```
-5
View File
@@ -17,11 +17,6 @@ function fix_headers {
python scripts/fix_headers.py
}
function test {
coverage run --branch --include=github/*.py --omit=github/tests/*.py setup.py test --quiet || exit
coverage report --show-missing || exit
}
function bump {
previousVersion=$( grep '^version =' setup.py | sed 's/version = \"\(.*\)\"/\1/' )
echo "Next version number? (previous: '$previousVersion')"
+2
View File
@@ -0,0 +1,2 @@
[pytest]
python_files=tests/*.py
-1
View File
@@ -98,7 +98,6 @@ if __name__ == "__main__":
"Programming Language :: Python :: 3.8",
"Topic :: Software Development",
],
test_suite="tests.AllTests",
python_requires=">=3.5",
install_requires=["deprecated", "pyjwt", "requests>=2.14.0"],
extras_require={"integrations": ["cryptography"]},
+2 -1
View File
@@ -1,4 +1,5 @@
cryptography
httpretty>=0.9.6
parameterized>=0.7.0
coverage>=5.0.3
pytest>=5.3
pytest-cov>=2.8
-229
View File
@@ -1,229 +0,0 @@
# -*- coding: utf-8 -*-
############################ Copyrights and license ############################
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 AKFish <akfish@gmail.com> #
# Copyright 2013 David Farr <david.farr@sap.com> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2015 Ed Holland <eholland@alertlogic.com> #
# Copyright 2016 John Eskew <jeskew@edx.org> #
# Copyright 2016 Matthew Neal <meneal@matthews-mbp.raleigh.ibm.com> #
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
# Copyright 2016 Sam Corbett <sam.corbett@cloudsoftcorp.com> #
# Copyright 2017 Aaron Levine <allevin@sandia.gov> #
# Copyright 2017 Nicolas Agustín Torres <nicolastrres@gmail.com> #
# Copyright 2018 Hayden Fuss <wifu1234@gmail.com> #
# Copyright 2018 Shinichi TAMURA <shnch.tmr@gmail.com> #
# Copyright 2018 Steve Kowalik <steven@wedontsleep.org> #
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
# Copyright 2018 sfdye <tsfdye@gmail.com> #
# Copyright 2018 Vinay Hegde <vinayhegde2010@gmail.com>
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
# #
# PyGithub is free software: you can redistribute it and/or modify it under #
# the terms of the GNU Lesser General Public License as published by the Free #
# Software Foundation, either version 3 of the License, or (at your option) #
# any later version. #
# #
# PyGithub 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 General Public License for more #
# details. #
# #
# You should have received a copy of the GNU Lesser General Public License #
# along with PyGithub. If not, see <http://www.gnu.org/licenses/>. #
# #
################################################################################
from .AuthenticatedUser import AuthenticatedUser
from .Authentication import Authentication
from .Authorization import Authorization
from .BadAttributes import BadAttributes
from .Branch import Branch
from .BranchProtection import BranchProtection
from .Commit import Commit
from .CommitCombinedStatus import CommitCombinedStatus
from .CommitComment import CommitComment
from .CommitStatus import CommitStatus
from .ConditionalRequestUpdate import ConditionalRequestUpdate
from .Connection import Connection
from .ContentFile import ContentFile
from .Download import Download
from .Enterprise import Enterprise
from .Equality import Equality
from .Event import Event
from .Exceptions import Exceptions, SpecificExceptions
from .ExposeAllAttributes import ExposeAllAttributes
from .Gist import Gist
from .GistComment import GistComment
from .GitBlob import GitBlob
from .GitCommit import GitCommit
from .Github_ import Github
from .GithubIntegration import GithubIntegration
from .GitMembership import GitMembership
from .GitRef import GitRef
from .GitRelease import Release
from .GitReleaseAsset import ReleaseAsset
from .GitTag import GitTag
from .GitTree import GitTree
from .Hook import Hook
from .Issue import Issue
from .Issue33 import Issue33
from .Issue50 import Issue50
from .Issue54 import Issue54
from .Issue80 import Issue80
from .Issue87 import Issue87
from .Issue131 import Issue131
from .Issue133 import Issue133
from .Issue134 import Issue134
from .Issue139 import Issue139
from .Issue140 import Issue140
from .Issue142 import Issue142
from .Issue158 import Issue158
from .Issue174 import Issue174
from .Issue214 import Issue214
from .Issue216 import Issue216
from .Issue278 import Issue278
from .Issue494 import Issue494
from .Issue572 import Issue572
from .Issue823 import Issue823
from .Issue937 import Issue937
from .Issue945 import Issue945
from .IssueComment import IssueComment
from .IssueEvent import IssueEvent
from .Label import Label
from .License import License
from .Logging_ import Logging
from .Markdown import Markdown
from .Migration import Migration
from .Milestone import Milestone
from .NamedUser import NamedUser
from .Notification import Notification
from .Organization import Organization
from .OrganizationHasInMembers import OrganizationHasInMembers
from .PaginatedList import PaginatedList
from .Persistence import Persistence
from .Project import Project
from .PullRequest import PullRequest
from .PullRequest1168 import PullRequest1168
from .PullRequest1169 import PullRequest1169
from .PullRequest1375 import PullRequest1375
from .PullRequestComment import PullRequestComment
from .PullRequestFile import PullRequestFile
from .PullRequestReview import PullRequestReview
from .RateLimiting import RateLimiting
from .RawData import RawData
from .Reaction import Reaction
from .Repository import LazyRepository, Repository
from .RepositoryKey import RepositoryKey
from .RequiredPullRequestReviews import RequiredPullRequestReviews
from .RequiredStatusChecks import RequiredStatusChecks
from .Retry import Retry
from .Search import Search
from .SourceImport import SourceImport
from .Tag import Tag
from .Team import Team
from .Topic import Topic
from .Traffic import Traffic
from .UserKey import UserKey
__all__ = [
AuthenticatedUser,
Authentication,
Authorization,
BadAttributes,
Branch,
BranchProtection,
Commit,
CommitCombinedStatus,
CommitComment,
CommitStatus,
ConditionalRequestUpdate,
Connection,
ContentFile,
Download,
Enterprise,
Equality,
Event,
Exceptions,
ExposeAllAttributes,
Gist,
GistComment,
GitBlob,
GitCommit,
GitMembership,
Github,
GithubIntegration,
GitRef,
GitTag,
GitTree,
Hook,
Issue,
Issue33,
Issue50,
Issue54,
Issue80,
Issue87,
Issue131,
Issue133,
Issue134,
Issue139,
Issue140,
Issue142,
Issue158,
Issue174,
Issue214,
Issue216,
Issue278,
Issue494,
Issue572,
Issue823,
Issue937,
Issue945,
IssueComment,
IssueEvent,
LazyRepository,
Label,
License,
Logging,
Markdown,
Migration,
Milestone,
NamedUser,
Notification,
Organization,
OrganizationHasInMembers,
PaginatedList,
Persistence,
Project,
PullRequest,
PullRequest1168,
PullRequest1169,
PullRequest1375,
PullRequestComment,
PullRequestReview,
PullRequestFile,
RateLimiting,
RawData,
Reaction,
Release,
ReleaseAsset,
Repository,
RepositoryKey,
RequiredPullRequestReviews,
RequiredStatusChecks,
Retry,
Search,
SpecificExceptions,
SourceImport,
Tag,
Team,
Topic,
Traffic,
UserKey,
]
+14 -26
View File
@@ -2,13 +2,7 @@
############################ Copyrights and license ############################
# #
# Copyright 2012 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2012 Zearin <zearin@gonk.net> #
# Copyright 2013 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2014 Vincent Jacques <vincent@vincent-jacques.net> #
# Copyright 2015 Uriel Corfa <uriel@corfa.fr> #
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
# Copyright 2018 sfdye <tsfdye@gmail.com> #
# Copyright 2020 Steve Kowalik <steven@wedontsleep.org> #
# #
# This file is part of PyGithub. #
# http://pygithub.readthedocs.io/ #
@@ -28,27 +22,21 @@
# #
################################################################################
import sys
import unittest
from . import AllTests, Framework
from . import Framework
def main(argv):
if "--record" in argv:
def pytest_addoption(parser):
parser.addoption("--record", action="store_true", help="record mode")
parser.addoption(
"--auth_with_token", action="store_true", help="auth using a token"
)
parser.addoption("--auth_with_jwt", action="store_true", help="auth using JWT")
def pytest_configure(config):
if config.getoption("record"):
Framework.activateRecordMode()
argv = [arg for arg in argv if arg != "--record"]
if "--auth_with_token" in argv:
if config.getoption("auth_with_token"):
Framework.activateTokenAuthMode()
argv = [arg for arg in argv if arg != "--auth_with_token"]
if "--auth_with_jwt" in argv:
if config.getoption("auth_with_jwt"):
Framework.activateJWTAuthMode()
argv = [arg for arg in argv if arg != "--auth_with_jwt"]
unittest.main(module=AllTests, argv=argv)
if __name__ == "__main__":
main(sys.argv)
+1 -1
View File
@@ -7,7 +7,7 @@ envlist =
[testenv]
deps = -rtest-requirements.txt
commands = coverage run --source github,tests setup.py test
commands = pytest --cov=github {posargs}
[testenv:flake8]
basepython = python3.6