diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fbc6a7c8..33f89336 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 ``` diff --git a/manage.sh b/manage.sh index 2d65667d..467b5a4f 100755 --- a/manage.sh +++ b/manage.sh @@ -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')" diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..c9c73edd --- /dev/null +++ b/pytest.ini @@ -0,0 +1,2 @@ +[pytest] +python_files=tests/*.py diff --git a/setup.py b/setup.py index da733c10..d79271b9 100755 --- a/setup.py +++ b/setup.py @@ -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"]}, diff --git a/test-requirements.txt b/test-requirements.txt index f89f7822..0ceb50a7 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,5 @@ cryptography httpretty>=0.9.6 parameterized>=0.7.0 -coverage>=5.0.3 +pytest>=5.3 +pytest-cov>=2.8 diff --git a/tests/AllTests.py b/tests/AllTests.py deleted file mode 100644 index c289219a..00000000 --- a/tests/AllTests.py +++ /dev/null @@ -1,229 +0,0 @@ -# -*- coding: utf-8 -*- - -############################ Copyrights and license ############################ -# # -# Copyright 2012 Vincent Jacques # -# Copyright 2012 Zearin # -# Copyright 2013 AKFish # -# Copyright 2013 David Farr # -# Copyright 2013 Vincent Jacques # -# Copyright 2014 Vincent Jacques # -# Copyright 2015 Ed Holland # -# Copyright 2016 John Eskew # -# Copyright 2016 Matthew Neal # -# Copyright 2016 Peter Buckley # -# Copyright 2016 Sam Corbett # -# Copyright 2017 Aaron Levine # -# Copyright 2017 Nicolas Agustín Torres # -# Copyright 2018 Hayden Fuss # -# Copyright 2018 Shinichi TAMURA # -# Copyright 2018 Steve Kowalik # -# Copyright 2018 Wan Liuyang # -# Copyright 2018 sfdye # -# Copyright 2018 Vinay Hegde -# # -# 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 . # -# # -################################################################################ - -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, -] diff --git a/tests/__main__.py b/tests/conftest.py similarity index 63% rename from tests/__main__.py rename to tests/conftest.py index eadc5ba6..88082e66 100644 --- a/tests/__main__.py +++ b/tests/conftest.py @@ -2,13 +2,7 @@ ############################ Copyrights and license ############################ # # -# Copyright 2012 Vincent Jacques # -# Copyright 2012 Zearin # -# Copyright 2013 Vincent Jacques # -# Copyright 2014 Vincent Jacques # -# Copyright 2015 Uriel Corfa # -# Copyright 2016 Peter Buckley # -# Copyright 2018 sfdye # +# Copyright 2020 Steve Kowalik # # # # 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) diff --git a/tox.ini b/tox.ini index 1f017880..1047b995 100644 --- a/tox.ini +++ b/tox.ini @@ -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