Files
qmt_bridge/reference/xtquant_big_convert/run_all_tests.py
T

109 lines
4.1 KiB
Python

# coding: utf-8
"""Run the full test suite from a single entry point.
Groups tests by area and prints a clear per-group + total report. Optional
live/API tests (need a running QMT + redis) are skipped by default.
Usage:
python run_all_tests.py # all offline tests (default)
python run_all_tests.py -v # verbose
python run_all_tests.py --live # also run live RPC tests (needs QMT running)
python run_all_tests.py --group signal_trader # only one group
python run_all_tests.py --group backtest
"""
import argparse
import os
import subprocess
import sys
import time
ROOT = os.path.dirname(os.path.abspath(__file__))
SRC = os.path.join(ROOT, "src")
# Test groups: (name, paths, requires_live)
GROUPS = [
("signal_trader", [os.path.join("tests", "bigqmt_signal_trader")], False),
("backtest", [os.path.join("tests", "bigqmt_backtest")], False),
]
LIVE_GROUP = ("live_api", ["test_all_apis.py"], True)
def run_group(name, paths, verbose):
"""Run a pytest group, return (passed, failed, skipped, seconds)."""
cmd = [sys.executable, "-m", "pytest"] + paths + ["-q" if not verbose else "-v"]
t0 = time.time()
proc = subprocess.run(cmd, cwd=ROOT, capture_output=True, text=True)
elapsed = time.time() - t0
out = (proc.stdout or "") + (proc.stderr or "")
# Parse pytest summary like "290 passed in 8.5s" / "1 failed, 289 passed, 3 skipped"
passed = failed = skipped = 0
for line in out.splitlines():
line = line.strip()
if not any(tok in line for tok in ("passed", "failed", "skipped", "error")):
continue
for part in line.split(","):
words = part.strip().split()
if len(words) >= 2 and words[0].isdigit():
num = int(words[0])
if words[1].startswith("passed"):
passed += num
elif words[1].startswith("failed") or words[1].startswith("error"):
failed += num
elif words[1].startswith("skipped"):
skipped += num
return passed, failed, skipped, elapsed, out, proc.returncode
def main():
parser = argparse.ArgumentParser(description="Run all bigqmt tests")
parser.add_argument("-v", "--verbose", action="store_true")
parser.add_argument("--live", action="store_true", help="also run live RPC tests (needs QMT)")
parser.add_argument("--group", help="run only this group (signal_trader/backtest/live_api)")
args = parser.parse_args()
groups = list(GROUPS)
if args.live:
groups.append(LIVE_GROUP)
if args.group:
groups = [g for g in groups if g[0] == args.group]
if not groups:
print("Unknown group: %s (available: %s)" % (args.group, ", ".join(g[0] for g in GROUPS + [LIVE_GROUP])))
return 1
print("=" * 70)
print("Big QMT Bridge - 全量测试")
print("=" * 70)
total_passed = total_failed = total_skipped = 0
total_time = 0.0
failed_groups = []
for name, paths, needs_live in groups:
print("\n--- %s ---" % name)
passed, failed, skipped, elapsed, out, rc = run_group(name, paths, args.verbose)
total_passed += passed
total_failed += failed
total_skipped += skipped
total_time += elapsed
status = "PASS" if failed == 0 and rc == 0 else "FAIL"
print(" %s: %d passed, %d failed, %d skipped (%.1fs)" % (status, passed, failed, skipped, elapsed))
if failed or rc != 0:
failed_groups.append(name)
if not args.verbose:
# print the failing part of the output for visibility
tail = "\n".join(out.splitlines()[-20:])
print(tail)
print("\n" + "=" * 70)
print("=== 汇总 ===")
print("通过 %d / 失败 %d / 跳过 %d / 总计 %d" % (total_passed, total_failed, total_skipped, total_passed + total_failed + total_skipped))
print("总耗时 %.1fs" % total_time)
if failed_groups:
print("失败分组: %s" % ", ".join(failed_groups))
return 1
print("全部通过 ✅")
return 0
if __name__ == "__main__":
sys.exit(main())