def test_disabled(self):
     self.assertTrue(
         check_docstring_directive(":avocado: disable", "disable"))
     self.assertTrue(
         check_docstring_directive(":avocado:\tdisable", "disable"))
     self.assertFalse(
         check_docstring_directive(":AVOCADO: DISABLE", "disable"))
     self.assertFalse(
         check_docstring_directive(":avocado: disabled", "disable"))
 def test_enabled(self):
     self.assertTrue(check_docstring_directive(":avocado: enable",
                                               "enable"))
     self.assertTrue(
         check_docstring_directive(":avocado:\tenable", "enable"))
     self.assertTrue(
         check_docstring_directive(":avocado: enable\n:avocado: tags=fast",
                                   "enable"))
     self.assertFalse(
         check_docstring_directive(":AVOCADO: ENABLE", "enable"))
     self.assertFalse(
         check_docstring_directive(":avocado: enabled", "enable"))
Example #3
0
def find_python_tests(target_module, target_class, determine_match, path):
    """
    Attempts to find Python tests from source files

    A Python test in this context is a method within a specific type
    of class (or that inherits from a specific class).

    :param target_module: the name of the module from which a class should
                          have come from.  When attempting to find a Python
                          unittest, the target_module will most probably
                          be "unittest", as per the standard library module
                          name.  When attempting to find Avocado tests, the
                          target_module will most probably be "avocado".
    :type target_module: str
    :param target_class: the name of the class that is considered to contain
                         test methods.  When attempting to find Python
                         unittests, the target_class will most probably be
                         "TestCase".  When attempting to find Avocado tests,
                         the target_class  will most probably be "Test".
    :type target_class: str
    :type determine_match: a callable that will determine if a given module
                           and class is contains valid Python tests
    :type determine_match: function
    :param path: path to a Python source code file
    :type path: str
    :returns: tuple where first item is dict with class name and additional
              info such as method names and tags; the second item is
              set of class names which look like Python tests but have been
              forcefully disabled.
    :rtype: tuple
    """
    module = PythonModule(path, target_module, target_class)
    # The resulting test classes
    result = collections.OrderedDict()
    disabled = set()

    for klass in module.iter_classes():
        docstring = ast.get_docstring(klass)
        # Looking for a class that has in the docstring either
        # ":avocado: enable" or ":avocado: disable
        if check_docstring_directive(docstring, 'disable'):
            disabled.add(klass.name)
            continue

        if check_docstring_directive(docstring, 'enable'):
            info = get_methods_info(klass.body,
                                    get_docstring_directives_tags(docstring),
                                    get_docstring_directives_requirements(
                                        docstring))
            result[klass.name] = info
            continue

        # From this point onwards we want to do recursive discovery, but
        # for now we don't know whether it is avocado.Test inherited
        # (Ifs are optimized for readability, not speed)

        # If "recursive" tag is specified, it is forced as test
        if check_docstring_directive(docstring, 'recursive'):
            match = True
        else:
            match = module.is_matching_klass(klass)
        info = get_methods_info(klass.body,
                                get_docstring_directives_tags(docstring),
                                get_docstring_directives_requirements(
                                    docstring))
        # Getting the list of parents of the current class
        parents = klass.bases

        match = _examine_same_module(parents, info, disabled, match, module,
                                     target_module, target_class, determine_match)

        # If there are parents left to be discovered, they
        # might be in a different module.
        for parent in parents:
            try:
                (parent_class,
                 imported_symbol,
                 symbol_is_module) = _get_attributes_for_further_examination(parent,
                                                                             module)

                found_spec = imported_symbol.get_importable_spec(symbol_is_module)
                if found_spec is None:
                    continue

            except ClassNotSuitable:
                continue

            _info, _dis, _match = _examine_class(target_module,
                                                 target_class,
                                                 determine_match,
                                                 found_spec.origin,
                                                 parent_class,
                                                 match)
            if _info:
                info.extend(_info)
                disabled.update(_dis)
            if _match is not match:
                match = _match

        # Only update the results if this was detected as 'avocado.Test'
        if match:
            result[klass.name] = info

    return result, disabled