mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-28 22:14:30 +00:00
138 lines
4.0 KiB
Python
138 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Test Generator — generate comprehensive tests for a Python module with a ReAct agent.
|
|
|
|
Usage::
|
|
|
|
python examples/code_companion/test_gen.py \
|
|
--module src/openjarvis/tools/calculator.py
|
|
python examples/code_companion/test_gen.py \
|
|
--module src/app/utils.py --framework unittest
|
|
python examples/code_companion/test_gen.py \
|
|
--module src/app/utils.py --output tests/test_utils.py
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import sys
|
|
|
|
import click
|
|
|
|
|
|
@click.command()
|
|
@click.option(
|
|
"--module",
|
|
required=True,
|
|
type=click.Path(exists=True),
|
|
help="Path to the Python module to generate tests for.",
|
|
)
|
|
@click.option(
|
|
"--framework",
|
|
default="pytest",
|
|
show_default=True,
|
|
type=click.Choice(["pytest", "unittest"], case_sensitive=False),
|
|
help="Test framework to target.",
|
|
)
|
|
@click.option(
|
|
"--output",
|
|
default=None,
|
|
type=click.Path(),
|
|
help=(
|
|
"File path to save generated tests. "
|
|
"Defaults to test_<module_name>.py in the current directory."
|
|
),
|
|
)
|
|
@click.option(
|
|
"--model",
|
|
default="qwen3:8b",
|
|
show_default=True,
|
|
help="Model to use for test generation.",
|
|
)
|
|
@click.option(
|
|
"--engine",
|
|
"engine_key",
|
|
default="ollama",
|
|
show_default=True,
|
|
help="Engine backend (ollama, cloud, vllm, etc.).",
|
|
)
|
|
def main(
|
|
module: str,
|
|
framework: str,
|
|
output: str | None,
|
|
model: str,
|
|
engine_key: str,
|
|
) -> None:
|
|
"""Generate comprehensive tests for a Python MODULE using a ReAct agent.
|
|
|
|
The agent reads the module source, reasons about edge cases and behavior,
|
|
and produces a complete test file. Tests are saved to a file or printed
|
|
to stdout.
|
|
"""
|
|
try:
|
|
from openjarvis import Jarvis
|
|
except ImportError:
|
|
click.echo(
|
|
"Error: openjarvis is not installed. "
|
|
"Install it with: uv sync --extra dev",
|
|
err=True,
|
|
)
|
|
sys.exit(1)
|
|
|
|
tools = ["file_read", "think", "file_write"]
|
|
|
|
# Derive default output path from the module name.
|
|
module_basename = os.path.basename(module).removesuffix(".py")
|
|
if output is None:
|
|
output = f"test_{module_basename}.py"
|
|
|
|
prompt = (
|
|
f"You are an expert Python test engineer. Generate comprehensive "
|
|
f"tests for the module at '{module}' using the **{framework}** "
|
|
f"framework.\n\n"
|
|
"Steps:\n"
|
|
f"1. Use file_read to read the source code of '{module}'.\n"
|
|
"2. Use think to plan test cases: happy paths, edge cases, error "
|
|
"handling, and boundary conditions.\n"
|
|
"3. Read any related modules or base classes if needed for context.\n"
|
|
f"4. Use file_write to save the generated tests to '{output}'.\n\n"
|
|
"Guidelines:\n"
|
|
"- Each public function/method should have at least one test.\n"
|
|
"- Include docstrings on each test explaining what it verifies.\n"
|
|
"- Test edge cases (empty input, None, large values, invalid types).\n"
|
|
"- Use mocks/patches for external dependencies.\n"
|
|
"- The test file must be self-contained and runnable.\n"
|
|
)
|
|
|
|
click.echo(f"Generating tests for: {module}")
|
|
click.echo(f"Framework: {framework} | Output: {output}")
|
|
click.echo(f"Model: {model} | Engine: {engine_key}")
|
|
click.echo("-" * 60)
|
|
|
|
try:
|
|
j = Jarvis(model=model, engine_key=engine_key)
|
|
except Exception as exc:
|
|
click.echo(
|
|
f"Error: could not initialize Jarvis — {exc}\n\n"
|
|
"Make sure your engine is running. For Ollama:\n"
|
|
" ollama serve\n"
|
|
" ollama pull qwen3:8b\n\n"
|
|
"For cloud engines, ensure API keys are set in your .env file.",
|
|
err=True,
|
|
)
|
|
sys.exit(1)
|
|
|
|
try:
|
|
response = j.ask(prompt, agent="native_react", tools=tools)
|
|
except Exception as exc:
|
|
click.echo(f"Error during test generation: {exc}", err=True)
|
|
sys.exit(1)
|
|
finally:
|
|
j.close()
|
|
|
|
click.echo(response)
|
|
click.echo(f"\nTests saved to: {output}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|