(self, runtests: RunTests)
| 394 | return result |
| 395 | |
| 396 | def run_tests_sequentially(self, runtests: RunTests) -> None: |
| 397 | if self.coverage: |
| 398 | tracer = trace.Trace(trace=False, count=True) |
| 399 | else: |
| 400 | tracer = None |
| 401 | |
| 402 | save_modules = set(sys.modules) |
| 403 | |
| 404 | jobs = runtests.get_jobs() |
| 405 | if jobs is not None: |
| 406 | tests = count(jobs, 'test') |
| 407 | else: |
| 408 | tests = 'tests' |
| 409 | msg = f"Run {tests} sequentially in a single process" |
| 410 | if runtests.timeout: |
| 411 | msg += " (timeout: %s)" % format_duration(runtests.timeout) |
| 412 | self.log(msg) |
| 413 | |
| 414 | tests_iter = runtests.iter_tests() |
| 415 | for test_index, test_name in enumerate(tests_iter, 1): |
| 416 | start_time = time.perf_counter() |
| 417 | |
| 418 | self.logger.display_progress(test_index, test_name) |
| 419 | |
| 420 | result = self.run_test(test_name, runtests, tracer) |
| 421 | |
| 422 | # Unload the newly imported test modules (best effort finalization) |
| 423 | new_modules = [module for module in sys.modules |
| 424 | if module not in save_modules and |
| 425 | module.startswith(("test.", "test_"))] |
| 426 | for module in new_modules: |
| 427 | sys.modules.pop(module, None) |
| 428 | # Remove the attribute of the parent module. |
| 429 | parent, _, name = module.rpartition('.') |
| 430 | try: |
| 431 | delattr(sys.modules[parent], name) |
| 432 | except (KeyError, AttributeError): |
| 433 | pass |
| 434 | |
| 435 | text = str(result) |
| 436 | test_time = time.perf_counter() - start_time |
| 437 | if test_time >= PROGRESS_MIN_TIME: |
| 438 | text = f"{text} in {format_duration(test_time)}" |
| 439 | self.logger.display_progress(test_index, text) |
| 440 | |
| 441 | if result.must_stop(self.fail_fast, self.fail_env_changed): |
| 442 | break |
| 443 | |
| 444 | def get_state(self) -> str: |
| 445 | state = self.results.get_state(self.fail_env_changed) |
no test coverage detected