Build pytest command with appropriate options.
(self, args: argparse.Namespace)
| 110 | return list(set(test_files)) # Remove duplicates |
| 111 | |
| 112 | def build_pytest_command(self, args: argparse.Namespace) -> List[str]: |
| 113 | """Build pytest command with appropriate options.""" |
| 114 | cmd = [self.detect_pytest_binary()] |
| 115 | |
| 116 | # Test selection |
| 117 | if args.fast: |
| 118 | cmd.extend(["-m", "not gui and not slow"]) |
| 119 | elif args.gui_only: |
| 120 | cmd.extend(["-m", "gui"]) |
| 121 | elif args.unit_only: |
| 122 | cmd.extend(["-m", "unit"]) |
| 123 | elif args.changed: |
| 124 | changed_files = self.get_changed_files() |
| 125 | test_files = self.map_files_to_tests(changed_files) |
| 126 | if test_files: |
| 127 | cmd.extend(test_files) |
| 128 | else: |
| 129 | print("No test files found for changed source files, running all tests") |
| 130 | |
| 131 | # Parallel execution |
| 132 | if not args.no_parallel: |
| 133 | workers = args.workers if args.workers else "auto" |
| 134 | cmd.extend(["-n", str(workers)]) |
| 135 | |
| 136 | # Coverage |
| 137 | if args.coverage: |
| 138 | cmd.extend(["--cov=src", "--cov-report=term-missing", "--cov-report=json"]) |
| 139 | |
| 140 | # Output format |
| 141 | if args.verbose: |
| 142 | cmd.append("-v") |
| 143 | else: |
| 144 | cmd.append("-q") |
| 145 | |
| 146 | # Performance tracking |
| 147 | cmd.extend(["--durations=10"]) |
| 148 | |
| 149 | # Timeout (enforce 10-second rule from CLAUDE.md) |
| 150 | cmd.extend(["--timeout=10"]) |
| 151 | |
| 152 | # JSON output for parsing |
| 153 | cmd.extend(["--json-report", "--json-report-file=test_results.json"]) |
| 154 | |
| 155 | return cmd |
| 156 | |
| 157 | def run_tests(self, args: argparse.Namespace) -> TestSuiteReport: |
| 158 | """Execute tests and collect results.""" |
no test coverage detected