se2p / pynguin

The PYthoN General UnIt Test geNerator is a test-generation tool for Python
https://www.pynguin.eu
MIT License
1.24k stars 75 forks source link

How to avoid digging deep into the dependencies #31

Closed ravindrabajpai closed 8 months ago

ravindrabajpai commented 1 year ago

Hi,

In my project, I am using dependencies such as sqlalchemy, boto3, and pynguin reports an error as - │ /work/venvs/py310/lib/python3.10/site-packages/sqlalchemy/orm/decl_api.py:309 in cascading │ │ │ │ 306 │ │ │ │ 307 │ │ │ │ 308 │ │ """ │ │ ❱ 309 │ │ return cls._stateful(cascading=True) │ │ 310 │ │ 311 │ │ 312 class _stateful_declared_attr(declared_attr): │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ TypeError: _stateful_declared_attr._stateful() missing 1 required positional argument: 'self'

My project runs fine although.

Is there a way to make penguin avoid looking deeper into the code, which I have not written such as these.

What is the guidelines to ignore these dependencies, shall we mock them from our side before running penguin. Please guide.

Thanks.

stephanlukasczyk commented 1 year ago

Hi,

Could you please provide a minimal working example that shows this behaviour, together with the used software versions and Pynguin command line you've used?

Best, Stephan

ravindrabajpai commented 1 year ago

Hi Stephan,

Thank you for your response. Please find the minimal repro below -

which python /work/venvs/py310/bin/python

python --version Python 3.10.6

pynguin --version pynguin 0.27.0

pwd /work/test/repro

cd /work/test/repro

ls pycache mydb.db pynguin-report pynguine_tests ut

cat ut/test_main.py `import sys from typing import List

import sqlalchemy from sqlalchemy.orm import sessionmaker

class SQLiteConnectionManager(object): def init(self): super().init()

@staticmethod
def get_connection_for_env():
    engine = sqlalchemy.create_engine("sqlite:////work/test/repro")

    session_maker = sessionmaker(bind=engine)
    session = session_maker()
    return engine, session

if name == 'main': try: engine, session = SQLiteConnectionManager.get_connection_for_env() print ('Connection Initialized...') sys.exit(0) except Exception as e: print (e) raise e finally: print('Finally closing db connection') session.close() engine.dispose() ` python ut/test_main.py Connection Initialized... Finally closing db connection

pynguin --project-path /work/test/repro/ut --output-path /work/test/repro/pynguine_tests/ --module-name test_main ╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮ │ /work/venvs/py310/bin/pynguin:8 in │ │ │ │ 5 from pynguin.cli import main │ │ 6 if name == 'main': │ │ 7 │ sys.argv[0] = re.sub(r'(-script.pyw|.exe)?$', '', sys.argv[0]) │ │ ❱ 8 │ sys.exit(main()) │ │ 9 │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/cli.py:190 in main │ │ │ │ 187 │ set_configuration(parsed.config) │ │ 188 │ if console is not None: │ │ 189 │ │ with console.status("Running Pynguin..."): │ │ ❱ 190 │ │ │ return run_pynguin().value │ │ 191 │ else: │ │ 192 │ │ return run_pynguin().value │ │ 193 │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/generator.py:111 in run_pynguin │ │ │ │ 108 │ """ │ │ 109 │ try: │ │ 110 │ │ _LOGGER.info("Start Pynguin Test Generation…") │ │ ❱ 111 │ │ return _run() │ │ 112 │ finally: │ │ 113 │ │ _LOGGER.info("Stop Pynguin Test Generation…") │ │ 114 │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/generator.py:496 in _run │ │ │ │ 493 │ │ 494 │ │ 495 def _run() -> ReturnCode: │ │ ❱ 496 │ if (setup_result := _setup_and_check()) is None: │ │ 497 │ │ return ReturnCode.SETUP_FAILED │ │ 498 │ executor, test_cluster, constant_provider = setup_result │ │ 499 │ # traces slices for test cases after execution │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/generator.py:260 in _setup_and_check │ │ │ │ 257 │ │ │ 258 │ # Analyzing the SUT should not cause any coverage. │ │ 259 │ tracer.disable() │ │ ❱ 260 │ if (test_cluster := _setup_test_cluster()) is None: │ │ 261 │ │ return None │ │ 262 │ tracer.enable() │ │ 263 │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/generator.py:117 in _setup_test_cluster │ │ │ │ 114 │ │ 115 │ │ 116 def _setup_test_cluster() -> ModuleTestCluster | None: │ │ ❱ 117 │ test_cluster = generate_test_cluster( │ │ 118 │ │ config.configuration.module_name, │ │ 119 │ │ config.configuration.type_inference.type_inference_strategy, │ │ 120 │ ) │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/analyses/module.py:1303 in │ │ generate_test_cluster │ │ │ │ 1300 │ Returns: │ │ 1301 │ │ A new test cluster for the given module │ │ 1302 │ """ │ │ ❱ 1303 │ return analyse_module(parse_module(module_name), type_inference_strategy) │ │ 1304 │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/analyses/module.py:1282 in analyse_module │ │ │ │ 1279 │ │ A test cluster for the module │ │ 1280 │ """ │ │ 1281 │ test_cluster = ModuleTestCluster(linenos=parsed_module.linenos) │ │ ❱ 1282 │ resolve_dependencies( │ │ 1283 │ │ root_module=parsed_module, │ │ 1284 │ │ type_inference_strategy=type_inference_strategy, │ │ 1285 │ │ test_cluster=test_cluster, │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/analyses/module.py:1159 in │ │ __resolve_dependencies │ │ │ │ 1156 │ │ │ continue │ │ 1157 │ │ │ │ 1158 │ │ # Analyze all classes found in the current module │ │ ❱ 1159 │ │ analyse_included_classes( │ │ 1160 │ │ │ module=current_module, │ │ 1161 │ │ │ root_module_name=root_module.module_name, │ │ 1162 │ │ │ type_inference_strategy=type_inference_strategy, │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/analyses/module.py:1219 in │ │ analyse_included_classes │ │ │ │ 1216 │ │ │ │ 1217 │ │ type_info = test_cluster.type_system.to_type_info(current) │ │ 1218 │ │ │ │ ❱ 1219 │ │ __analyse_class( │ │ 1220 │ │ │ type_info=type_info, │ │ 1221 │ │ │ type_inference_strategy=type_inference_strategy, │ │ 1222 │ │ │ module_tree=parse_results[current.module].syntax_tree, │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/pynguin/analyses/module.py:1019 in │ │ analyse_class │ │ │ │ 1016 │ │ if add_to_test: │ │ 1017 │ │ │ test_cluster.add_accessible_object_under_test(generic, method_data) │ │ 1018 │ │ │ ❱ 1019 │ for method_name, method in inspect.getmembers( │ │ 1020 │ │ type_info.raw_type, inspect.isfunction │ │ 1021 │ ): │ │ 1022 │ │ analyse_method( │ │ │ │ /usr/lib/python3.10/inspect.py:469 in getmembers │ │ │ │ 466 │ │ # like calling their get (see bug #1785), so fall back to │ │ 467 │ │ # looking in the dict. │ │ 468 │ │ try: │ │ ❱ 469 │ │ │ value = getattr(object, key) │ │ 470 │ │ │ # handle the duplicate key │ │ 471 │ │ │ if key in processed: │ │ 472 │ │ │ │ raise AttributeError │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/sqlalchemy/util/langhelpers.py:1446 in get │ │ │ │ 1443 │ │ │ 1444 │ def get__(self, instance, owner): │ │ 1445 │ │ if instance is None: │ │ ❱ 1446 │ │ │ clsval = self.clslevel(owner) │ │ 1447 │ │ │ return clsval │ │ 1448 │ │ else: │ │ 1449 │ │ │ return self.func(instance) │ │ │ │ /work/venvs/py310/lib/python3.10/site-packages/sqlalchemy/orm/decl_api.py:309 in cascading │ │ │ │ 306 │ │ │ │ 307 │ │ │ │ 308 │ │ """ │ │ ❱ 309 │ │ return cls._stateful(cascading=True) │ │ 310 │ │ 311 │ │ 312 class _stateful_declared_attr(declared_attr): │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ TypeError: _stateful_declared_attr._stateful() missing 1 required positional argument: 'self'