File size: 4,264 Bytes
4f0238f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
"""

Test runner for TouchGrass project.



This script runs all unit tests and generates a comprehensive test report.

"""

import subprocess
import sys
import argparse
from pathlib import Path
from datetime import datetime
import json


def run_tests(test_path: str = "tests", markers: str = None, verbose: bool = True,

              junit_xml: str = None, coverage: bool = False):
    """Run pytest with specified options."""

    cmd = ["pytest", test_path]

    if markers:
        cmd.extend(["-m", markers])

    if verbose:
        cmd.append("-v")

    if junit_xml:
        cmd.extend(["--junit-xml", junit_xml])

    if coverage:
        cmd.extend([
            "--cov=TouchGrass",
            "--cov-report=html",
            "--cov-report=term"
        ])

    # Add --tb=short for shorter tracebacks
    cmd.append("--tb=short")

    print(f"Running: {' '.join(cmd)}\n")

    result = subprocess.run(cmd)

    return result.returncode


def generate_test_report(output_dir: str = "test_reports"):
    """Generate a comprehensive test report."""
    output_dir = Path(output_dir)
    output_dir.mkdir(parents=True, exist_ok=True)

    report = {
        "timestamp": datetime.now().isoformat(),
        "summary": {},
        "details": []
    }

    # Run tests with JSON output
    json_output = output_dir / "test_results.json"
    cmd = [
        "pytest", "tests",
        "-v",
        "--tb=short",
        f"--junit-xml={output_dir / 'junit.xml'}",
        "--json-report",
        f"--json-report-file={json_output}"
    ]

    try:
        subprocess.run(cmd, check=False)
    except Exception as e:
        print(f"Warning: Could not generate JSON report: {e}")

    # Read JSON report if it exists
    if json_output.exists():
        with open(json_output, 'r') as f:
            try:
                results = json.load(f)
                report["summary"] = {
                    "total": results.get("summary", {}).get("total", 0),
                    "passed": results.get("summary", {}).get("passed", 0),
                    "failed": results.get("summary", {}).get("failed", 0),
                    "skipped": results.get("summary", {}).get("skipped", 0)
                }
            except json.JSONDecodeError:
                pass

    # Save report
    report_file = output_dir / "test_report.json"
    with open(report_file, 'w') as f:
        json.dump(report, f, indent=2)

    print(f"\n✓ Test report generated at {report_file}")

    return report


def main():
    parser = argparse.ArgumentParser(description="Run TouchGrass test suite")
    parser.add_argument("--tests", type=str, default="tests",
                       help="Test directory or specific test file")
    parser.add_argument("--markers", type=str, default=None,
                       help="Only run tests with specified markers (e.g., 'not slow')")
    parser.add_argument("--no-verbose", action="store_true",
                       help="Disable verbose output")
    parser.add_argument("--junit-xml", type=str, default=None,
                       help="Output JUnit XML report to specified file")
    parser.add_argument("--coverage", action="store_true",
                       help="Run with coverage reporting")
    parser.add_argument("--report-dir", type=str, default="test_reports",
                       help="Directory for test reports")
    parser.add_argument("--skip-report", action="store_true",
                       help="Skip generating test report")

    args = parser.parse_args()

    # Run tests
    exit_code = run_tests(
        test_path=args.tests,
        markers=args.markers,
        verbose=not args.no_verbose,
        junit_xml=args.junit_xml,
        coverage=args.coverage
    )

    # Generate report unless skipped
    if not args.skip_report:
        generate_test_report(args.report_dir)

    print("\n" + "=" * 60)
    if exit_code == 0:
        print("✓ All tests passed!")
    else:
        print(f"✗ Some tests failed (exit code: {exit_code})")
    print("=" * 60)

    return exit_code


if __name__ == "__main__":
    exit_code = main()
    sys.exit(exit_code)