[VVP] Track Requirements to Test Cases 43/56043/2
authorstark, steven <ss820f@att.com>
Mon, 9 Jul 2018 18:33:13 +0000 (11:33 -0700)
committerstark, steven <ss820f@att.com>
Mon, 9 Jul 2018 18:48:02 +0000 (11:48 -0700)
Change-Id: I35c7630d0aabb970e67323e1e895a57cbcb23fb2
Issue-ID: VVP-79
Signed-off-by: stark, steven <ss820f@att.com>
ice_validator/tests/conftest.py
ice_validator/tests/helpers.py
requirements.txt

index 69709af..84429cf 100644 (file)
@@ -147,3 +147,14 @@ def pytest_generate_tests(metafunc):
     if 'templates' in metafunc.fixturenames:
         from .parametrizers import parametrize_templates
         parametrize_templates(metafunc)
     if 'templates' in metafunc.fixturenames:
         from .parametrizers import parametrize_templates
         parametrize_templates(metafunc)
+
+
+def pytest_report_collectionfinish(config, startdir, items):
+    """Generates a simple traceability report to sysout"""
+    print("Traceability Report")
+    print("==================================================================")
+    for item in items:
+        if hasattr(item.function, "requirement_ids"):
+            for req_id in item.function.requirement_ids:
+                print(req_id + "," + item.function.__module__ + ","
+                      + item.function.__name__)
index 9cde1fa..82d0201 100644 (file)
@@ -39,6 +39,7 @@
 #
 
 import yaml
 #
 
 import yaml
+from boltons import funcutils
 
 
 def check_basename_ending(template_type, basename):
 
 
 def check_basename_ending(template_type, basename):
@@ -76,3 +77,27 @@ def get_parsed_yml_for_yaml_files(yaml_files, sections=[]):
             parsed_yml_list.append(yml)
 
     return parsed_yml_list
             parsed_yml_list.append(yml)
 
     return parsed_yml_list
+
+
+def validates(*requirement_ids):
+    """Decorator that tags the test function with one or more requirement IDs.
+
+    Example:
+        >>> @validates('R-12345', 'R-12346')
+        ... def test_something():
+        ...     pass
+        >>> assert test_something.requirement_ids == ['R-12345', 'R-12346']
+    """
+    def decorator(func):
+        # NOTE: We use a utility here to ensure that function signatures are
+        # maintained because pytest inspects function signatures to inject
+        # fixtures.  I experimented with a few options, but this is the only
+        # library that worked. Other libraries dynamically generated a
+        # function at run-time, and then lost the requirement_ids attribute
+        @funcutils.wraps(func)
+        def wrapper(*args, **kw):
+            return func(*args, **kw)
+        wrapper.requirement_ids = requirement_ids
+        return wrapper
+    decorator.requirement_ids = requirement_ids
+    return decorator
index a33e916..ce8e47f 100644 (file)
@@ -40,4 +40,5 @@
 
 pytest
 PyYAML
 
 pytest
 PyYAML
-pytest-tap
\ No newline at end of file
+pytest-tap
+boltons