""" 测试 seed_is_exist 功能(真实数据库) 测试说明: - 调用真实的 seed_is_exist 函数和真实 MySQL 数据库(192.168.123.199) - 首次运行自动创建 LookingWeb 库和 seeds_info 表(幂等,可重复运行) - 测试插入的数据在测后自动清理,不污染数据库 """ import sys import os import uuid import pymysql import pytest from loguru import logger # 添加项目路径 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..')) from dataService.MySqlService import DatabaseConfig, MySQLDatabase, seed_is_exist, save_seed from dataService.dto.SeedInfo import SeedInfo CREATE_DATABASE_SQL = ( "CREATE DATABASE IF NOT EXISTS `LookingWeb` " "DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" ) CREATE_TABLE_SQL = """ CREATE TABLE IF NOT EXISTS `seeds_info` ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(255) DEFAULT NULL, seed_url VARCHAR(512) NOT NULL, have_download VARCHAR(16) DEFAULT NULL, create_time DATETIME DEFAULT NULL, update_time DATETIME DEFAULT NULL, url VARCHAR(512) DEFAULT NULL, PRIMARY KEY (id), KEY idx_seed_url (seed_url) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 """ # 本模块测试插入过的种子 URL,测后统一清理 _inserted_urls = [] def ensure_schema(): """幂等创建 LookingWeb 库和 seeds_info 表(真实数据库)""" # 第一步:不带库名连接,先创建数据库 conn = pymysql.connect( host=DatabaseConfig.HOST, port=DatabaseConfig.PORT, user=DatabaseConfig.USER, password=DatabaseConfig.PASSWORD, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) try: with conn.cursor() as cur: cur.execute(CREATE_DATABASE_SQL) conn.commit() logger.info("数据库就绪: {}(已确认存在)", DatabaseConfig.DB) finally: conn.close() # 第二步:连接 LookingWeb 库,创建 seeds_info 表 conn = pymysql.connect( host=DatabaseConfig.HOST, port=DatabaseConfig.PORT, user=DatabaseConfig.USER, password=DatabaseConfig.PASSWORD, db=DatabaseConfig.DB, charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) try: with conn.cursor() as cur: cur.execute(CREATE_TABLE_SQL) conn.commit() logger.info("数据表就绪: seeds_info") finally: conn.close() def make_test_seed(): """创建带唯一 seed_url 的真实 SeedInfo 对象,并登记以便测后清理""" url = f"magnet:?xt=urn:btih:{uuid.uuid4().hex}" _inserted_urls.append(url) return SeedInfo(name="测试种子", seedUrl=url, haveDownload="1", url=url) @pytest.fixture(scope="module", autouse=True) def db_schema(): """模块级:确保真实数据库和表存在""" ensure_schema() yield @pytest.fixture(autouse=True) def cleanup_inserted_seeds(): """每个测试后:清理本模块插入的种子行,保证测试可重复运行""" yield if not _inserted_urls: return with MySQLDatabase.create_connection() as db: for seed_url in _inserted_urls: db.execute("DELETE FROM seeds_info WHERE seed_url = %s", (seed_url,)) _inserted_urls.clear() class TestSeedIsExist: """使用真实数据库测试 seed_is_exist""" def setup_method(self): logger.remove() logger.add(sys.stderr, level="DEBUG") def test_seed_not_exists_returns_false(self): """数据库中不存在的种子 URL 应返回 False""" seed = make_test_seed() logger.info("测试种子不存在场景: {}", seed.seedUrl) result = seed_is_exist(seed) assert result is False def test_seed_exists_returns_true(self): """先通过真实的 save_seed 插入种子,seed_is_exist 应返回 True""" seed = make_test_seed() assert save_seed(seed) is True, "前置条件:save_seed 应成功插入种子" logger.info("测试种子已插入: {}", seed.seedUrl) result = seed_is_exist(seed) assert result is True def test_multiple_seeds_all_exist(self): """多个已存在种子都应被识别为存在""" seeds = [make_test_seed() for _ in range(3)] for seed in seeds: assert save_seed(seed) is True for seed in seeds: assert seed_is_exist(seed) is True, f"种子应已存在: {seed.seedUrl}" def test_seed_exists_after_delete_returns_false(self): """删除后的种子再查询应返回 False(完整的真实生命周期)""" from dataService.MySqlService import delete_seed seed = make_test_seed() assert save_seed(seed) is True assert seed_is_exist(seed) is True assert delete_seed(seed) is True, "前置条件:delete_seed 应成功删除种子" assert seed_is_exist(seed) is False def test_db_unreachable_returns_false(self, monkeypatch): """数据库不可达时(真实错误路径)应返回 False,而不是抛异常""" # 指向同主机一个已关闭的端口,模拟数据库不可达 monkeypatch.setattr(DatabaseConfig, "PORT", 3307) seed = make_test_seed() result = seed_is_exist(seed) assert result is False def run_tests(): """运行所有测试""" pytest.main([ __file__, "-v", "--tb=short", "--log-cli-level=INFO" ]) if __name__ == "__main__": run_tests()