def fixture(func=None, *, scope: Union[Scope, str] = Scope.Test): """ Decorator which will cause the wrapped function to be collected and treated as a fixture. Args: func: The wrapped function which should yield or return some data required to execute a test. scope: The scope of a fixture determines how long it can be cached for (and therefore how frequently the fixture should be regenerated). """ if not isinstance(scope, Scope): scope = Scope.from_str(scope) if func is None: return partial(fixture, scope=scope) # By setting is_fixture = True, the framework will know # that if this fixture is provided as a default arg, it # is responsible for resolving the value. path = Path(inspect.getfile(func)).absolute() if hasattr(func, "ward_meta"): func.ward_meta.is_fixture = True func.ward_meta.path = path else: func.ward_meta = CollectionMetadata(is_fixture=True, scope=scope, path=path) _DEFINED_FIXTURES.append(Fixture(func)) @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper
def skip( func_or_reason: Union[str, Callable, None] = None, *, reason: Optional[str] = None, when: Union[bool, Callable] = True, ): """ Decorator which can be used to optionally skip tests. Args: func_or_reason (object): The wrapped test function to skip. reason: The reason the test was skipped. May appear in output. when: Predicate function. Will be called immediately before the test is executed. If it evaluates to True, the test will be skipped. Otherwise the test will run as normal. """ if func_or_reason is None: return functools.partial(skip, reason=reason, when=when) if isinstance(func_or_reason, str): return functools.partial(skip, reason=func_or_reason, when=when) func = func_or_reason marker = SkipMarker(reason=reason, when=when) if hasattr(func, "ward_meta"): func.ward_meta.marker = marker # type: ignore[attr-defined] else: func.ward_meta = CollectionMetadata( marker=marker) # type: ignore[attr-defined] @functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper
def decorator_test(func): unwrapped = inspect.unwrap(func) module_name: str = unwrapped.__module__ is_home_module: bool = "." not in module_name if is_test_module_name(module_name) and is_home_module: force_path: Path = kwargs.get("_force_path") if force_path: path = force_path.absolute() else: path = get_absolute_path(unwrapped) if hasattr(unwrapped, "ward_meta"): unwrapped.ward_meta.description = description unwrapped.ward_meta.tags = tags unwrapped.ward_meta.path = path else: unwrapped.ward_meta = CollectionMetadata( description=description, tags=tags, path=path, ) collect_into = kwargs.get("_collect_into", COLLECTED_TESTS) collect_into[path].append(unwrapped) @functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper return func
def xfail( func_or_reason: Union[str, Callable, None] = None, *, reason: Optional[str] = None, when: Union[bool, Callable] = True, ): """ Decorator that can be used to mark a test as "expected to fail". Args: func_or_reason: The wrapped test function to mark as an expected failure. reason: The reason we expect the test to fail. May appear in output. when: Predicate function. Will be called immediately before the test is executed. If it evaluates to True, the test will be marked as an expected failure. Otherwise the test will run as normal. """ if func_or_reason is None: return functools.partial(xfail, reason=reason, when=when) if isinstance(func_or_reason, str): return functools.partial(xfail, reason=func_or_reason, when=when) func = func_or_reason marker = XfailMarker(reason=reason, when=when) if hasattr(func, "ward_meta"): func.ward_meta.marker = marker # type: ignore[attr-defined] else: func.ward_meta = CollectionMetadata( marker=marker) # type: ignore[attr-defined] @functools.wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper
def _(func=example_test): out_func = testable_test(func) assert out_func.ward_meta == CollectionMetadata( marker=None, description="testable test description", is_fixture=False, scope=Scope.Test, bound_args=None, path=FORCE_TEST_PATH, )
def decorator_using(func): signature = inspect.signature(func) bound_args = signature.bind_partial(*using_args, **using_kwargs) if hasattr(func, "ward_meta"): func.ward_meta.bound_args = bound_args else: func.ward_meta = CollectionMetadata(bound_args=bound_args) @wraps(func) def wrapper(*args, **kwargs): return func(*args, **kwargs) return wrapper