From 33fd4fa682d01cbf9f001e315a623324a098edb9 Mon Sep 17 00:00:00 2001 From: Deko Date: Sat, 4 Mar 2023 00:15:19 +0100 Subject: [PATCH] Add test pipeline step and a basic test --- .gitignore | 10 +- .gitlab-ci.yml | 30 +++- Dockerfile | 2 +- .../discord_client.cpython-311.pyc | Bin 4383 -> 0 bytes app/__pycache__/twitch_client.cpython-311.pyc | Bin 8651 -> 0 bytes app/discord_client.py | 2 +- app/main.py | 4 +- app/tests/__init__.py | 0 app/tests/conftest.py | 16 ++ app/tests/test_discord_client.py | 44 ++++++ poetry.lock | 138 +++++++++++++++++- pyproject.toml | 3 + 12 files changed, 238 insertions(+), 11 deletions(-) delete mode 100644 app/__pycache__/discord_client.cpython-311.pyc delete mode 100644 app/__pycache__/twitch_client.cpython-311.pyc create mode 100644 app/tests/__init__.py create mode 100644 app/tests/conftest.py create mode 100644 app/tests/test_discord_client.py diff --git a/.gitignore b/.gitignore index 8b11ccf..7cacb97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,11 @@ +# Locally specific files .env .idea/ -.idea/vcs.xml + +# Cache +__pycache__/ +*.pyc + +# Tests and Coverage +.pytest_cache/ +.coverage* diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e105a6f..6b47718 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,6 @@ stages: - lint + - test - build - deploy @@ -11,17 +12,24 @@ stages: .base: image: python:3.11.2 + only: + changes: + - "/poetry.lock" + - "/pyproject.toml" + - "/app/*" + +.test: + extends: .base + stage: test + before_script: + - *install-deps .lint: extends: .base stage: lint before_script: - *install-deps - only: - changes: - - "/poetry.lock" - - "/pyproject.toml" - - "/app/*" + ###################################### # # # LINT STEPS # @@ -38,6 +46,18 @@ isort: script: - poetry run isort --check . +###################################### +# # +# TEST STEPS # +# # +###################################### + +test: + extends: .test + coverage: '/TOTAL.*\s+(\d+\%)/' + script: + - poetry run pytest --cov -v + ###################################### # # # BUILD STEPS # diff --git a/Dockerfile b/Dockerfile index 814af90..3b2b882 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,4 +12,4 @@ RUN curl -sSL https://install.python-poetry.org | python3 - ENV PATH=/root/.local/bin:$PATH RUN poetry install -CMD ["poetry", "run", "python", "app/main.py"] +CMD ["poetry", "run", "python", "-m" , "app.main"] diff --git a/app/__pycache__/discord_client.cpython-311.pyc b/app/__pycache__/discord_client.cpython-311.pyc deleted file mode 100644 index 659fe9c3c762fe72eee22a937bc7d6503b846212..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4383 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 RAn(2D6I%alpH?dF{{d*CXPy86 diff --git a/app/discord_client.py b/app/discord_client.py index 610b335..a7a5d7b 100644 --- a/app/discord_client.py +++ b/app/discord_client.py @@ -2,7 +2,7 @@ import os import requests from loguru import logger -from twitch_client import StreamInformation +from app.twitch_client import StreamInformation class DiscordClient: diff --git a/app/main.py b/app/main.py index 5ed6a8f..353d939 100644 --- a/app/main.py +++ b/app/main.py @@ -1,10 +1,10 @@ import os import time -from discord_client import DiscordClient +from app.discord_client import DiscordClient +from app.twitch_client import StreamInformation, TwitchClient from loguru import logger from requests import HTTPError -from twitch_client import StreamInformation, TwitchClient class Main: diff --git a/app/tests/__init__.py b/app/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/tests/conftest.py b/app/tests/conftest.py new file mode 100644 index 0000000..44a212e --- /dev/null +++ b/app/tests/conftest.py @@ -0,0 +1,16 @@ +from collections import namedtuple +from unittest import mock + +import pytest + + +@pytest.fixture +def mock_loggers(): + with ( + mock.patch("loguru.logger.info") as info_logger, + mock.patch("loguru.logger.error") as error_logger, + ): + mocked_loggers = namedtuple( + "mocked_loggers", ["info_logger", "error_logger"] + ) + yield mocked_loggers(info_logger, error_logger) diff --git a/app/tests/test_discord_client.py b/app/tests/test_discord_client.py new file mode 100644 index 0000000..5422787 --- /dev/null +++ b/app/tests/test_discord_client.py @@ -0,0 +1,44 @@ +import os +from unittest import mock + +import pytest +import requests_mock +from requests import HTTPError + +from app.discord_client import DiscordClient +from app.twitch_client import StreamInformation + + +def test_require_webhook_url(): + with pytest.raises(KeyError): + DiscordClient() + + +def test_send_information_to_discord_fails(mock_loggers): + stream = StreamInformation( + user_id="", + user_name="", + user_login="", + game_name="", + started_at="", + title="", + viewer_count=0, + _thumbnail_url="" + ) + + with ( + mock.patch.dict(os.environ, {"DISCORD_WEBHOOK_URL": "https://test"}), + requests_mock.Mocker() as requests_mocker, + ): + requests_mocker.post(url="https://test", status_code=400) + + discord_client = DiscordClient() + with pytest.raises(HTTPError): + discord_client.send_information_to_discord( + stream=stream, profile_image="" + ) + + assert len(mock_loggers.info_logger.call_args_list) == 1 + assert mock_loggers.info_logger.call_args.args[0] == ( + "Sending a message with an embed to the webhook..." + ) diff --git a/poetry.lock b/poetry.lock index c0708f5..6ec27a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,19 @@ +[[package]] +name = "attrs" +version = "22.2.0" +description = "Classes Without Boilerplate" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs"] +docs = ["furo", "sphinx", "myst-parser", "zope.interface", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier"] +tests = ["attrs", "zope.interface"] +tests-no-zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] +tests_no_zope = ["hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist", "cloudpickle", "mypy (>=0.971,<0.990)", "pytest-mypy-plugins"] + [[package]] name = "black" version = "23.1.0" @@ -54,6 +70,17 @@ category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +[[package]] +name = "coverage" +version = "7.2.1" +description = "Code coverage measurement for Python" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +toml = ["tomli"] + [[package]] name = "idna" version = "3.4" @@ -62,6 +89,14 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "isort" version = "5.12.0" @@ -127,6 +162,73 @@ python-versions = ">=3.7" docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)", "sphinx (>=6.1.3)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest (>=7.2.1)"] +[[package]] +name = "pluggy" +version = "1.0.0" +description = "plugin and hook calling mechanisms for python" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "pytest" +version = "7.2.2" +description = "pytest: simple powerful testing with Python" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +attrs = ">=19.2.0" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" + +[package.extras] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] + +[[package]] +name = "pytest-cov" +version = "4.0.0" +description = "Pytest plugin for measuring coverage." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] + +[[package]] +name = "pytest-cover" +version = "3.0.0" +description = "Pytest plugin for measuring coverage. Forked from `pytest-cov`." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pytest-cov = ">=2.0" + +[[package]] +name = "pytest-coverage" +version = "0.0" +description = "Pytest plugin for measuring coverage. Forked from `pytest-cov`." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +pytest-cover = "*" + [[package]] name = "requests" version = "2.28.2" @@ -145,6 +247,30 @@ urllib3 = ">=1.21.1,<1.27" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "requests-mock" +version = "1.10.0" +description = "Mock out responses from the requests package" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +requests = ">=2.3,<3" +six = "*" + +[package.extras] +fixture = ["fixtures"] +test = ["fixtures", "mock", "purl", "pytest", "sphinx", "testrepository (>=0.0.18)", "testtools", "requests-futures"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + [[package]] name = "urllib3" version = "1.26.14" @@ -172,9 +298,10 @@ dev = ["pytest (>=4.6.2)", "black (>=19.3b0)"] [metadata] lock-version = "1.1" python-versions = "^3.11" -content-hash = "2cd384690a48bd802789a049147162c975c512098cc42b7716ba54b06f448092" +content-hash = "c88f613c25a933f82f5abb7053b249fe6bc13d021c655f1da432fca43c5d2fba" [metadata.files] +attrs = [] black = [] certifi = [] charset-normalizer = [] @@ -183,13 +310,22 @@ click = [ {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] colorama = [] +coverage = [] idna = [] +iniconfig = [] isort = [] loguru = [] mypy-extensions = [] packaging = [] pathspec = [] platformdirs = [] +pluggy = [] +pytest = [] +pytest-cov = [] +pytest-cover = [] +pytest-coverage = [] requests = [] +requests-mock = [] +six = [] urllib3 = [] win32-setctime = [] diff --git a/pyproject.toml b/pyproject.toml index c3eb69b..1a2ef44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,9 @@ requests = "^2.28.2" loguru = "^0.6.0" black = "^23.1.0" isort = "^5.12.0" +pytest = "^7.2.2" +requests-mock = "^1.10.0" +pytest-coverage = "^0.0" [tool.poetry.dev-dependencies]