Coverage for run_tests.py: 0.00%

97 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2026-04-12 14:12 +0000

1#!/usr/bin/env python3 

2""" 

3Comprehensive test runner for the backend with different test categories and options. 

4""" 

5 

6import argparse 

7import os 

8import subprocess 

9import sys 

10from datetime import datetime 

11from pathlib import Path 

12 

13 

14def run_command(cmd, description=""): 

15 """Run a command and return the result.""" 

16 if description: 

17 pass 

18 

19 start_time = datetime.now() 

20 result = subprocess.run(cmd, capture_output=False, text=True) 

21 end_time = datetime.now() 

22 

23 (end_time - start_time).total_seconds() 

24 

25 return result.returncode == 0 

26 

27 

28def check_environment(): 

29 """Check if the testing environment is properly set up.""" 

30 

31 # Check if uv is available 

32 try: 

33 result = subprocess.run(["uv", "--version"], capture_output=True, text=True) 

34 if result.returncode != 0: 

35 return False 

36 except FileNotFoundError: 

37 return False 

38 

39 # Check if we're in the right directory 

40 if not Path("pyproject.toml").exists(): 

41 return False 

42 

43 # Check if tests directory exists 

44 if not Path("tests").exists(): 

45 return False 

46 

47 # Check environment variables 

48 supabase_url = os.getenv("SUPABASE_URL") 

49 if supabase_url: 

50 pass 

51 else: 

52 pass 

53 

54 return True 

55 

56 

57def main(): 

58 parser = argparse.ArgumentParser(description="Run backend tests with various options") 

59 parser.add_argument( 

60 "--category", 

61 choices=["unit", "integration", "contract", "e2e", "smoke", "slow", "all"], 

62 default="all", 

63 help="Test category to run", 

64 ) 

65 parser.add_argument("--coverage", action="store_true", help="Run with coverage") 

66 parser.add_argument("--html-coverage", action="store_true", help="Generate HTML coverage report") 

67 parser.add_argument("--xml-coverage", action="store_true", help="Generate XML coverage report") 

68 parser.add_argument("--json-coverage", action="store_true", help="Generate JSON coverage report") 

69 parser.add_argument("--fail-under", type=int, help="Fail if coverage is below this percentage") 

70 parser.add_argument("--verbose", "-v", action="store_true", help="Verbose output") 

71 parser.add_argument("--fail-fast", "-x", action="store_true", help="Stop on first failure") 

72 parser.add_argument("--parallel", action="store_true", help="Run tests in parallel") 

73 parser.add_argument("--file", help="Run specific test file") 

74 parser.add_argument("--function", help="Run specific test function") 

75 parser.add_argument("--dry-run", action="store_true", help="Show commands without running") 

76 

77 args = parser.parse_args() 

78 

79 # Check environment 

80 if not check_environment(): 

81 sys.exit(1) 

82 

83 # Build pytest command 

84 cmd = ["uv", "run", "pytest"] 

85 

86 # Per-category coverage thresholds (if not specified by user) 

87 coverage_thresholds = { 

88 "unit": 80, 

89 "integration": 70, 

90 "contract": 90, 

91 "e2e": 50, 

92 "smoke": 100, 

93 "all": 75, 

94 } 

95 

96 # Add test category markers 

97 if args.category == "unit": 

98 cmd.extend(["-m", "unit"]) 

99 elif args.category == "integration": 

100 cmd.extend(["-m", "integration"]) 

101 elif args.category == "contract": 

102 cmd.extend(["-m", "contract"]) 

103 elif args.category == "e2e": 

104 cmd.extend(["-m", "e2e"]) 

105 elif args.category == "smoke": 

106 cmd.extend(["-m", "smoke"]) 

107 elif args.category == "slow": 

108 cmd.extend(["-m", "slow"]) 

109 elif args.category == "all": 

110 # Run all tests 

111 pass 

112 

113 # Add coverage options 

114 if args.coverage or args.html_coverage or args.xml_coverage or args.json_coverage: 

115 cmd.extend(["--cov=."]) 

116 

117 if args.html_coverage: 

118 cmd.extend(["--cov-report=html"]) 

119 if args.xml_coverage: 

120 cmd.extend(["--cov-report=xml"]) 

121 if args.json_coverage: 

122 cmd.extend(["--cov-report=json"]) 

123 if not args.html_coverage and not args.xml_coverage and not args.json_coverage: 

124 cmd.extend(["--cov-report=term-missing"]) 

125 

126 # Add coverage threshold (use is not None to allow 0) 

127 fail_under = args.fail_under if args.fail_under is not None else coverage_thresholds.get(args.category, 75) 

128 cmd.extend(["--cov-fail-under", str(fail_under)]) 

129 

130 # Add verbose output 

131 if args.verbose: 

132 cmd.append("-v") 

133 

134 # Add fail fast 

135 if args.fail_fast: 

136 cmd.append("-x") 

137 

138 # Add parallel execution 

139 if args.parallel: 

140 cmd.extend(["-n", "auto"]) # Requires pytest-xdist 

141 

142 # Add specific file or function 

143 if args.file: 

144 if args.function: 

145 cmd.append(f"{args.file}::{args.function}") 

146 else: 

147 cmd.append(args.file) 

148 elif args.function: 

149 cmd.extend(["-k", args.function]) 

150 

151 # Show command if dry run 

152 if args.dry_run: 

153 return 

154 

155 # Run the tests 

156 description = f"pytest tests ({args.category} category)" 

157 if args.coverage or args.html_coverage or args.xml_coverage or args.json_coverage: 

158 fail_under = args.fail_under if args.fail_under is not None else coverage_thresholds.get(args.category, 75) 

159 description += f" with coverage (threshold: {fail_under}%)" 

160 

161 success = run_command(cmd, description) 

162 

163 # Generate additional reports 

164 if args.html_coverage: 

165 if success: 

166 pass 

167 else: 

168 pass 

169 

170 if args.xml_coverage: 

171 if success: 

172 pass 

173 else: 

174 pass 

175 

176 if args.json_coverage: 

177 if success: 

178 pass 

179 else: 

180 pass 

181 

182 # Exit with appropriate code 

183 sys.exit(0 if success else 1) 

184 

185 

186if __name__ == "__main__": 

187 main()