|
|
#!/bin/bash
|
|
|
# ===================================
|
|
|
# A股/港股/美股 智能分析系统 - 测试脚本
|
|
|
# ===================================
|
|
|
#
|
|
|
# 使用方法:
|
|
|
# ./test.sh [测试场景]
|
|
|
#
|
|
|
# 测试场景:
|
|
|
# market - 仅大盘复盘
|
|
|
# a-stock - A股个股分析(茅台、平安银行)
|
|
|
# etf - etf分析(卫星etf 563230)
|
|
|
# hk-stock - 港股分析(腾讯、阿里)
|
|
|
# us-stock - 美股分析(苹果、特斯拉)
|
|
|
# mixed - 混合市场分析
|
|
|
# single - 单股模式测试
|
|
|
# dry-run - 仅获取数据不分析
|
|
|
# full - 完整流程测试
|
|
|
# quick - 快速测试(单只股票)
|
|
|
# all - 运行所有测试
|
|
|
#
|
|
|
# 示例:
|
|
|
# ./test.sh market # 测试大盘复盘
|
|
|
# ./test.sh us-stock # 测试美股分析
|
|
|
# ./test.sh quick # 快速测试
|
|
|
#
|
|
|
|
|
|
set -e
|
|
|
|
|
|
# 颜色定义
|
|
|
RED='\033[0;31m'
|
|
|
GREEN='\033[0;32m'
|
|
|
YELLOW='\033[1;33m'
|
|
|
BLUE='\033[0;34m'
|
|
|
NC='\033[0m' # No Color
|
|
|
|
|
|
# 打印带颜色的信息
|
|
|
info() {
|
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
|
}
|
|
|
|
|
|
success() {
|
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
|
}
|
|
|
|
|
|
warn() {
|
|
|
echo -e "${YELLOW}[WARN]${NC} $1"
|
|
|
}
|
|
|
|
|
|
error() {
|
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
|
}
|
|
|
|
|
|
header() {
|
|
|
echo ""
|
|
|
echo "=============================================="
|
|
|
echo -e "${GREEN}$1${NC}"
|
|
|
echo "=============================================="
|
|
|
echo ""
|
|
|
}
|
|
|
|
|
|
# 检查Python环境
|
|
|
check_python() {
|
|
|
if ! command -v python3 &> /dev/null; then
|
|
|
error "Python3 未安装"
|
|
|
exit 1
|
|
|
fi
|
|
|
info "Python版本: $(python3 --version)"
|
|
|
}
|
|
|
|
|
|
# 检查依赖
|
|
|
check_deps() {
|
|
|
info "检查依赖..."
|
|
|
python3 -c "import yfinance" 2>/dev/null || { warn "yfinance 未安装,美股测试可能失败"; }
|
|
|
python3 -c "import akshare" 2>/dev/null || { warn "akshare 未安装,A股/港股测试可能失败"; }
|
|
|
success "依赖检查完成"
|
|
|
}
|
|
|
|
|
|
# ==================== 测试场景 ====================
|
|
|
|
|
|
# 测试1: 大盘复盘
|
|
|
test_market() {
|
|
|
header "测试场景: 大盘复盘"
|
|
|
info "运行大盘复盘分析..."
|
|
|
python3 main.py --market-review "$@"
|
|
|
success "大盘复盘测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试2: A股分析
|
|
|
test_a_stock() {
|
|
|
header "测试场景: A股分析"
|
|
|
info "分析A股: 600519(茅台), 000001(平安银行)"
|
|
|
python3 main.py --stocks 600519,000001 --no-market-review "$@"
|
|
|
success "A股分析测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试2.5: ETF分析
|
|
|
test_etf() {
|
|
|
header "测试场景: ETF分析"
|
|
|
info "分析ETF: 563230(卫星ETF)"
|
|
|
python3 main.py --stocks 563230,512400 --no-market-review "$@"
|
|
|
success "ETF分析测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试3: 港股分析
|
|
|
test_hk_stock() {
|
|
|
header "测试场景: 港股分析"
|
|
|
info "分析港股: hk00700(腾讯), hk09988(阿里)"
|
|
|
python3 main.py --stocks hk00700,hk09988 --no-market-review "$@"
|
|
|
success "港股分析测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试4: 美股分析
|
|
|
test_us_stock() {
|
|
|
header "测试场景: 美股分析"
|
|
|
info "分析美股: AAPL(苹果), TSLA(特斯拉)"
|
|
|
# 允许透传参数,默认不带 --no-notify
|
|
|
python3 main.py --stocks AAPL --no-market-review "$@"
|
|
|
success "美股分析测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试5: 混合市场
|
|
|
test_mixed() {
|
|
|
header "测试场景: 混合市场分析"
|
|
|
info "分析混合市场: 600519(A股), hk00700(港股), AAPL(美股)"
|
|
|
python3 main.py --stocks 600519,hk00700,AAPL --no-market-review
|
|
|
success "混合市场测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试6: 单股推送模式
|
|
|
test_single() {
|
|
|
header "测试场景: 单股推送模式"
|
|
|
info "测试单股推送模式..."
|
|
|
python3 main.py --stocks 600519 --single-notify --no-market-review
|
|
|
success "单股推送模式测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试7: dry-run模式
|
|
|
test_dry_run() {
|
|
|
header "测试场景: Dry-Run 模式"
|
|
|
info "仅获取数据,不进行AI分析..."
|
|
|
python3 main.py --stocks 600519,AAPL --dry-run --no-notify
|
|
|
success "Dry-Run 测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试8: 完整流程
|
|
|
test_full() {
|
|
|
header "测试场景: 完整流程"
|
|
|
info "运行完整分析流程(个股+大盘)..."
|
|
|
python3 main.py --stocks 600519 --no-notify
|
|
|
success "完整流程测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试9: 快速测试
|
|
|
test_quick() {
|
|
|
header "测试场景: 快速测试"
|
|
|
info "单只股票快速测试..."
|
|
|
python3 main.py --stocks 600519 --no-market-review
|
|
|
success "快速测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试10: 代码识别测试
|
|
|
test_code_recognition() {
|
|
|
header "测试场景: 代码识别"
|
|
|
info "测试股票代码识别逻辑..."
|
|
|
|
|
|
python3 << 'PYTEST'
|
|
|
import sys
|
|
|
sys.path.insert(0, '.')
|
|
|
from data_provider.akshare_fetcher import _is_hk_code, _is_us_code
|
|
|
|
|
|
test_cases = [
|
|
|
# (代码, 预期HK, 预期US, 描述)
|
|
|
("AAPL", False, True, "美股-苹果"),
|
|
|
("TSLA", False, True, "美股-特斯拉"),
|
|
|
("BRK.B", False, True, "美股-伯克希尔B"),
|
|
|
("hk00700", True, False, "港股-腾讯"),
|
|
|
("HK09988", True, False, "港股-阿里"),
|
|
|
("600519", False, False, "A股-茅台"),
|
|
|
("000001", False, False, "A股-平安"),
|
|
|
]
|
|
|
|
|
|
print("\n股票代码识别测试:")
|
|
|
print("-" * 60)
|
|
|
all_pass = True
|
|
|
for code, exp_hk, exp_us, desc in test_cases:
|
|
|
is_hk = _is_hk_code(code)
|
|
|
is_us = _is_us_code(code)
|
|
|
hk_ok = is_hk == exp_hk
|
|
|
us_ok = is_us == exp_us
|
|
|
status = "✅" if (hk_ok and us_ok) else "❌"
|
|
|
all_pass = all_pass and hk_ok and us_ok
|
|
|
print(f"{status} {code:10} | HK:{is_hk:5} US:{is_us:5} | {desc}")
|
|
|
|
|
|
print("-" * 60)
|
|
|
print(f"{'✅ 所有测试通过!' if all_pass else '❌ 有测试失败!'}")
|
|
|
sys.exit(0 if all_pass else 1)
|
|
|
PYTEST
|
|
|
|
|
|
success "代码识别测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试11: YFinance代码转换测试
|
|
|
test_yfinance_convert() {
|
|
|
header "测试场景: YFinance 代码转换"
|
|
|
info "测试YFinance代码转换逻辑..."
|
|
|
|
|
|
python3 << 'PYTEST'
|
|
|
import sys
|
|
|
sys.path.insert(0, '.')
|
|
|
from data_provider.yfinance_fetcher import YfinanceFetcher
|
|
|
|
|
|
fetcher = YfinanceFetcher()
|
|
|
|
|
|
test_cases = [
|
|
|
("AAPL", "AAPL", "美股"),
|
|
|
("tsla", "TSLA", "美股小写"),
|
|
|
("BRK.B", "BRK.B", "美股特殊"),
|
|
|
("hk00700", "0700.HK", "港股"),
|
|
|
("HK09988", "9988.HK", "港股大写"),
|
|
|
("600519", "600519.SS", "A股沪市"),
|
|
|
("000001", "000001.SZ", "A股深市"),
|
|
|
("300750", "300750.SZ", "A股创业板"),
|
|
|
]
|
|
|
|
|
|
print("\nYFinance 代码转换测试:")
|
|
|
print("-" * 60)
|
|
|
all_pass = True
|
|
|
for input_code, expected, desc in test_cases:
|
|
|
result = fetcher._convert_stock_code(input_code)
|
|
|
status = "✅" if result == expected else "❌"
|
|
|
all_pass = all_pass and (result == expected)
|
|
|
print(f"{status} {input_code:10} -> {result:12} (期望: {expected:12}) | {desc}")
|
|
|
|
|
|
print("-" * 60)
|
|
|
print(f"{'✅ 所有测试通过!' if all_pass else '❌ 有测试失败!'}")
|
|
|
sys.exit(0 if all_pass else 1)
|
|
|
PYTEST
|
|
|
|
|
|
success "YFinance 代码转换测试完成"
|
|
|
}
|
|
|
|
|
|
# 测试12: 语法检查
|
|
|
test_syntax() {
|
|
|
header "测试场景: Python 语法检查"
|
|
|
info "检查所有Python文件语法..."
|
|
|
|
|
|
python3 -m py_compile main.py src/config.py src/notification.py \
|
|
|
data_provider/akshare_fetcher.py \
|
|
|
data_provider/yfinance_fetcher.py \
|
|
|
bot/commands/analyze.py
|
|
|
|
|
|
success "语法检查通过"
|
|
|
}
|
|
|
|
|
|
# 测试13: Flake8 静态检查
|
|
|
test_flake8() {
|
|
|
header "测试场景: Flake8 静态检查"
|
|
|
info "运行 Flake8 检查严重错误..."
|
|
|
|
|
|
if command -v flake8 &> /dev/null; then
|
|
|
flake8 main.py src/config.py src/notification.py --select=F821,E999 --max-line-length=120
|
|
|
success "Flake8 检查通过"
|
|
|
else
|
|
|
warn "Flake8 未安装,跳过检查"
|
|
|
fi
|
|
|
}
|
|
|
|
|
|
# 运行所有测试
|
|
|
test_all() {
|
|
|
header "运行所有测试"
|
|
|
|
|
|
test_syntax
|
|
|
test_code_recognition
|
|
|
test_yfinance_convert
|
|
|
test_flake8
|
|
|
|
|
|
echo ""
|
|
|
info "以下测试需要网络和API配置,可能会失败:"
|
|
|
echo ""
|
|
|
|
|
|
test_dry_run || warn "Dry-Run 测试失败(可能是网络问题)"
|
|
|
test_quick || warn "快速测试失败(可能是API问题)"
|
|
|
|
|
|
success "所有测试完成!"
|
|
|
}
|
|
|
|
|
|
# ==================== 主程序 ====================
|
|
|
|
|
|
main() {
|
|
|
header "A股/港股/美股 智能分析系统 - 测试"
|
|
|
|
|
|
check_python
|
|
|
check_deps
|
|
|
|
|
|
case "${1:-help}" in
|
|
|
market)
|
|
|
shift
|
|
|
test_market "$@"
|
|
|
;;
|
|
|
a-stock|a_stock|astock)
|
|
|
shift
|
|
|
test_a_stock "$@"
|
|
|
;;
|
|
|
etf)
|
|
|
shift
|
|
|
test_etf "$@"
|
|
|
;;
|
|
|
hk-stock|hk_stock|hkstock|hk)
|
|
|
shift
|
|
|
test_hk_stock "$@"
|
|
|
;;
|
|
|
us-stock|us_stock|usstock|us)
|
|
|
shift
|
|
|
test_us_stock "$@"
|
|
|
;;
|
|
|
mixed|mix)
|
|
|
shift
|
|
|
test_mixed "$@"
|
|
|
;;
|
|
|
single)
|
|
|
shift
|
|
|
test_single "$@"
|
|
|
;;
|
|
|
dry-run|dryrun|dry)
|
|
|
shift
|
|
|
test_dry_run "$@"
|
|
|
;;
|
|
|
full)
|
|
|
shift
|
|
|
test_full "$@"
|
|
|
;;
|
|
|
quick|q)
|
|
|
shift
|
|
|
test_quick "$@"
|
|
|
;;
|
|
|
code|recognition)
|
|
|
shift
|
|
|
test_code_recognition "$@"
|
|
|
;;
|
|
|
yfinance|yf)
|
|
|
shift
|
|
|
test_yfinance_convert "$@"
|
|
|
;;
|
|
|
syntax)
|
|
|
shift
|
|
|
test_syntax "$@"
|
|
|
;;
|
|
|
flake8|lint)
|
|
|
shift
|
|
|
test_flake8 "$@"
|
|
|
;;
|
|
|
all)
|
|
|
shift
|
|
|
test_all "$@"
|
|
|
;;
|
|
|
help|--help|-h|*)
|
|
|
echo "使用方法: $0 [测试场景]"
|
|
|
echo ""
|
|
|
echo "测试场景:"
|
|
|
echo " market - 仅大盘复盘"
|
|
|
echo " a-stock - A股个股分析"
|
|
|
echo " etf - ETF分析"
|
|
|
echo " hk-stock - 港股分析"
|
|
|
echo " us-stock - 美股分析"
|
|
|
echo " mixed - 混合市场分析"
|
|
|
echo " single - 单股推送模式"
|
|
|
echo " dry-run - 仅获取数据"
|
|
|
echo " full - 完整流程"
|
|
|
echo " quick - 快速测试(推荐)"
|
|
|
echo " code - 代码识别测试"
|
|
|
echo " yfinance - YFinance转换测试"
|
|
|
echo " syntax - 语法检查"
|
|
|
echo " flake8 - 静态检查"
|
|
|
echo " all - 运行所有测试"
|
|
|
echo ""
|
|
|
echo "示例:"
|
|
|
echo " $0 quick # 快速测试"
|
|
|
echo " $0 us-stock # 测试美股"
|
|
|
echo " $0 code # 测试代码识别"
|
|
|
echo " $0 all # 运行所有测试"
|
|
|
;;
|
|
|
esac
|
|
|
}
|
|
|
|
|
|
main "$@"
|