refactor(tests): optimize unit test structure

This commit is contained in:
chengyongru
2026-03-24 13:37:06 +08:00
committed by Xubin Ren
parent d25985be0b
commit 72acba5d27
52 changed files with 104 additions and 13 deletions

View File

@@ -21,13 +21,14 @@ jobs:
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Install uv
uses: astral-sh/setup-uv@v4
- name: Install system dependencies - name: Install system dependencies
run: sudo apt-get update && sudo apt-get install -y libolm-dev build-essential run: sudo apt-get update && sudo apt-get install -y libolm-dev build-essential
- name: Install dependencies - name: Install all dependencies
run: | run: uv sync --all-extras
python -m pip install --upgrade pip
pip install .[dev]
- name: Run tests - name: Run tests
run: python -m pytest tests/ -v run: uv run pytest tests/

View File

@@ -3,6 +3,7 @@
import asyncio import asyncio
import os import os
import re import re
import sys
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any
@@ -113,10 +114,11 @@ class ExecTool(Tool):
except asyncio.TimeoutError: except asyncio.TimeoutError:
pass pass
finally: finally:
try: if sys.platform != "win32":
os.waitpid(process.pid, os.WNOHANG) try:
except (ProcessLookupError, ChildProcessError) as e: os.waitpid(process.pid, os.WNOHANG)
logger.debug("Process already reaped or not found: {}", e) except (ProcessLookupError, ChildProcessError) as e:
logger.debug("Process already reaped or not found: {}", e)
return f"Error: Command timed out after {effective_timeout} seconds" return f"Error: Command timed out after {effective_timeout} seconds"
output_parts = [] output_parts = []

View File

@@ -70,11 +70,8 @@ langsmith = [
dev = [ dev = [
"pytest>=9.0.0,<10.0.0", "pytest>=9.0.0,<10.0.0",
"pytest-asyncio>=1.3.0,<2.0.0", "pytest-asyncio>=1.3.0,<2.0.0",
"pytest-cov>=6.0.0,<7.0.0",
"ruff>=0.1.0", "ruff>=0.1.0",
"matrix-nio[e2e]>=0.25.2",
"mistune>=3.0.0,<4.0.0",
"nh3>=0.2.17,<1.0.0",
"mypy>=1.19.1",
] ]
[project.scripts] [project.scripts]

View File

@@ -3,6 +3,16 @@ from types import SimpleNamespace
import pytest import pytest
# Check optional dingtalk dependencies before running tests
try:
from nanobot.channels import dingtalk
DINGTALK_AVAILABLE = getattr(dingtalk, "DINGTALK_AVAILABLE", False)
except ImportError:
DINGTALK_AVAILABLE = False
if not DINGTALK_AVAILABLE:
pytest.skip("DingTalk dependencies not installed (dingtalk-stream)", allow_module_level=True)
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
import nanobot.channels.dingtalk as dingtalk_module import nanobot.channels.dingtalk as dingtalk_module
from nanobot.channels.dingtalk import DingTalkChannel, NanobotDingTalkHandler from nanobot.channels.dingtalk import DingTalkChannel, NanobotDingTalkHandler

View File

@@ -1,3 +1,14 @@
# Check optional Feishu dependencies before running tests
try:
from nanobot.channels import feishu
FEISHU_AVAILABLE = getattr(feishu, "FEISHU_AVAILABLE", False)
except ImportError:
FEISHU_AVAILABLE = False
if not FEISHU_AVAILABLE:
import pytest
pytest.skip("Feishu dependencies not installed (lark-oapi)", allow_module_level=True)
from nanobot.channels.feishu import FeishuChannel from nanobot.channels.feishu import FeishuChannel

View File

@@ -1,3 +1,14 @@
# Check optional Feishu dependencies before running tests
try:
from nanobot.channels import feishu
FEISHU_AVAILABLE = getattr(feishu, "FEISHU_AVAILABLE", False)
except ImportError:
FEISHU_AVAILABLE = False
if not FEISHU_AVAILABLE:
import pytest
pytest.skip("Feishu dependencies not installed (lark-oapi)", allow_module_level=True)
from nanobot.channels.feishu import FeishuChannel, _extract_post_content from nanobot.channels.feishu import FeishuChannel, _extract_post_content

View File

@@ -7,6 +7,16 @@ from unittest.mock import MagicMock, patch
import pytest import pytest
# Check optional Feishu dependencies before running tests
try:
from nanobot.channels import feishu
FEISHU_AVAILABLE = getattr(feishu, "FEISHU_AVAILABLE", False)
except ImportError:
FEISHU_AVAILABLE = False
if not FEISHU_AVAILABLE:
pytest.skip("Feishu dependencies not installed (lark-oapi)", allow_module_level=True)
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
from nanobot.channels.feishu import FeishuChannel, FeishuConfig from nanobot.channels.feishu import FeishuChannel, FeishuConfig

View File

@@ -6,6 +6,17 @@ list of card elements into groups so that each group contains at most one
table, allowing nanobot to send multiple cards instead of failing. table, allowing nanobot to send multiple cards instead of failing.
""" """
# Check optional Feishu dependencies before running tests
try:
from nanobot.channels import feishu
FEISHU_AVAILABLE = getattr(feishu, "FEISHU_AVAILABLE", False)
except ImportError:
FEISHU_AVAILABLE = False
if not FEISHU_AVAILABLE:
import pytest
pytest.skip("Feishu dependencies not installed (lark-oapi)", allow_module_level=True)
from nanobot.channels.feishu import FeishuChannel from nanobot.channels.feishu import FeishuChannel

View File

@@ -6,6 +6,16 @@ from unittest.mock import MagicMock, patch
import pytest import pytest
from pytest import mark from pytest import mark
# Check optional Feishu dependencies before running tests
try:
from nanobot.channels import feishu
FEISHU_AVAILABLE = getattr(feishu, "FEISHU_AVAILABLE", False)
except ImportError:
FEISHU_AVAILABLE = False
if not FEISHU_AVAILABLE:
pytest.skip("Feishu dependencies not installed (lark-oapi)", allow_module_level=True)
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.channels.feishu import FeishuChannel from nanobot.channels.feishu import FeishuChannel

View File

@@ -4,6 +4,12 @@ from types import SimpleNamespace
import pytest import pytest
# Check optional matrix dependencies before importing
try:
import nh3 # noqa: F401
except ImportError:
pytest.skip("Matrix dependencies not installed (nh3)", allow_module_level=True)
import nanobot.channels.matrix as matrix_module import nanobot.channels.matrix as matrix_module
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus

View File

@@ -4,6 +4,16 @@ from types import SimpleNamespace
import pytest import pytest
# Check optional QQ dependencies before running tests
try:
from nanobot.channels import qq
QQ_AVAILABLE = getattr(qq, "QQ_AVAILABLE", False)
except ImportError:
QQ_AVAILABLE = False
if not QQ_AVAILABLE:
pytest.skip("QQ dependencies not installed (qq-botpy)", allow_module_level=True)
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
from nanobot.channels.qq import QQChannel, QQConfig from nanobot.channels.qq import QQChannel, QQConfig

View File

@@ -2,6 +2,12 @@ from __future__ import annotations
import pytest import pytest
# Check optional Slack dependencies before running tests
try:
import slack_sdk # noqa: F401
except ImportError:
pytest.skip("Slack dependencies not installed (slack-sdk)", allow_module_level=True)
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
from nanobot.channels.slack import SlackChannel from nanobot.channels.slack import SlackChannel

View File

@@ -5,6 +5,12 @@ from unittest.mock import AsyncMock
import pytest import pytest
# Check optional Telegram dependencies before running tests
try:
import telegram # noqa: F401
except ImportError:
pytest.skip("Telegram dependencies not installed (python-telegram-bot)", allow_module_level=True)
from nanobot.bus.events import OutboundMessage from nanobot.bus.events import OutboundMessage
from nanobot.bus.queue import MessageBus from nanobot.bus.queue import MessageBus
from nanobot.channels.telegram import TELEGRAM_REPLY_CONTEXT_MAX_LEN, TelegramChannel from nanobot.channels.telegram import TELEGRAM_REPLY_CONTEXT_MAX_LEN, TelegramChannel