| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- """
- MCP 服务器测试模块
- 测试内容:
- 1. 格式编码工具(纯函数测试,零依赖)
- 2. MCP 服务器集成测试(需要数据库连接)
- 运行方式:
- cd SmartBizTrip
- python -m tests.test_mcp_servers
- """
- import unittest
- import json
- import sys
- import os
- from datetime import date, datetime, timedelta
- from decimal import Decimal
- # 确保能导入 SmartBizTrip 模块
- sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
- # ==================== 1. 格式编码工具测试(纯函数,零依赖) ====================
- class TestFormatEncoder(unittest.TestCase):
- """测试 default_encoder 函数和 DateEncoder 类"""
- def setUp(self):
- from utils.format import default_encoder, DateEncoder
- self.default_encoder_func = default_encoder
- self.date_encoder_cls = DateEncoder
- def test_encode_datetime(self):
- """测试 datetime 编码"""
- dt = datetime(2025, 7, 30, 14, 30, 0)
- result = self.default_encoder_func(dt)
- self.assertEqual(result, '2025-07-30 14:30:00')
- def test_encode_date(self):
- """测试 date 编码"""
- d = date(2025, 7, 30)
- result = self.default_encoder_func(d)
- self.assertEqual(result, '2025-07-30')
- def test_encode_timedelta(self):
- """测试 timedelta 编码"""
- td = timedelta(hours=5, minutes=30)
- result = self.default_encoder_func(td)
- self.assertEqual(result, '5:30:00')
- def test_encode_decimal(self):
- """测试 Decimal 编码"""
- dec = Decimal('123.45')
- result = self.default_encoder_func(dec)
- self.assertIsInstance(result, float)
- self.assertAlmostEqual(result, 123.45)
- def test_encode_unknown(self):
- """测试未知类型原样返回"""
- obj = "hello"
- result = self.default_encoder_func(obj)
- self.assertEqual(result, "hello")
- def test_date_encoder_json_dumps(self):
- """测试 DateEncoder 类与 json.dumps 配合使用"""
- data = {
- "date": date(2025, 7, 30),
- "datetime": datetime(2025, 7, 30, 14, 30, 0),
- "value": Decimal('99.99')
- }
- result = json.dumps(data, cls=self.date_encoder_cls)
- parsed = json.loads(result)
- self.assertEqual(parsed["date"], "2025-07-30")
- self.assertEqual(parsed["datetime"], "2025-07-30 14:30:00")
- self.assertEqual(parsed["value"], 99.99)
- # ==================== 2. MCP 服务器集成测试(需要数据库) ====================
- @unittest.skipUnless(os.getenv("RUN_ONLINE_TESTS") == "1", "需要数据库;设置 RUN_ONLINE_TESTS=1 后运行")
- class TestWeatherMCPIntegration(unittest.TestCase):
- """集成测试:天气 MCP 服务器"""
- @classmethod
- def setUpClass(cls):
- from mcp_server.mcp_weather_server import WeatherService
- cls.service = WeatherService()
- def test_query_weather_single_day(self):
- """使用 insert_may01_data.sql 中的成都天气样例。"""
- result = self.service.query_weather("成都", "2026-05-01", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- first = parsed["data"][0]
- self.assertEqual(first["city"], "成都")
- self.assertEqual(first["fx_date"], "2026-05-01")
- self.assertEqual(first["temp_max"], 28)
- self.assertEqual(first["temp_min"], 18)
- def test_query_weather_date_range(self):
- """范围查询只返回已有日期的数据,不会补造缺失日期。"""
- result = self.service.query_weather("成都", "2026-04-29", "2026-05-03")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertEqual([day["fx_date"] for day in parsed["data"]], ["2026-05-01"])
- for day in parsed["data"]:
- self.assertEqual(day["city"], "成都")
- self.assertGreaterEqual(day["fx_date"], "2026-04-29")
- self.assertLessEqual(day["fx_date"], "2026-05-03")
- # 同一城市,排除样例日期后应返回无数据。
- outside = self.service.query_weather("成都", "2026-05-02", "2026-05-03")
- self.assertEqual(json.loads(outside)["status"], "no_data")
- def test_query_weather_chengdu(self):
- """测试成都天气查询"""
- result = self.service.query_weather("成都", "2026-05-01", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- self.assertEqual(parsed["data"][0]["city"], "成都")
- def test_query_weather_no_data(self):
- """测试无数据情况"""
- result = self.service.query_weather("火星", "2026-05-01", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "no_data")
- # def test_weather_mcp_server_config(self):
- # """验证天气 MCP 服务器配置"""
- # from mcp_server.mcp_weather_server import create_weather_mcp_server
- # server = create_weather_mcp_server()
- # self.assertEqual(server.name, "WeatherTools")
- @unittest.skipUnless(os.getenv("RUN_ONLINE_TESTS") == "1", "需要数据库;设置 RUN_ONLINE_TESTS=1 后运行")
- class TestTicketMCPIntegration(unittest.TestCase):
- """集成测试:票务 MCP 服务器"""
- @classmethod
- def setUpClass(cls):
- from mcp_server.mcp_ticket_server import TicketService
- cls.service = TicketService()
- def test_query_train(self):
- """测试高铁票查询——北京到成都 2026-05-01"""
- result = self.service.query_train("北京", "成都", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- first = parsed["data"][0]
- self.assertEqual(first["departure_city"], "北京")
- self.assertEqual(first["arrival_city"], "成都")
- self.assertIn("train_number", first)
- def test_query_train_with_seat(self):
- """测试带座位类型的高铁票查询——北京到成都 二等座"""
- result = self.service.query_train("北京", "成都", "2026-05-01", "二等座")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- for item in parsed["data"]:
- self.assertEqual(item["seat_type"], "二等座")
- def test_query_train_no_data(self):
- """测试无数据情况——北京到上海无数据"""
- result = self.service.query_train("北京", "上海", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "no_data")
- def test_query_flight(self):
- """测试航班查询——北京到成都 2026-05-01"""
- result = self.service.query_flight("北京", "成都", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- first = parsed["data"][0]
- self.assertEqual(first["departure_city"], "北京")
- self.assertEqual(first["arrival_city"], "成都")
- def test_query_flight_with_cabin(self):
- """测试带舱位类型的航班查询——头等舱"""
- result = self.service.query_flight("北京", "成都", "2026-05-01", "头等舱")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- for item in parsed["data"]:
- self.assertEqual(item["cabin_type"], "头等舱")
- def test_query_event(self):
- """测试会展门票查询——成都企业数字化转型峰会 成都 2026-05-01"""
- result = self.service.query_event("成都", "成都企业数字化转型峰会", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- first = parsed["data"][0]
- self.assertEqual(first["event_name"], "成都企业数字化转型峰会")
- self.assertEqual(first["city"], "成都")
- self.assertEqual(first["venue"], "成都世纪城新国际会展中心")
- def test_query_event_dengzaiqi(self):
- """测试会展门票查询——西部智能制造大会 成都"""
- result = self.service.query_event("成都", "西部智能制造大会", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- self.assertEqual(parsed["data"][0]["venue"], "中国西部国际博览城")
- def test_query_event_no_data(self):
- """测试无数据情况——不存在的活动名称"""
- result = self.service.query_event("成都", "不存在的企业峰会", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "no_data")
- # def test_ticket_mcp_server_config(self):
- # """验证票务 MCP 服务器配置"""
- # from mcp_server.mcp_ticket_server import create_ticket_mcp_server
- # server = create_ticket_mcp_server()
- # self.assertEqual(server.name, "TicketTools")
- @unittest.skipUnless(os.getenv("RUN_ONLINE_TESTS") == "1", "需要数据库;设置 RUN_ONLINE_TESTS=1 后运行")
- class TestTripMCPIntegration(unittest.TestCase):
- """集成测试:差旅 MCP 服务器"""
- @classmethod
- def setUpClass(cls):
- from mcp_server.mcp_trip_server import TripService
- cls.service = TripService()
- def test_query_car_rental(self):
- """测试商务用车查询——成都 2026-05-01"""
- result = self.service.query_car_rental("成都", "成都", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- first = parsed["data"][0]
- self.assertEqual(first["pickup_city"], "成都")
- self.assertEqual(first["return_city"], "成都")
- def test_query_car_rental_with_type(self):
- """测试带车型的商务用车查询——SUV"""
- result = self.service.query_car_rental("成都", "成都", "2026-05-01", "SUV")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- for item in parsed["data"]:
- self.assertEqual(item["car_type"], "SUV")
- def test_query_car_rental_no_data(self):
- """测试无数据情况——北京无商务用车数据"""
- result = self.service.query_car_rental("北京", "北京", "2026-05-01")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "no_data")
- def test_query_insurance(self):
- """测试保险查询(全部)"""
- result = self.service.query_insurance()
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- def test_query_insurance_with_type(self):
- """测试带类型的保险查询——综合型"""
- result = self.service.query_insurance("综合型")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- for item in parsed["data"]:
- self.assertEqual(item["insurance_type"], "综合型")
- def test_query_insurance_jingwai(self):
- """测试境外型保险查询"""
- result = self.service.query_insurance("境外型")
- parsed = json.loads(result)
- self.assertEqual(parsed["status"], "success")
- self.assertGreater(len(parsed["data"]), 0)
- for item in parsed["data"]:
- self.assertEqual(item["insurance_type"], "境外型")
- # def test_trip_mcp_server_config(self):
- # """验证差旅 MCP 服务器配置"""
- # from mcp_server.mcp_trip_server import create_trip_mcp_server
- # server = create_trip_mcp_server()
- # self.assertEqual(server.name, "TripTools")
- if __name__ == "__main__":
- unittest.main(verbosity=2)
|