Skip to content

Commit

Permalink
test: 提高测试覆盖率 (#97)
Browse files Browse the repository at this point in the history
  • Loading branch information
he0119 authored Dec 31, 2022
1 parent 0af8647 commit eded990
Show file tree
Hide file tree
Showing 10 changed files with 550 additions and 63 deletions.
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[report]
exclude_lines =
pragma: no cover
if TYPE_CHECKING:
raise NotImplementedError
46 changes: 46 additions & 0 deletions tests/models/test_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ def __init__(self, status_code: int):
return MockResponse(200)
if url == "https://v2.nonebot.dev":
return MockResponse(200)
if url == "exception":
raise Exception("test exception")

return MockResponse(404)


def test_adapter_from_issue(mocker: MockerFixture) -> None:
"""测试从 issue 中构造 AdapterPublishInfo 的情况"""
import src.globals as g
from src.models import AdapterPublishInfo

mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)
Expand All @@ -53,6 +56,18 @@ def test_adapter_from_issue(mocker: MockerFixture) -> None:
is_official=False,
)

info.update_file()

with g.settings.input_config.adapter_path.open("r") as f:
data = json.load(f)[1]
assert data == info.dict()
mock_httpx.assert_has_calls(
[
mocker.call("https://pypi.org/pypi/project_link/json"),
mocker.call("https://v2.nonebot.dev"),
] # type: ignore
)


def test_adapter_from_issue_trailing_whitespace(mocker: MockerFixture) -> None:
"""测试末尾如果有空格的情况"""
Expand Down Expand Up @@ -82,6 +97,13 @@ def test_adapter_from_issue_trailing_whitespace(mocker: MockerFixture) -> None:
is_official=False,
)

mock_httpx.assert_has_calls(
[
mocker.call("https://pypi.org/pypi/project_link/json"),
mocker.call("https://v2.nonebot.dev"),
] # type: ignore
)


def test_adapter_info_validation_success(mocker: MockerFixture) -> None:
"""测试验证成功的情况"""
Expand Down Expand Up @@ -191,3 +213,27 @@ def test_adapter_info_name_validation_failed(mocker: MockerFixture) -> None:
mocker.call("https://v2.nonebot.dev"),
]
mock_httpx.assert_has_calls(calls) # type: ignore


def test_adapter_info_validation_failed_http_exception(mocker: MockerFixture) -> None:
"""测试验证失败的情况,HTTP 请求报错"""
from src.models import AdapterPublishInfo, MyValidationError

mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)
mock_issue = mocker.MagicMock()
mock_issue.body = generate_issue_body(homepage="exception")
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
AdapterPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Adapter: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="exception">主页</a> 返回状态码 None。<dt>请确保您的项目主页可访问。</dt></li></code></pre>\n<details><summary>详情</summary><pre><code><li>✅ 标签: test-#ffffff。</li><li>✅ 包 <a href="https://pypi.org/project/project_link/">project_link</a> 已发布至 PyPI。</li></code></pre></details>"""
)

calls = [
mocker.call("https://pypi.org/pypi/project_link/json"),
mocker.call("exception"),
]
mock_httpx.assert_has_calls(calls) # type: ignore
89 changes: 61 additions & 28 deletions tests/models/test_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections import OrderedDict
from typing import Union

import pytest
from pytest_mock import MockerFixture


Expand All @@ -25,12 +26,15 @@ def __init__(self, status_code: int):
return MockResponse(200)
if url == "https://v2.nonebot.dev":
return MockResponse(200)
if url == "exception":
raise Exception("test exception")

return MockResponse(404)


def test_bot_from_issue(mocker: MockerFixture) -> None:
"""测试从 issue 中构造 BotPublishInfo"""
import src.globals as g
from src.models import BotPublishInfo

mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)
Expand All @@ -48,6 +52,12 @@ def test_bot_from_issue(mocker: MockerFixture) -> None:
tags=[{"label": "test", "color": "#ffffff"}],
is_official=False,
)

info.update_file()

with g.settings.input_config.bot_path.open("r") as f:
data = json.load(f)[1]
assert data == info.dict()
mock_httpx.assert_called_once_with("https://v2.nonebot.dev")


Expand Down Expand Up @@ -118,13 +128,13 @@ def test_bot_info_validation_failed(mocker: MockerFixture) -> None:
)
mock_issue.user.login = "author"

try:
info = BotPublishInfo.from_issue(mock_issue)
except MyValidationError as e:
assert (
e.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 第 2 个标签名称过长<dt>请确保标签名称不超过 10 个字符。</dt></li><li>⚠️ 第 2 个标签颜色错误<dt>请确保标签颜色符合十六进制颜色码规则。</dt></li></code></pre>"""
)
with pytest.raises(MyValidationError) as e:
BotPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 第 2 个标签名称过长<dt>请确保标签名称不超过 10 个字符。</dt></li><li>⚠️ 第 2 个标签颜色错误<dt>请确保标签颜色符合十六进制颜色码规则。</dt></li></code></pre>"""
)

calls = [
mocker.call("https://www.baidu.com"),
Expand All @@ -144,13 +154,13 @@ def test_bot_info_validation_failed_json_error(mocker: MockerFixture) -> None:
)
mock_issue.user.login = "author"

try:
info = BotPublishInfo.from_issue(mock_issue)
except MyValidationError as e:
assert (
e.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 标签解码失败。<dt>请确保标签格式正确。</dt></li></code></pre>"""
)
with pytest.raises(MyValidationError) as e:
BotPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 标签解码失败。<dt>请确保标签格式正确。</dt></li></code></pre>"""
)

calls = [
mocker.call("https://www.baidu.com"),
Expand All @@ -170,13 +180,13 @@ def test_bot_info_validation_failed_tag_field_missing(mocker: MockerFixture) ->
)
mock_issue.user.login = "author"

try:
info = BotPublishInfo.from_issue(mock_issue)
except MyValidationError as e:
assert (
e.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 第 1 个标签缺少 color 字段。<dt>请确保标签字段完整。</dt></li></code></pre>"""
)
with pytest.raises(MyValidationError) as e:
BotPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="https://www.baidu.com">主页</a> 返回状态码 404。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 第 1 个标签缺少 color 字段。<dt>请确保标签字段完整。</dt></li></code></pre>"""
)

calls = [
mocker.call("https://www.baidu.com"),
Expand All @@ -193,15 +203,38 @@ def test_bot_info_validation_failed_name_tags_missing(mocker: MockerFixture) ->
mock_issue.body = generate_issue_body(name="", tags="")
mock_issue.user.login = "author"

try:
info = BotPublishInfo.from_issue(mock_issue)
except MyValidationError as e:
assert (
e.message
== """> Bot: \n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ name: 无法匹配到数据。<dt>请确保填写该项目。</dt></li><li>⚠️ tags: 无法匹配到数据。<dt>请确保填写该项目。</dt></li></code></pre>\n<details><summary>详情</summary><pre><code><li>✅ 项目 <a href="https://v2.nonebot.dev">主页</a> 返回状态码 200。</li></code></pre></details>"""
)
with pytest.raises(MyValidationError) as e:
BotPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Bot: \n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ name: 无法匹配到数据。<dt>请确保填写该项目。</dt></li><li>⚠️ tags: 无法匹配到数据。<dt>请确保填写该项目。</dt></li></code></pre>\n<details><summary>详情</summary><pre><code><li>✅ 项目 <a href="https://v2.nonebot.dev">主页</a> 返回状态码 200。</li></code></pre></details>"""
)

calls = [
mocker.call("https://v2.nonebot.dev"),
]
mock_httpx.assert_has_calls(calls) # type: ignore


def test_bot_info_validation_failed_http_exception(mocker: MockerFixture) -> None:
"""测试验证失败的情况,HTTP 请求报错"""
from src.models import BotPublishInfo, MyValidationError

mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)
mock_issue = mocker.MagicMock()
mock_issue.body = generate_issue_body(homepage="exception")
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
BotPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Bot: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="exception">主页</a> 返回状态码 None。<dt>请确保您的项目主页可访问。</dt></li></code></pre>\n<details><summary>详情</summary><pre><code><li>✅ 标签: test-#ffffff。</li></code></pre></details>"""
)

calls = [
mocker.call("exception"),
]
mock_httpx.assert_has_calls(calls) # type: ignore
6 changes: 3 additions & 3 deletions tests/models/test_name.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def test_pypi_project_name_invalid(mocker: MockerFixture) -> None:
mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)

with pytest.raises(ValidationError) as e:
info = AdapterPublishInfo(
AdapterPublishInfo(
module_name="module_name",
project_link="project_link/",
name="name",
Expand All @@ -60,7 +60,7 @@ def test_module_name_invalid(mocker: MockerFixture) -> None:
mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)

with pytest.raises(ValidationError) as e:
info = AdapterPublishInfo(
AdapterPublishInfo(
module_name="1module_name",
project_link="project_link",
name="name",
Expand All @@ -87,7 +87,7 @@ def test_name_duplication(mocker: MockerFixture) -> None:
mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)

with pytest.raises(ValidationError) as e:
info = AdapterPublishInfo(
AdapterPublishInfo(
module_name="module_name1",
project_link="project_link1",
name="name",
Expand Down
43 changes: 40 additions & 3 deletions tests/models/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def __init__(self, status_code: int):
return MockResponse(200)
if url == "https://v2.nonebot.dev":
return MockResponse(200)
if url == "exception":
raise Exception("test exception")

return MockResponse(404)

Expand All @@ -33,6 +35,7 @@ def test_plugin_from_issue(mocker: MockerFixture) -> None:
"""测试从 issue 中构造 PluginPublishInfo 的情况"""
import os

import src.globals as g
from src.models import PluginPublishInfo

os.environ["PLUGIN_TEST_RESULT"] = "True"
Expand All @@ -54,6 +57,12 @@ def test_plugin_from_issue(mocker: MockerFixture) -> None:
tags=[{"label": "test", "color": "#ffffff"}],
is_official=False,
)

info.update_file()

with g.settings.input_config.plugin_path.open("r") as f:
data = json.load(f)[1]
assert data == info.dict(exclude={"plugin_test_result"})
calls = [
mocker.call("https://pypi.org/pypi/project_link/json"),
mocker.call("https://v2.nonebot.dev"),
Expand Down Expand Up @@ -181,7 +190,7 @@ def test_plugin_info_validation_failed(mocker: MockerFixture) -> None:
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
info = PluginPublishInfo.from_issue(mock_issue)
PluginPublishInfo.from_issue(mock_issue)

assert (
e.value.message
Expand Down Expand Up @@ -211,7 +220,7 @@ def test_plugin_info_validation_partial_failed(mocker: MockerFixture) -> None:
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
info = PluginPublishInfo.from_issue(mock_issue)
PluginPublishInfo.from_issue(mock_issue)

assert (
e.value.message
Expand Down Expand Up @@ -244,7 +253,7 @@ def test_plugin_info_skip_plugin_test(mocker: MockerFixture) -> None:
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
info = PluginPublishInfo.from_issue(mock_issue)
PluginPublishInfo.from_issue(mock_issue)

assert (
e.value.message
Expand All @@ -255,3 +264,31 @@ def test_plugin_info_skip_plugin_test(mocker: MockerFixture) -> None:
mocker.call("https://www.baidu.com"),
]
mock_httpx.assert_has_calls(calls) # type: ignore


def test_plugin_info_validation_failed_http_exception(mocker: MockerFixture) -> None:
"""测试验证失败的情况,HTTP 请求报错"""
import os

from src.models import MyValidationError, PluginPublishInfo

os.environ["PLUGIN_TEST_RESULT"] = "False"
os.environ["PLUGIN_TEST_OUTPUT"] = "test output"

mock_httpx = mocker.patch("httpx.get", side_effect=mocked_httpx_get)
mock_issue = mocker.MagicMock()
mock_issue.body = generate_issue_body(homepage="exception")
mock_issue.user.login = "author"

with pytest.raises(MyValidationError) as e:
PluginPublishInfo.from_issue(mock_issue)

assert (
e.value.message
== """> Plugin: name\n\n**⚠️ 在发布检查过程中,我们发现以下问题:**\n<pre><code><li>⚠️ 项目 <a href="exception">主页</a> 返回状态码 None。<dt>请确保您的项目主页可访问。</dt></li><li>⚠️ 插件加载测试未通过。<details><summary>测试输出</summary>test output</details></li></code></pre>\n<details><summary>详情</summary><pre><code><li>✅ 标签: test-#ffffff。</li><li>✅ 包 <a href="https://pypi.org/project/project_link/">project_link</a> 已发布至 PyPI。</li></code></pre></details>"""
)
calls = [
mocker.call("https://pypi.org/pypi/project_link/json"),
mocker.call("exception"),
]
mock_httpx.assert_has_calls(calls) # type: ignore
Loading

0 comments on commit eded990

Please sign in to comment.