def test_loader_should_raise_if_location_to_load_not_exists(mocker): """The Loader should raise an Exception if a location does not exist which should be loaded""" # given non_existant_location = mocker.MagicMock() non_existant_location.exists.return_value = False locations = [mocker.MagicMock(), non_existant_location] # then with pytest.raises(RadishError): # when load_modules(locations)
def cli(**kwargs): """radish - The root from red to green. BDD tooling for Python. radish-test can be used to perform tests for the Steps implemented in a radish base directory. Use the `MATCHER_CONFIGS` to pass configuration files containing the Step matchers. """ config = Config(kwargs) # turn of ANSI colors if requested if config.no_ansi: cf.disable() logger.debug("Basedirs: %s", ", ".join(str(d) for d in config.basedirs)) logger.debug("Loading all modules from the basedirs") loaded_modules = loader.load_modules(config.basedirs) logger.debug( "Loaded %d modules from the basedirs: %s", len(loaded_modules), ", ".join(str(m) for m in loaded_modules), ) logger.debug("Matcher configs: %s", ", ".join(str(m) for m in config.matcher_configs)) coverage_config = CoverageConfig(config.show_missing, config.show_missing_templates) run_matcher_tests(config.matcher_configs, coverage_config, step_registry)
def test_loader_should_load_python_module_in_location(mocker): """The Loader should attempt to load Python module within a location""" # given load_module_mock = mocker.patch("radish.loader.load_module") module_mock = mocker.MagicMock(name="Python Module") location = mocker.MagicMock() location.glob.return_value = [module_mock] # when loaded_locations = load_modules([location]) # then load_module_mock.assert_called_once_with(module_mock) assert loaded_locations == [module_mock]
def test_step_matches_configs(match_config_files, basedirs, cover_min_percentage=None, cover_show_missing=False): """ Test if the given match config files matches the actual matched step implementations. """ if cover_min_percentage is not None and float(cover_min_percentage) > 100: sys.stderr.write( str( colorful.magenta( 'You are a little cocky to think you can reach a minimum coverage of {0:.2f}%\n' .format(float(cover_min_percentage))))) return 3 # load user's custom python files for basedir in basedirs: load_modules(basedir) steps = StepRegistry().steps if not steps: sys.stderr.write( str( colorful.magenta( 'No step implementations found in {0}, thus doesn\'t make sense to continue' .format(basedirs)))) return 4 failed = 0 passed = 0 covered_steps = set() for match_config_file in match_config_files: # load the given match config file with codecs.open(match_config_file, "r", "utf-8") as f: match_config = yaml.safe_load(f) if not match_config: print( colorful.magenta( 'No sentences found in {0} to test against'.format( match_config_file))) return 5 print( colorful.yellow('Testing sentences from {0}:'.format( colorful.bold_yellow(match_config_file)))) failed_sentences, passed_senteces = test_step_matches( match_config, steps) failed += failed_sentences passed += passed_senteces covered_steps = covered_steps.union(x['should_match'] for x in match_config if 'should_match' in x) # newline sys.stdout.write('\n') report = colorful.bold_white('{0} sentences ('.format(failed + passed)) if passed > 0: report += colorful.bold_green('{0} passed'.format(passed)) if passed > 0 and failed > 0: report += colorful.bold_white(', ') if failed > 0: report += colorful.bold_red('{0} failed'.format(failed)) report += colorful.bold_white(')') print(report) step_coverage = 100.0 / len(steps) * len(covered_steps) coverage_report = colorful.bold_white( 'Covered {0} of {1} step implementations'.format( len(covered_steps), len(steps))) ret = 0 if failed == 0 else 1 if cover_min_percentage: coverage_color = colorful.bold_green if step_coverage >= float( cover_min_percentage) else colorful.bold_red coverage_report += colorful.bold_white(' (coverage: ') coverage_report += coverage_color('{0:.2f}%'.format(step_coverage)) if float(cover_min_percentage) > step_coverage: coverage_report += colorful.bold_white( ', expected a minimum of {0}'.format( colorful.bold_green(cover_min_percentage + '%'))) if failed == 0: ret = 2 # if tests have passed and coverage is too low we fail with exit code 2 coverage_report += colorful.bold_white(')') print(coverage_report) if cover_show_missing: missing_steps = get_missing_steps(steps, covered_steps) if missing_steps: missing_step_report = colorful.bold_yellow('Missing steps:\n') for step in missing_steps: missing_step_report += '- {0} at '.format( colorful.cyan(step[0])) missing_step_report += colorful.cyan(step[1]) + '\n' sys.stdout.write(missing_step_report) return ret
def test_step_matches_configs( match_config_files, basedirs, cover_min_percentage=None, cover_show_missing=False ): """ Test if the given match config files matches the actual matched step implementations. """ if cover_min_percentage is not None and float(cover_min_percentage) > 100: sys.stderr.write( str( colorful.magenta( "You are a little cocky to think you can reach a minimum coverage of {0:.2f}%\n".format( float(cover_min_percentage) ) ) ) ) return 3 # load user's custom python files for basedir in basedirs: load_modules(basedir) steps = StepRegistry().steps if not steps: sys.stderr.write( str( colorful.magenta( "No step implementations found in {0}, thus doesn't make sense to continue".format( basedirs ) ) ) ) return 4 failed = 0 passed = 0 covered_steps = set() for match_config_file in match_config_files: # load the given match config file with codecs.open(match_config_file, "r", "utf-8") as f: match_config = yaml.safe_load(f) if not match_config: print( colorful.magenta( "No sentences found in {0} to test against".format( match_config_file ) ) ) return 5 print( colorful.yellow( "Testing sentences from {0}:".format( colorful.bold_yellow(match_config_file) ) ) ) failed_sentences, passed_senteces = test_step_matches(match_config, steps) failed += failed_sentences passed += passed_senteces covered_steps = covered_steps.union( x["should_match"] for x in match_config if "should_match" in x ) # newline sys.stdout.write("\n") report = colorful.bold_white("{0} sentences (".format(failed + passed)) if passed > 0: report += colorful.bold_green("{0} passed".format(passed)) if passed > 0 and failed > 0: report += colorful.bold_white(", ") if failed > 0: report += colorful.bold_red("{0} failed".format(failed)) report += colorful.bold_white(")") print(report) step_coverage = 100.0 / len(steps) * len(covered_steps) coverage_report = colorful.bold_white( "Covered {0} of {1} step implementations".format(len(covered_steps), len(steps)) ) ret = 0 if failed == 0 else 1 if cover_min_percentage: coverage_color = ( colorful.bold_green if step_coverage >= float(cover_min_percentage) else colorful.bold_red ) coverage_report += colorful.bold_white(" (coverage: ") coverage_report += coverage_color("{0:.2f}%".format(step_coverage)) if float(cover_min_percentage) > step_coverage: coverage_report += colorful.bold_white( ", expected a minimum of {0}".format( colorful.bold_green(cover_min_percentage + "%") ) ) if failed == 0: ret = 2 # if tests have passed and coverage is too low we fail with exit code 2 coverage_report += colorful.bold_white(")") print(coverage_report) if cover_show_missing: missing_steps = get_missing_steps(steps, covered_steps) if missing_steps: missing_step_report = colorful.bold_yellow("Missing steps:\n") for step in missing_steps: missing_step_report += "- {0} at ".format(colorful.cyan(step[0])) missing_step_report += colorful.cyan(step[1]) + "\n" sys.stdout.write(missing_step_report) return ret
def cli(**kwargs): """radish - The root from red to green. BDD tooling for Python. Use radish to run your Feature File. Provide the Feature Files to run in FEATURE_FILES. """ config = Config(kwargs) world.config = config # turn of ANSI colors if requested if config.no_ansi: cf.disable() logger.debug( "Loaded %d built-in extension modules: %s", len(loaded_built_in_extensions), ", ".join(str(e) for e in loaded_built_in_extensions), ) logger.debug("Feature Files: %s", ", ".join(str(p) for p in config.feature_files)) logger.debug("Basedirs: %s", ", ".join(str(d) for d in config.basedirs)) logger.debug("Loading extensions") loaded_extensions = extension_registry.load_extensions(config) logger.debug( "Loaded %d extensions: %s", len(loaded_extensions), ", ".join(type(e).__name__ for e in loaded_extensions), ) parser = FeatureFileParser() features = [] for feature_file in config.feature_files: logger.debug("Parsing Feature File %s", feature_file) try: feature_ast = parser.parse(feature_file) if feature_ast: features.append(feature_ast) except RadishError as exc: print("", flush=True) print( "An error occured while parsing the Feature File {}:".format( feature_file), flush=True, ) print(exc, flush=True) sys.exit(1) logger.debug("Loading all modules from the basedirs") loaded_modules = loader.load_modules(config.basedirs) logger.debug( "Loaded %d modules from the basedirs: %s", len(loaded_modules), ", ".join(str(m) for m in loaded_modules), ) exit_status = 0 try: runner = Runner(config, step_registry=step_registry, hook_registry=hook_registry) logger.debug( "Starting Runner WIP mode: %r, Dry-Run mode: %r", config.wip_mode, config.dry_run_mode, ) success = runner.start(features) logger.debug("Finished Runner with status %s", success) exit_status = 0 if success else 1 except RadishError as exc: print("", flush=True) print("An error occured while running the Feature Files:", flush=True) print(exc, flush=True) exit_status = 1 sys.exit(exit_status)
# configure the radish command line logger which is used for debugging logger = logging.getLogger("radish") logging.basicConfig( level=logging.CRITICAL, format="%(asctime)s - %(name)s [%(levelname)s]: %(message)s") # NOTE(TF): somehow doctest with pytest imports this module multiple times ... if "doctest" not in sys.modules: # load radish built-in extensions __SOURCE_DIR__ = Path(__file__).absolute().parent __BUILT_IN_EXTENSIONS__ = [ __SOURCE_DIR__ / "extensions", __SOURCE_DIR__ / "formatters", ] loaded_built_in_extensions = loader.load_modules(__BUILT_IN_EXTENSIONS__) def enable_radish_debug_mode(ctx, param, enabled): """Enable radish for debugging""" if enabled: logger.setLevel(logging.DEBUG) logger.debug("Enabled debug mode") else: logger.setLevel(logging.ERROR) def expand_basedirs(ctx, param, basedirs): """Expand the given basedirs setting A single basedirs can contain multiple basedir locations.