diff --git a/frappe/commands/testing.py b/frappe/commands/testing.py index d1381671b2..a5ffaf0089 100644 --- a/frappe/commands/testing.py +++ b/frappe/commands/testing.py @@ -373,6 +373,7 @@ def run_tests( @click.option("--use-orchestrator", is_flag=True, help="Use orchestrator to run parallel tests") @click.option("--dry-run", is_flag=True, default=False, help="Dont actually run tests") @click.option("--lightmode", is_flag=True, default=False, help="Skips all before test setup") +@click.option("--failfast", is_flag=True, default=False, help="Exit on first failure occurred") @pass_context def run_parallel_tests( context: CliCtxObj, @@ -383,6 +384,7 @@ def run_parallel_tests( use_orchestrator=False, dry_run=False, lightmode=False, + failfast=False, ): from traceback_with_variables import activate_by_import @@ -404,6 +406,7 @@ def run_parallel_tests( total_builds=total_builds, dry_run=dry_run, lightmode=lightmode, + failfast=failfast, ) mode = "Orchestrator" if use_orchestrator else "Parallel" banner = f""" diff --git a/frappe/parallel_test_runner.py b/frappe/parallel_test_runner.py index 7f57e54618..d879241e33 100644 --- a/frappe/parallel_test_runner.py +++ b/frappe/parallel_test_runner.py @@ -29,13 +29,16 @@ TEST_WEIGHT_OVERRIDES = { class ParallelTestRunner: - def __init__(self, app, site, build_number=1, total_builds=1, dry_run=False, lightmode=False): + def __init__( + self, app, site, build_number=1, total_builds=1, dry_run=False, lightmode=False, failfast=False + ): self.app = app self.site = site self.build_number = frappe.utils.cint(build_number) or 1 self.total_builds = frappe.utils.cint(total_builds) self.dry_run = dry_run self.lightmode = lightmode + self.failfast = failfast self.test_file_list = [] self.total_test_weight = 0 self.test_result = None @@ -81,7 +84,9 @@ class ParallelTestRunner: self.total_test_weight = sum(self.get_test_weight(test) for test in self.test_file_list) def run_tests(self): - self.test_result = TestResult(stream=sys.stderr, descriptions=True, verbosity=2) + self.test_result = TestResult( + stream=sys.stderr, descriptions=True, verbosity=2, failfast=self.failfast + ) for test_file_info in self.test_file_list: self.run_tests_for_file(test_file_info) diff --git a/frappe/testing/result.py b/frappe/testing/result.py index e144291a2e..c530b4bbf1 100644 --- a/frappe/testing/result.py +++ b/frappe/testing/result.py @@ -29,8 +29,9 @@ logger = logging.getLogger(__name__) class TestResult(unittest.TextTestResult): - def __init__(self, stream, descriptions, verbosity): + def __init__(self, stream, descriptions, verbosity, failfast=False): super().__init__(stream, descriptions, verbosity) + self.failfast = failfast self._old_stdout = [] self._old_stderr = []