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

Error when generating tests for a file using numpy as a dependency #57

Closed BergLucas closed 7 months ago

BergLucas commented 7 months ago

Describe the bug When I try to generate tests for a file that imports numpy, Pynguin crashes.

To Reproduce Steps to reproduce the behaviour:

  1. Use Pynguin version '0.34.0'
  2. Use the following (minimal) code as a subject for test generation:
    
    import numpy

def foo(x: int) -> int: return x * 2


3. Use the following command line arguments to Pynguin:

```bash
--module-name <module-name>
--project-path <project-name>
--output-path <output-name>
  1. Give the error (stack trace, etc) you are encountering:
    ╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮
    │ /home/lucas/.conda/envs/2324-master-thesis/bin/pynguin:8 in <module>                             │
    │                                                                                                  │
    │   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                                                                                              │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/cli.py:193 in main                              │
    │                                                                                                  │
    │   190 │   set_configuration(parsed.config)                                                       │
    │   191 │   if console is not None:                                                                │
    │   192 │   │   with console.status("Running Pynguin..."):                                         │
    │ ❱ 193 │   │   │   return run_pynguin().value                                                     │
    │   194 │   else:                                                                                  │
    │   195 │   │   return run_pynguin().value                                                         │
    │   196                                                                                            │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/generator.py:108 in run_pynguin                 │
    │                                                                                                  │
    │   105 │   """                                                                                    │
    │   106 │   try:                                                                                   │
    │   107 │   │   _LOGGER.info("Start Pynguin Test Generation…")                                     │
    │ ❱ 108 │   │   return _run()                                                                      │
    │   109 │   finally:                                                                               │
    │   110 │   │   _LOGGER.info("Stop Pynguin Test Generation…")                                      │
    │   111                                                                                            │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/generator.py:507 in _run                        │
    │                                                                                                  │
    │   504                                                                                            │
    │   505                                                                                            │
    │   506 def _run() -> ReturnCode:                                                                  │
    │ ❱ 507 │   if (setup_result := _setup_and_check()) is None:                                       │
    │   508 │   │   return ReturnCode.SETUP_FAILED                                                     │
    │   509 │   executor, test_cluster, constant_provider = setup_result                               │
    │   510 │   # traces slices for test cases after execution                                         │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/generator.py:258 in _setup_and_check            │
    │                                                                                                  │
    │   255 │                                                                                          │
    │   256 │   # Analyzing the SUT should not cause any coverage.                                     │
    │   257 │   tracer.disable()                                                                       │
    │ ❱ 258 │   if (test_cluster := _setup_test_cluster()) is None:                                    │
    │   259 │   │   return None                                                                        │
    │   260 │   tracer.enable()                                                                        │
    │   261                                                                                            │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/generator.py:114 in _setup_test_cluster         │
    │                                                                                                  │
    │   111                                                                                            │
    │   112                                                                                            │
    │   113 def _setup_test_cluster() -> ModuleTestCluster | None:                                     │
    │ ❱ 114 │   test_cluster = generate_test_cluster(                                                  │
    │   115 │   │   config.configuration.module_name,                                                  │
    │   116 │   │   config.configuration.type_inference.type_inference_strategy,                       │
    │   117 │   │   query_type4py=config.configuration.type_inference.type4py,                         │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:1447 in                      │
    │ generate_test_cluster                                                                            │
    │                                                                                                  │
    │   1444 │   Returns:                                                                              │
    │   1445 │   │   A new test cluster for the given module                                           │
    │   1446 │   """                                                                                   │
    │ ❱ 1447 │   return analyse_module(                                                                │
    │   1448 │   │   parse_module(module_name, query_type4py=query_type4py),                           │
    │   1449 │   │   type_inference_strategy,                                                          │
    │   1450 │   │   query_type4py=query_type4py,                                                      │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:1422 in analyse_module       │
    │                                                                                                  │
    │   1419 │   │   A test cluster for the module                                                     │
    │   1420 │   """                                                                                   │
    │   1421 │   test_cluster = ModuleTestCluster(linenos=parsed_module.linenos)                       │
    │ ❱ 1422 │   __resolve_dependencies(                                                               │
    │   1423 │   │   root_module=parsed_module,                                                        │
    │   1424 │   │   type_inference_strategy=type_inference_strategy,                                  │
    │   1425 │   │   test_cluster=test_cluster,                                                        │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:1304 in                      │
    │ __resolve_dependencies                                                                           │
    │                                                                                                  │
    │   1301 │   │   )                                                                                 │
    │   1302 │   │                                                                                     │
    │   1303 │   │   # Analyze all functions found in the current module                               │
    │ ❱ 1304 │   │   __analyse_included_functions(                                                     │
    │   1305 │   │   │   module=current_module,                                                        │
    │   1306 │   │   │   root_module_name=root_module.module_name,                                     │
    │   1307 │   │   │   type_inference_strategy=type_inference_strategy,                              │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:1398 in                      │
    │ __analyse_included_functions                                                                     │
    │                                                                                                  │
    │   1395 │   │   │   func_name=current.__qualname__,                                               │
    │   1396 │   │   │   func=current,                                                                 │
    │   1397 │   │   │   type_inference_strategy=type_inference_strategy,                              │
    │ ❱ 1398 │   │   │   module_tree=parse_results[current.__module__].syntax_tree,                    │
    │   1399 │   │   │   type4py_data=parse_results[current.__module__].type4py_data,                  │
    │   1400 │   │   │   test_cluster=test_cluster,                                                    │
    │   1401 │   │   │   add_to_test=current.__module__ == root_module_name,                           │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:1248 in __missing__          │
    │                                                                                                  │
    │   1245 │                                                                                         │
    │   1246 │   def __missing__(self, key):                                                           │
    │   1247 │   │   # Parse module on demand                                                          │
    │ ❱ 1248 │   │   res = self[key] = parse_module(key, query_type4py=self._query_type4py)            │
    │   1249 │   │   return res                                                                        │
    │   1250                                                                                           │
    │   1251                                                                                           │
    │                                                                                                  │
    │ /home/lucas/Documents/GitHub/pynguin/src/pynguin/analyses/module.py:247 in parse_module          │
    │                                                                                                  │
    │    244 │   Returns:                                                                              │
    │    245 │   │   A tuple of the imported module type and its optional AST                          │
    │    246 │   """                                                                                   │
    │ ❱  247 │   module = importlib.import_module(module_name)                                         │
    │    248 │   type4py_data: Type4pyData | None = None                                               │
    │    249 │   syntax_tree: astroid.Module | None = None                                             │
    │    250 │   linenos: int = -1                                                                     │
    │                                                                                                  │
    │ /home/lucas/.conda/envs/2324-master-thesis/lib/python3.10/importlib/__init__.py:126 in           │
    │ import_module                                                                                    │
    │                                                                                                  │
    │   123 │   │   │   if character != '.':                                                           │
    │   124 │   │   │   │   break                                                                      │
    │   125 │   │   │   level += 1                                                                     │
    │ ❱ 126 │   return _bootstrap._gcd_import(name[level:], package, level)                            │
    │   127                                                                                            │
    │   128                                                                                            │
    │   129 _RELOADING = {}                                                                            │
    │ in _gcd_import:1050                                                                              │
    │ in _find_and_load:1027                                                                           │
    │ in _find_and_load_unlocked:1004                                                                  │
    ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
    ModuleNotFoundError: No module named 'numpy.char'

Expected behavior Pynguin should have generated a test for the function foo.

Software Version

stephanlukasczyk commented 7 months ago

Closed by merging #58 in 45483ab