diff --git a/kgb/tests/py3/test_function_spy.py b/kgb/tests/py3/test_function_spy.py
index 466d9c9fe0b8bbefb24ffbf2d9a6342d90b972b6..f8310fb9454ece4f468612153e18a779b50ce94e 100644
--- a/kgb/tests/py3/test_function_spy.py
+++ b/kgb/tests/py3/test_function_spy.py
@@ -1,3 +1,5 @@
+import functools
+import inspect
 import logging
 import sys
 from unittest import SkipTest
@@ -8,6 +10,25 @@ from kgb.tests.base import TestCase
 logger = logging.getLogger('kgb')
 
 
+def require_func_pos_only_args(func):
+    """Require positional-only arguments for a function.
+
+    If not available, the test will be skippd.
+
+    Args:
+        func (callable):
+            The unit test function to decorate.
+    """
+    @functools.wraps(func)
+    def _wrap(*args, **kwargs):
+        if sys.version_info[:2] >= (3, 8):
+            return func(*args, **kwargs)
+        else:
+            raise SkipTest('inspect.getargspec is not available on Python 3.8')
+
+    return _wrap
+
+
 class FunctionSpyTests(TestCase):
     """Python 3 unit tests for kgb.spies.FunctionSpy."""
 
@@ -85,13 +106,11 @@ class FunctionSpyTests(TestCase):
                 'return': bool,
             })
 
+    @require_func_pos_only_args
     def test_call_with_function_and_positional_only_args(self):
         """Testing FunctionSpy calls with function containing positional-only
         arguments
         """
-        if sys.version_info[:2] < (3, 8):
-            raise SkipTest('Not supported on this version of Python')
-
         func = self.make_func("""
             def func(a, b=1, /):
                 return a * b
@@ -105,13 +124,11 @@ class FunctionSpyTests(TestCase):
         self.assertEqual(func.spy.calls[0].args, (2, 5))
         self.assertEqual(func.spy.calls[0].kwargs, {})
 
+    @require_func_pos_only_args
     def test_call_with_function_and_positional_only_args_no_pos_passed(self):
         """Testing FunctionSpy calls with function containing positional-only
         arguments and no positional argument passed
         """
-        if sys.version_info[:2] < (3, 8):
-            raise SkipTest('Not supported on this version of Python')
-
         func = self.make_func("""
             def func(a, b=2, /):
                 return a * b
@@ -206,3 +223,363 @@ class FunctionSpyTests(TestCase):
                            func_name='my_method')
 
         self.agency.assertSpyNotCalled(logger.warning)
+
+    def test_getfullargspec_with_function(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with function"""
+        def func(a, b=2):
+            return a * b
+
+        self.agency.spy_on(func)
+
+        argspec = inspect.getfullargspec(func)
+
+        self.assertEqual(argspec.args, ['a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    @require_func_pos_only_args
+    def test_getfullargspec_with_function_pos_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with function and
+        positional-only arguments
+        """
+        func = self.make_func("""
+            def func(a, b=2, /, c=3):
+                return a * b
+        """)
+
+        self.agency.spy_on(func)
+
+        argspec = inspect.getfullargspec(func)
+
+        self.assertEqual(argspec.args, ['a', 'b', 'c'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2, 3))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_function_keyword_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with function and
+        keyword-only arguments
+        """
+        def func(*, a, b=2):
+            return a * b
+
+        self.agency.spy_on(func)
+
+        argspec = inspect.getfullargspec(func)
+
+        self.assertEqual(argspec.args, [])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertIsNone(argspec.defaults)
+        self.assertEqual(argspec.kwonlyargs, ['a', 'b'])
+        self.assertEqual(argspec.kwonlydefaults, {
+            'b': 2,
+        })
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_function_annotations(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with function and
+        annotations
+        """
+        def func(a: int, b: int = 2) -> int:
+            return a * b
+
+        self.agency.spy_on(func)
+
+        argspec = inspect.getfullargspec(func)
+
+        self.assertEqual(argspec.args, ['a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {
+            'a': int,
+            'b': int,
+            'return': int,
+        })
+
+    def test_getfullargspec_with_bound_method(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with bound method"""
+        class MyObject:
+            def func(self, a, b=2):
+                return a * b
+
+        obj = MyObject()
+        self.agency.spy_on(obj.func)
+
+        argspec = inspect.getfullargspec(obj.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    @require_func_pos_only_args
+    def test_getfullargspec_with_bound_method_pos_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with bound method
+        and positional-only arguments
+        """
+        MyObject = self.make_func(
+            """
+            class MyObject:
+                def func(self, a, b=2, /, c=3):
+                    return a * b
+            """,
+            func_name='MyObject')
+
+        obj = MyObject()
+        self.agency.spy_on(obj.func)
+
+        argspec = inspect.getfullargspec(obj.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b', 'c'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2, 3))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_bound_method_keyword_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with bound method
+        and keyword-only arguments
+        """
+        class MyObject:
+            def func(self, *, a, b=2):
+                return a * b
+
+        obj = MyObject()
+        self.agency.spy_on(obj.func)
+
+        argspec = inspect.getfullargspec(obj.func)
+
+        self.assertEqual(argspec.args, ['self'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertIsNone(argspec.defaults)
+        self.assertEqual(argspec.kwonlyargs, ['a', 'b'])
+        self.assertEqual(argspec.kwonlydefaults, {
+            'b': 2,
+        })
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_bound_method_annotations(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with bound method
+        and annotations
+        """
+        class MyObject:
+            def func(self, a: int, b: int = 2) -> int:
+                return a * b
+
+        obj = MyObject()
+        self.agency.spy_on(obj.func)
+
+        argspec = inspect.getfullargspec(obj.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {
+            'a': int,
+            'b': int,
+            'return': int,
+        })
+
+    def test_getfullargspec_with_unbound_method(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with unbound method
+        """
+        class MyObject:
+            def func(self, a, b=2):
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    @require_func_pos_only_args
+    def test_getfullargspec_with_unbound_method_pos_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with unbound method
+        and positional-only arguments
+        """
+        MyObject = self.make_func(
+            """
+            class MyObject:
+                def func(self, a, b=2, /, c=3):
+                    return a * b
+            """,
+            func_name='MyObject')
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b', 'c'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2, 3))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_unbound_method_keyword_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with unbound method
+        and keyword-only arguments
+        """
+        class MyObject:
+            def func(self, *, a, b=2):
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['self'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertIsNone(argspec.defaults)
+        self.assertEqual(argspec.kwonlyargs, ['a', 'b'])
+        self.assertEqual(argspec.kwonlydefaults, {
+            'b': 2,
+        })
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_unbound_method_annotations(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with unbound method
+        and annotations
+        """
+        class MyObject:
+            def func(self, a: int, b: int = 2) -> int:
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['self', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {
+            'a': int,
+            'b': int,
+            'return': int,
+        })
+
+    def test_getfullargspec_with_classmethod(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with classmethod
+        """
+        class MyObject:
+            @classmethod
+            def func(cls, a, b=2):
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['cls', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    @require_func_pos_only_args
+    def test_getfullargspec_with_classmethod_pos_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with classmethod
+        and positional-only arguments
+        """
+        MyObject = self.make_func(
+            """
+            class MyObject:
+                @classmethod
+                def func(cls, a, b=2, /, c=3):
+                    return a * b
+            """,
+            func_name='MyObject')
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['cls', 'a', 'b', 'c'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2, 3))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_classmethod_keyword_only(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with classmethod
+        and keyword-only arguments
+        """
+        class MyObject:
+            @classmethod
+            def func(cls, *, a, b=2):
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['cls'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertIsNone(argspec.defaults)
+        self.assertEqual(argspec.kwonlyargs, ['a', 'b'])
+        self.assertEqual(argspec.kwonlydefaults, {
+            'b': 2,
+        })
+        self.assertEqual(argspec.annotations, {})
+
+    def test_getfullargspec_with_classmethod_annotations(self):
+        """Testing FunctionSpy in inspect.getfullargspec() with classmethod
+        and annotations
+        """
+        class MyObject:
+            @classmethod
+            def func(cls, a: int, b: int = 2) -> int:
+                return a * b
+
+        self.agency.spy_on(MyObject.func)
+
+        argspec = inspect.getfullargspec(MyObject.func)
+
+        self.assertEqual(argspec.args, ['cls', 'a', 'b'])
+        self.assertIsNone(argspec.varargs)
+        self.assertIsNone(argspec.varkw)
+        self.assertEqual(argspec.defaults, (2,))
+        self.assertEqual(argspec.kwonlyargs, [])
+        self.assertIsNone(argspec.kwonlydefaults)
+        self.assertEqual(argspec.annotations, {
+            'a': int,
+            'b': int,
+            'return': int,
+        })
