Add a Python script to autogenerate some tests for pytest

pull/1726/head
Daniele Forsi IU5HKX 2025-06-15 11:11:12 +02:00
rodzic f2aaed6e09
commit 464450384d
2 zmienionych plików z 97 dodań i 0 usunięć

Wyświetl plik

@ -22,6 +22,7 @@ SWGDEP = \
EXTRA_DIST = $(SWGFILES) \
Makefile.PL perltest.pl tcltest.tcl.in \
python/generate_tests.py \
python/test_startup.py \
luatest.lua README.python
@ -108,6 +109,10 @@ all-py: $(pyexec_ltlib)
check-py: all-py pytest-${enable_pytest}
generate-pytests: all-py
$(AM_V_at)PYTHONPATH=$(builddir):$(builddir)/.libs \
$(PYTHON) "$(srcdir)/python/generate_tests.py" "$(srcdir)/python/"
pytest-yes:
$(AM_V_at)PYTHONPATH=$(builddir):$(builddir)/.libs \
$(PYTEST) --capture=no $(srcdir)/

Wyświetl plik

@ -0,0 +1,92 @@
#! /bin/env python
"""
Creates tests for the Python bindings for Hamlib
Running this script directly will use the installed bindings.
For an in-tree run use "make check", or set PYTHONPATH to point to
the directories containing Hamlib.py and _Hamlib.so.
"""
import inspect
import os
import sys
import Hamlib
# This class gets copied to the generated file with replacements
class TestClass:
"""A pytest class for {object_name}"""
@classmethod
def setup_class(cls):
"""Common initialization before calling test methods"""
cls.actual_callables, cls.actual_properties = cls.generate_data({object_name})
def test_callables(self):
"""Check that nothing was added or removed"""
expected_callables = {expected_callables}
assert expected_callables == self.actual_callables
def test_properties(self):
"""Check that nothing was added or removed"""
expected_properties = {expected_properties}
assert expected_properties == self.actual_properties
@classmethod
def generate_data(cls, the_object):
"""Extract callables and properties from the given object"""
callables = []
properties = []
for method_or_property in dir(the_object):
if not method_or_property.startswith("_"):
if callable(getattr(the_object, method_or_property)):
callables.append(method_or_property)
else:
properties.append(method_or_property)
return callables, properties
def generate_file(object_name, callables, properties):
"""Create a complete file for pytest"""
file_header = '''#! /bin/env pytest
"""
Tests of the Python bindings for Hamlib
DO NOT EDIT this autogenerated file, run "make generate-pytests" instead
"""
import Hamlib
'''
filename = f"test_{object_name.replace(".", "_")}_class.py"
class_source = inspect.getsource(TestClass)
expected_callables = repr(callables)
expected_properties = repr(properties)
print(f"Generating {filename}")
with open(filename, "w", encoding='utf-8') as output_file:
print(file_header, file=output_file)
print(class_source.format(
object_name=object_name,
expected_callables=expected_callables,
expected_properties=expected_properties),
file=output_file, end='')
if __name__ == "__main__":
if len(sys.argv) == 2 and not sys.argv[1].startswith("-"):
os.chdir(sys.argv[1])
else:
print("Usage: {sys.argv[0]} [OUTPUT_DIRECTORY]", file=sys.stderr)
sys.exit(1)
for the_object in (
Hamlib,
Hamlib.Amp,
Hamlib.Rig,
Hamlib.Rot,
):
try:
full_name = f"{the_object.__module__}.{the_object.__name__}"
except AttributeError:
full_name = the_object.__name__
expected_callables, expected_properties = TestClass.generate_data(the_object)
generate_file(full_name, expected_callables, expected_properties)