hbllmutils.entry.code.unittest

Unit test generation command-line interface for Python source files.

This module provides a CLI tool for generating comprehensive unit tests for Python source files using Large Language Models (LLMs). It supports multiple test frameworks (pytest, unittest, nose2) and offers extensive configuration options for customizing the test generation process.

The module contains the following main components:

  • generate_unittest_for_file() - Core function for generating unit tests for a single file

  • _get_llm_task() - Internal cached function for creating LLM task instances

  • _add_unittest_subcommand() - Registers the unittest CLI subcommand

Note

This module requires an LLM model configuration to function. Models can be specified via command-line arguments, environment variables, or configuration files.

Warning

Test generation may consume significant API tokens/credits depending on the complexity of the source code and the chosen LLM model.

Example:

>>> from hbllmutils.entry.code.unittest import generate_unittest_for_file
>>> 
>>> # Generate tests for a source file
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     test_file='tests/test_calculator.py',
...     model_name='gpt-4',
...     test_framework_name='pytest',
...     mark_name='unittest'
... )
>>> 
>>> # Save the generated test code
>>> with open('tests/test_calculator.py', 'w') as f:
...     f.write(test_code)

generate_unittest_for_file

hbllmutils.entry.code.unittest.generate_unittest_for_file(source_file: str, test_file: str | None = None, model_name: str | None = None, timeout: int = 240, extra_params: Dict[str, str | int | float] | None = None, show_module_directory_tree: bool = False, skip_when_error: bool = True, force_ast_check: bool = True, test_framework_name: Literal['pytest', 'unittest', 'nose2'] = 'pytest', mark_name: str | None = 'unittest', ignore_modules: Tuple[str, ...] | None = None, no_ignore_modules: Tuple[str, ...] | None = None) str[source]

Generate unit test code for a single Python file using LLM.

This function reads a Python source file and optionally an existing test file, then generates comprehensive unit tests using an LLM model. The generated test code follows the specified test framework conventions and can use existing tests as reference for style and patterns.

The function performs the following steps:

  1. Loads or creates an LLM task with the specified configuration

  2. Analyzes the source file to understand its structure and functionality

  3. Optionally uses an existing test file as a style reference

  4. Generates comprehensive unit tests covering the source code

  5. Returns the generated test code as a string

Parameters:
  • source_file (str) – Path to the Python source file to generate tests for. Must be a valid Python file that can be parsed.

  • test_file (Optional[str]) – Optional path to existing test file to use as reference for test style and patterns. If provided and exists, the LLM will attempt to match the existing test style.

  • model_name (Optional[str]) – Name of the LLM model to use (e.g., ‘gpt-4’, ‘claude-2’). If None, uses default from configuration or environment variables.

  • timeout (int) – Timeout in seconds for LLM API requests. Defaults to 240 seconds.

  • extra_params (Optional[Dict[str, Union[str, int, float]]]) – Additional parameters to pass to the LLM model as a dictionary. Common parameters include ‘max_tokens’, ‘temperature’, etc.

  • show_module_directory_tree (bool) – If True, include module directory tree in prompts to provide structural context about the package layout.

  • skip_when_error (bool) – If True, skip imports that fail to load during analysis instead of raising exceptions. Useful for handling optional dependencies.

  • force_ast_check (bool) – If True, validate generated code with AST parsing to ensure syntactic correctness before returning.

  • test_framework_name (Literal['pytest', 'unittest', 'nose2']) – The test framework to generate tests for. Must be one of ‘pytest’, ‘unittest’, or ‘nose2’.

  • mark_name (Optional[str]) – The pytest mark name to use for generated tests (e.g., ‘unittest’ will generate @pytest.mark.unittest decorators). If None or empty, no mark decorators will be added. Only applies to pytest framework.

  • ignore_modules (Optional[Tuple[str, ...]]) – Optional tuple of module names to explicitly ignore during dependency analysis regardless of download count or other criteria.

  • no_ignore_modules (Optional[Tuple[str, ...]]) – Optional tuple of module names that should never be ignored during dependency analysis regardless of download count or other filtering criteria.

Returns:

The generated unit test code as a string, with trailing whitespace removed

Return type:

str

Raises:
  • FileNotFoundError – If the specified source file does not exist

  • RuntimeError – If test generation fails due to LLM errors or configuration issues

  • ValueError – If model configuration is invalid

Note

The function uses LRU caching internally via _get_llm_task() to reuse task instances with identical configurations, improving performance when generating tests for multiple files.

Warning

Test generation may take significant time depending on source file complexity and LLM model response time. Consider using appropriate timeout values.

Example:

>>> from hbllmutils.entry.code.unittest import generate_unittest_for_file
>>> 
>>> # Basic usage
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     model_name='gpt-4'
... )
>>> print(test_code[:100])  # Preview generated code

>>> # With existing test file as reference
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     test_file='tests/test_calculator.py',
...     model_name='gpt-4'
... )

>>> # With custom parameters
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     model_name='gpt-4',
...     timeout=300,
...     extra_params={'max_tokens': 128000, 'temperature': 0.7},
...     test_framework_name='pytest',
...     mark_name='unittest'
... )

>>> # For unittest framework
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     model_name='gpt-4',
...     test_framework_name='unittest',
...     mark_name=None  # No marks for unittest
... )

>>> # With directory tree context
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     model_name='gpt-4',
...     show_module_directory_tree=True
... )

>>> # With module filtering
>>> test_code = generate_unittest_for_file(
...     source_file='mypackage/calculator.py',
...     model_name='gpt-4',
...     ignore_modules=('deprecated_module',),
...     no_ignore_modules=('mypackage.core',)
... )