diff --git a/meta/lib/patchtest/tests/base.py b/meta/lib/patchtest/tests/base.py
index 8263932dda..30c207f016 100644
--- a/meta/lib/patchtest/tests/base.py
+++ b/meta/lib/patchtest/tests/base.py
@@ -133,18 +133,17 @@ class Metadata(Base):
     def setUpClassLocal(cls):
         cls.tinfoil = cls.setup_tinfoil()
 
-        # get info about added/modified/remove recipes
+        # get info about added/modified/removed recipes
         cls.added, cls.modified, cls.removed = cls.get_metadata_stats(cls.patchset)
 
     @classmethod
     def tearDownClassLocal(cls):
-        cls.tinfoil.shutdown()
+        if cls.tinfoil:
+            cls.tinfoil.shutdown()
 
     @classmethod
     def setup_tinfoil(cls, config_only=False):
-        """Initialize tinfoil api from bitbake"""
-
-        # import relevant libraries
+        """Initialize tinfoil api from bitbake."""
         try:
             scripts_path = os.path.join(PatchtestParser.repodir, "scripts", "lib")
             if scripts_path not in sys.path:
@@ -156,21 +155,19 @@ class Metadata(Base):
             raise PatchtestOEError('Could not import tinfoil module')
 
         orig_cwd = os.path.abspath(os.curdir)
-
-        # Load tinfoil
         tinfoil = None
         try:
             builddir = os.environ.get('BUILDDIR')
             if not builddir:
                 logger.warn('Bitbake environment not loaded?')
-                return tinfoil
+                return None
             os.chdir(builddir)
             tinfoil = bb.tinfoil.Tinfoil()
             tinfoil.prepare(config_only=config_only)
-        except bb.tinfoil.TinfoilUIException as te:
+        except bb.tinfoil.TinfoilUIException:
             if tinfoil:
                 tinfoil.shutdown()
-            raise PatchtestOEError('Could not prepare properly tinfoil (TinfoilUIException)')
+            raise PatchtestOEError('Could not properly configure tinfoil (TinfoilUIException)')
         except Exception as e:
             if tinfoil:
                 tinfoil.shutdown()
@@ -180,69 +177,48 @@ class Metadata(Base):
 
         return tinfoil
 
+    @staticmethod
+    def _find_pn(data, path):
+        """Find the PN from tinfoil recipe cache data for a given file path."""
+        pn = None
+        pn_native = None
+        for _path, _pn in data:
+            if path in _path:
+                if 'native' in _pn:
+                    pn_native = _pn
+                else:
+                    pn = _pn
+                    break
+        else:
+            if pn_native:
+                return pn_native
+            path_basename = path.split('_')[0]
+            for _path, _pn in data:
+                _path_basename = _path.split('_')[0]
+                if path_basename == _path_basename:
+                    pn = _pn
+        return pn
+
     @classmethod
-    def get_metadata_stats(cls, patchset):
-        """Get lists of added, modified and removed metadata files"""
+    def _getvar(cls, path, varname):
+        """Return a recipe variable value via tinfoil if available."""
+        if cls.tinfoil:
+            data = list(cls.tinfoil.cooker.recipecaches[''].pkg_fn.items())
+            pn = cls._find_pn(data, path)
+            rd = cls.tinfoil.parse_recipe(pn)
+            return rd.getVar(varname)
 
-        def find_pn(data, path):
-            """Find the PN from data"""
-            pn = None
-            pn_native = None
-            for _path, _pn in data:
-                if path in _path:
-                    if 'native' in _pn:
-                        # store the native PN but look for the non-native one first
-                        pn_native = _pn
-                    else:
-                        pn = _pn
-                        break
-            else:
-                # sent the native PN if found previously
-                if pn_native:
-                    return pn_native
-
-                # on renames (usually upgrades), we need to check (FILE) base names
-                # because the unidiff library does not provided the new filename, just the modified one
-                # and tinfoil datastore, once the patch is merged, will contain the new filename
-                path_basename = path.split('_')[0]
-                for _path, _pn in data:
-                    _path_basename = _path.split('_')[0]
-                    if path_basename == _path_basename:
-                        pn = _pn
-            return pn
-
-        if not cls.tinfoil:
-            cls.tinfoil = cls.setup_tinfoil()
-
-        added_paths, modified_paths, removed_paths = [], [], []
+    @classmethod
+    def get_metadata_stats(cls, patchset):
+        """Return lists of absolute paths for added, modified and removed recipe files."""
         added, modified, removed = [], [], []
-
-        # get metadata filename additions, modification and removals
         for patch in patchset:
             if patch.path.endswith('.bb') or patch.path.endswith('.bbappend') or patch.path.endswith('.inc'):
+                abspath = os.path.join(os.path.abspath(PatchtestParser.repodir), patch.path)
                 if patch.is_added_file:
-                    added_paths.append(
-                        os.path.join(
-                            os.path.abspath(PatchtestParser.repodir), patch.path
-                        )
-                    )
+                    added.append(abspath)
                 elif patch.is_modified_file:
-                    modified_paths.append(
-                        os.path.join(
-                            os.path.abspath(PatchtestParser.repodir), patch.path
-                        )
-                    )
+                    modified.append(abspath)
                 elif patch.is_removed_file:
-                    removed_paths.append(
-                        os.path.join(
-                            os.path.abspath(PatchtestParser.repodir), patch.path
-                        )
-                    )
-
-        data = cls.tinfoil.cooker.recipecaches[''].pkg_fn.items()
-
-        added = [find_pn(data,path) for path in added_paths]
-        modified = [find_pn(data,path) for path in modified_paths]
-        removed = [find_pn(data,path) for path in removed_paths]
-
-        return [a for a in added if a], [m for m in modified if m], [r for r in removed if r]
+                    removed.append(abspath)
+        return added, modified, removed
