Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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]
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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)
Beispiel #7
0
# 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.