testgenie-py 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. testgen/.coverage +0 -0
  2. testgen/analyzer/ast_analyzer.py +4 -1
  3. testgen/analyzer/fuzz_analyzer.py +2 -2
  4. testgen/analyzer/random_feedback_analyzer.py +3 -3
  5. testgen/analyzer/test_case_analyzer.py +2 -0
  6. testgen/code_to_test/__init__.py +0 -0
  7. testgen/code_to_test/boolean.py +146 -0
  8. testgen/code_to_test/calculator.py +29 -0
  9. testgen/code_to_test/code_to_fuzz.py +234 -0
  10. testgen/code_to_test/code_to_fuzz_lite.py +397 -0
  11. testgen/code_to_test/decisions.py +57 -0
  12. testgen/code_to_test/math_utils.py +47 -0
  13. testgen/code_to_test/sample_code_bin.py +141 -0
  14. testgen/controller/cli_controller.py +0 -1
  15. testgen/generated_boolean.py +48 -0
  16. testgen/reinforcement/agent.py +30 -26
  17. testgen/reinforcement/environment.py +7 -6
  18. testgen/reinforcement/statement_coverage_state.py +5 -3
  19. testgen/service/analysis_service.py +8 -6
  20. testgen/service/cfg_service.py +2 -0
  21. testgen/service/generator_service.py +6 -9
  22. testgen/service/logging_service.py +4 -2
  23. testgen/service/service.py +11 -20
  24. testgen/testgen.db +0 -0
  25. testgen/tests/__init__.py +0 -0
  26. testgen/tests/test_boolean.py +81 -0
  27. testgen/tests/test_generated_boolean.py +83 -0
  28. testgen/util/coverage_visualizer.py +5 -3
  29. testgen/util/file_utils.py +1 -1
  30. testgen/visualize/boolean_bin_and_coverage.png +0 -0
  31. testgen/visualize/boolean_bin_and_coverage_v1.png +0 -0
  32. testgen/visualize/boolean_bin_and_coverage_v2.png +0 -0
  33. testgen/visualize/boolean_bin_and_coverage_v3.png +0 -0
  34. testgen/visualize/boolean_bin_and_coverage_v4.png +0 -0
  35. testgen/visualize/boolean_bin_and_coverage_v5.png +0 -0
  36. testgen/visualize/boolean_bin_and_coverage_v6.png +0 -0
  37. testgen/visualize/boolean_bin_and_coverage_v7.png +0 -0
  38. testgen/visualize/boolean_bin_and_coverage_v8.png +0 -0
  39. testgen/visualize/boolean_bin_xor_coverage.png +0 -0
  40. testgen/visualize/boolean_bin_xor_coverage_v1.png +0 -0
  41. testgen/visualize/boolean_bin_xor_coverage_v2.png +0 -0
  42. testgen/visualize/boolean_bin_xor_coverage_v3.png +0 -0
  43. testgen/visualize/boolean_bin_xor_coverage_v4.png +0 -0
  44. testgen/visualize/boolean_bin_xor_coverage_v5.png +0 -0
  45. testgen/visualize/boolean_bin_xor_coverage_v6.png +0 -0
  46. testgen/visualize/boolean_bin_xor_coverage_v7.png +0 -0
  47. testgen/visualize/boolean_bin_xor_coverage_v8.png +0 -0
  48. testgen/visualize/boolean_status_flags_coverage.png +0 -0
  49. testgen/visualize/boolean_status_flags_coverage_v1.png +0 -0
  50. testgen/visualize/boolean_status_flags_coverage_v2.png +0 -0
  51. testgen/visualize/boolean_status_flags_coverage_v3.png +0 -0
  52. testgen/visualize/boolean_status_flags_coverage_v4.png +0 -0
  53. testgen/visualize/boolean_status_flags_coverage_v5.png +0 -0
  54. testgen/visualize/boolean_status_flags_coverage_v6.png +0 -0
  55. testgen/visualize/boolean_status_flags_coverage_v7.png +0 -0
  56. testgen/visualize/boolean_status_flags_coverage_v8.png +0 -0
  57. testgenie_py-0.2.4.dist-info/METADATA +139 -0
  58. testgenie_py-0.2.4.dist-info/RECORD +108 -0
  59. testgenie_py-0.2.2.dist-info/METADATA +0 -27
  60. testgenie_py-0.2.2.dist-info/RECORD +0 -67
  61. {testgenie_py-0.2.2.dist-info → testgenie_py-0.2.4.dist-info}/WHEEL +0 -0
  62. {testgenie_py-0.2.2.dist-info → testgenie_py-0.2.4.dist-info}/entry_points.txt +0 -0
@@ -4,6 +4,7 @@ from typing import List
4
4
 
5
5
  from testgen.models.test_case import TestCase
6
6
  from testgen.reinforcement.environment import ReinforcementEnvironment
7
+ from testgen.service.logging_service import get_logger
7
8
 
8
9
 
9
10
  class ReinforcementAgent:
@@ -13,6 +14,7 @@ class ReinforcementAgent:
13
14
  self.env = environment
14
15
  self.q_table = q_table if q_table else {}
15
16
  self.actions = ["add", "merge", "remove", "z3"]
17
+ self.logger = get_logger()
16
18
 
17
19
  def collect_test_cases(self) -> List[TestCase]:
18
20
  max_time = 30
@@ -50,7 +52,7 @@ class ReinforcementAgent:
50
52
  self.env.reset()
51
53
 
52
54
  current_state = self.env.get_state()
53
- print(f"Current state after reset: {current_state}")
55
+ self.logger.debug(f"Current state after reset: {current_state}")
54
56
 
55
57
  goal_state: float = 100.0
56
58
  steps_in_episode = 1
@@ -59,7 +61,7 @@ class ReinforcementAgent:
59
61
  start_time = time.time()
60
62
 
61
63
  while current_state[0] != goal_state and steps_in_episode < max_steps_per_episode and time.time() - start_time < max_time:
62
- print(f"Step {steps_in_episode} in episode {episode}")
64
+ print(f"\nStep {steps_in_episode} in episode {episode}")
63
65
 
64
66
  action = self.choose_action(current_state)
65
67
  next_state, reward = self.env.step(action)
@@ -77,10 +79,10 @@ class ReinforcementAgent:
77
79
  if current_state[0] > best_coverage:
78
80
  best_coverage = current_state[0]
79
81
  best_test_cases = self.env.test_cases.copy()
80
- print(f"New best coverage: {best_coverage}% with {len(best_test_cases)} test cases")
82
+ self.logger.debug(f"New best coverage: {best_coverage}% with {len(best_test_cases)} test cases")
81
83
  elif current_state[0] == best_coverage and len(best_test_cases) > len(self.env.test_cases):
82
84
  best_test_cases = self.env.test_cases.copy()
83
- print(f"New best coverage: {best_coverage}% with {len(best_test_cases)} test cases")
85
+ self.logger.debug(f"New best coverage: {best_coverage}% with {len(best_test_cases)} test cases")
84
86
 
85
87
  return best_test_cases
86
88
 
@@ -106,7 +108,29 @@ class ReinforcementAgent:
106
108
  print(f"CHOSEN EXPLOITATION ACTION: {chosen_action}")
107
109
  return chosen_action
108
110
 
109
- def optimize_test_suit(self, current_state, executable_statements):
111
+
112
+
113
+ @staticmethod
114
+ def get_action_list(test_case_length: int) -> List[str]:
115
+ action_list = ["add", "z3"]
116
+ if test_case_length >= 2:
117
+ action_list.extend(["merge", "remove"])
118
+ return action_list
119
+
120
+ def update_q_table(self, state: tuple, action: str, new_state:tuple, reward:float):
121
+ current_q = self.q_table.get((state, action), 0)
122
+ self.logger.debug(f"CURRENT Q: {current_q}")
123
+ valid_actions = self.get_action_list(new_state[1])
124
+
125
+ max_next_q = max(self.q_table.get((new_state, a), 0) for a in valid_actions)
126
+ self.logger.debug(f"MAX NEXT Q: {max_next_q}")
127
+
128
+ print(f"UPDATING Q TABLE FOR STATE: {state}, ACTION: {action} WITH REWARD: {reward}")
129
+ new_q = (1 - self.learning_rate) * current_q + self.learning_rate * (reward + max_next_q)
130
+
131
+ self.q_table[(state, action)] = new_q
132
+
133
+ """def optimize_test_suit(self, current_state, executable_statements):
110
134
  # Try to optimize test cases by repeatedly performing remove actions if reached full coverage
111
135
  test_case_count = current_state[1]
112
136
  optimization_attempts = min(10, test_case_count - 1)
@@ -130,24 +154,4 @@ class ReinforcementAgent:
130
154
  self.env.step("add")
131
155
  break
132
156
 
133
- return current_state
134
-
135
- @staticmethod
136
- def get_action_list(test_case_length: int) -> List[str]:
137
- action_list = ["add", "z3"]
138
- if test_case_length >= 2:
139
- action_list.extend(["merge", "remove"])
140
- return action_list
141
-
142
- def update_q_table(self, state: tuple, action: str, new_state:tuple, reward:float):
143
- current_q = self.q_table.get((state, action), 0)
144
- print(f"CURRENT Q: {current_q}")
145
- valid_actions = self.get_action_list(new_state[1])
146
-
147
- max_next_q = max(self.q_table.get((new_state, a), 0) for a in valid_actions)
148
- print(f"MAX NEXT Q: {max_next_q}")
149
-
150
- print(f"UPDATING Q TABLE FOR STATE: {state}, ACTION: {action} WITH REWARD: {reward}")
151
- new_q = (1 - self.learning_rate) * current_q + self.learning_rate * (reward + max_next_q)
152
-
153
- self.q_table[(state, action)] = new_q
157
+ return current_state"""
@@ -4,6 +4,7 @@ from typing import List, Tuple
4
4
 
5
5
  import coverage
6
6
 
7
+ from testgen.service.logging_service import get_logger
7
8
  import testgen.util.coverage_utils
8
9
  import testgen.util.file_utils
9
10
  from testgen.reinforcement.abstract_state import AbstractState
@@ -21,6 +22,7 @@ class ReinforcementEnvironment:
21
22
  self.test_cases = initial_test_cases.copy()
22
23
  self.state = state
23
24
  self.cov = coverage.Coverage()
25
+ self.logger = get_logger()
24
26
 
25
27
  # State represented by covered_statements, test_count
26
28
  def get_state(self) -> Tuple:
@@ -29,7 +31,7 @@ class ReinforcementEnvironment:
29
31
  def step(self, action) -> Tuple[Tuple, float]:
30
32
  prev_coverage = self.state.get_state()[0] # Get actual coverage before action
31
33
  prev_test_cases = self.state.get_state()[1]
32
- print(f"STEP: Previous coverage: {prev_coverage} before action: {action}")
34
+ self.logger.debug(f"STEP: Previous coverage: {prev_coverage} before action: {action}")
33
35
 
34
36
  # Execute action
35
37
  if action == "add":
@@ -62,8 +64,7 @@ class ReinforcementEnvironment:
62
64
  def render(self):
63
65
  pass
64
66
 
65
- @staticmethod
66
- def get_reward(coverage_delta, num_test_cases_delta) -> float:
67
+ def get_reward(self, coverage_delta, num_test_cases_delta) -> float:
67
68
  reward: float
68
69
  """
69
70
  Reward of 1.0 for increasing coverage
@@ -77,7 +78,7 @@ class ReinforcementEnvironment:
77
78
  else:
78
79
  reward = -1.0
79
80
 
80
- print(f"Coverage delta reward: {reward}")
81
+ self.logger.debug(f"Coverage delta reward: {reward}")
81
82
 
82
83
  """
83
84
  If new test cases are added, subtract a small penalty
@@ -86,7 +87,7 @@ class ReinforcementEnvironment:
86
87
  """
87
88
  test_cases_factor = (num_test_cases_delta * -0.1)
88
89
  reward = reward + test_cases_factor
89
- print(f"Reward or penalty added to coverage delta reward: {test_cases_factor}")
90
+ self.logger.debug(f"Reward or penalty added to coverage delta reward: {test_cases_factor}")
90
91
 
91
92
  print(f"Final reward {reward}")
92
93
  return reward
@@ -100,7 +101,7 @@ class ReinforcementEnvironment:
100
101
 
101
102
  executable_lines = set()
102
103
  if not test_cases:
103
- print("Warning: No test cases available to determine executable statements")
104
+ self.logger.debug("Warning: No test cases available to determine executable statements")
104
105
  from testgen.util.randomizer import new_random_test_case
105
106
  temp_case = new_random_test_case(self.file_name, self.class_name, self.fut)
106
107
  analysis = testgen.util.coverage_utils.get_coverage_analysis(self.file_name, self.class_name, self.fut.name, temp_case.inputs)
@@ -1,11 +1,13 @@
1
1
  from typing import Tuple
2
2
 
3
+ from testgen.service.logging_service import get_logger
3
4
  import testgen.util.coverage_utils
4
5
  from testgen.reinforcement.abstract_state import AbstractState
5
6
  from testgen.util import utils
6
7
 
7
8
  class StatementCoverageState(AbstractState):
8
9
  def __init__(self, environment):
10
+ self.logger = get_logger()
9
11
  self.environment = environment
10
12
 
11
13
  def get_state(self) -> Tuple[float, int]:
@@ -23,9 +25,9 @@ class StatementCoverageState(AbstractState):
23
25
  else:
24
26
  calc_coverage: float = (len(all_covered_statements) / len(executable_statements)) * 100
25
27
 
26
- print(f"GET STATE ALL COVERED STATEMENTS: {all_covered_statements}")
27
- print(f"GET STATE ALL EXECUTABLE STATEMENTS: {self.environment.get_all_executable_statements()}")
28
- print(f"GET STATE FLOAT COVERAGE: {calc_coverage}")
28
+ self.logger.debug(f"GET STATE ALL COVERED STATEMENTS: {all_covered_statements}")
29
+ self.logger.debug(f"GET STATE ALL EXECUTABLE STATEMENTS: {self.environment.get_all_executable_statements()}")
30
+ self.logger.debug(f"GET STATE FLOAT COVERAGE: {calc_coverage}")
29
31
 
30
32
  if calc_coverage >= 100:
31
33
  print(f"!!!!!!!!FULLY COVERED FUNCTION: {self.environment.fut.name}!!!!!!!!")
@@ -5,6 +5,7 @@ from types import ModuleType
5
5
  from typing import Dict, List
6
6
 
7
7
  import testgen
8
+ from testgen.service.logging_service import get_logger
8
9
  import testgen.util.file_utils
9
10
  import testgen.util.file_utils as file_utils
10
11
  import testgen.util.utils
@@ -32,6 +33,7 @@ class AnalysisService:
32
33
  self.test_case_analyzer_context = TestCaseAnalyzerContext(None, None)
33
34
  self.test_strategy = 0
34
35
  self.reinforcement_mode = "train"
36
+ self.logger = get_logger()
35
37
 
36
38
  def generate_test_cases(self) -> List[TestCase]:
37
39
  """Generate test cases using the current strategy."""
@@ -43,15 +45,15 @@ class AnalysisService:
43
45
 
44
46
  def create_analysis_context(self, filepath: str) -> AnalysisContext:
45
47
  """Create an analysis context for the given file."""
46
- print(f"Creating analysis context for {filepath}")
48
+ self.logger.debug(f"Creating analysis context for {filepath}")
47
49
  filename = file_utils.get_filename(filepath)
48
- print(f"Filename: {filename}")
50
+ self.logger.debug(f"Filename: {filename}")
49
51
  module = file_utils.load_module(filepath)
50
- print(f"Module: {module}")
52
+ self.logger.debug(f"Module: {module}")
51
53
  class_name = self.get_class_name(module)
52
- print(f"Class name: {class_name}")
54
+ self.logger.debug(f"Class name: {class_name}")
53
55
  function_data = self.get_function_data(filename, module, class_name)
54
- print(f"Function data: {function_data}")
56
+ self.logger.debug(f"Function data: {function_data}")
55
57
  return AnalysisContext(filepath, filename, class_name, module, function_data)
56
58
 
57
59
  def get_function_data(self, filename: str, module: ModuleType, class_name: str | None) -> List[FunctionMetadata]:
@@ -113,7 +115,7 @@ class AnalysisService:
113
115
  new_test_cases = agent.collect_test_cases()
114
116
  function_test_cases.extend(new_test_cases)
115
117
 
116
- print(f"\nTest cases for {function.name}: {len(function_test_cases)}")
118
+ print(f"\nNumber of test cases for {function.name}: {len(function_test_cases)}")
117
119
 
118
120
  current_coverage: float = environment.run_tests()
119
121
  print(f"Current coverage: {function.name}: {current_coverage}")
@@ -1,6 +1,7 @@
1
1
  import os
2
2
  from typing import List
3
3
  from testgen.models.test_case import TestCase
4
+ from testgen.service.logging_service import get_logger
4
5
  from testgen.util.coverage_visualizer import CoverageVisualizer
5
6
  from testgen.service.analysis_service import AnalysisService
6
7
 
@@ -10,6 +11,7 @@ class CFGService:
10
11
  def __init__(self):
11
12
  self.analysis_service = AnalysisService()
12
13
  self.visualizer = None
14
+ self.logger = get_logger()
13
15
 
14
16
  def initialize_visualizer(self, service):
15
17
  self.visualizer = CoverageVisualizer()
@@ -9,6 +9,7 @@ from testgen.generator.doctest_generator import DocTestGenerator
9
9
  from testgen.generator.pytest_generator import PyTestGenerator
10
10
  from testgen.generator.unit_test_generator import UnitTestGenerator
11
11
  from testgen.inspector.inspector import Inspector
12
+ from testgen.service.logging_service import get_logger
12
13
  from testgen.tree.node import Node
13
14
  from testgen.tree.tree_utils import build_binary_tree
14
15
  from testgen.models.generator_context import GeneratorContext
@@ -26,18 +27,19 @@ class GeneratorService:
26
27
  self.code_generator = CodeGenerator()
27
28
  self.test_generator = UnitTestGenerator(generator_context=None)
28
29
  self.generated_file_path = None
30
+ self.logger = get_logger()
29
31
 
30
32
  def set_test_format(self, test_format: int):
31
33
  """Set the test generator format."""
32
34
  self.test_format = test_format
33
35
  if test_format == UNITTEST_FORMAT:
34
- print("SETTING TEST FORMAT TO UNITTEST")
36
+ self.logger.debug("SETTING TEST FORMAT TO UNITTEST")
35
37
  self.test_generator = UnitTestGenerator(generator_context=None)
36
38
  elif test_format == PYTEST_FORMAT:
37
- print("SETTING TEST FORMAT TO PYTEST")
39
+ self.logger.debug("SETTING TEST FORMAT TO PYTEST")
38
40
  self.test_generator = PyTestGenerator(generator_context=None)
39
41
  elif test_format == DOCTEST_FORMAT:
40
- print("SETTING TEST FORMAT TO DOCTEST")
42
+ self.logger.debug("SETTING TEST FORMAT TO DOCTEST")
41
43
  self.test_generator = DocTestGenerator(generator_context=None)
42
44
  else:
43
45
  raise NotImplementedError(f"Test format {test_format} not implemented")
@@ -69,16 +71,11 @@ class GeneratorService:
69
71
 
70
72
  self.test_generator.generate_test_header()
71
73
 
72
- print("GENERATE TEST FILE: Generated test header")
73
-
74
74
  self.generate_function_tests(test_cases)
75
75
 
76
- print("GENERATE TEST FILE: Generate function tests")
77
-
78
- print()
79
76
 
80
77
  if self.test_format == DOCTEST_FORMAT:
81
- print("SAVING DOCT TEST FILE")
78
+ self.logger.debug("SAVING DOCT TEST FILE")
82
79
  self.test_generator.save_file()
83
80
  return self.filepath
84
81
  else:
@@ -15,7 +15,6 @@ class LogLevel(Enum):
15
15
 
16
16
  class LoggingService:
17
17
  """Centralized logging service for testgen framework"""
18
-
19
18
  _instance = None
20
19
  _initialized = False
21
20
 
@@ -42,6 +41,8 @@ class LoggingService:
42
41
  """Initialize the logging service"""
43
42
  if LoggingService._initialized:
44
43
  return
44
+
45
+ self.debug_mode = debug_mode
45
46
 
46
47
  # Set the base logging level
47
48
  level = LogLevel.DEBUG.value if debug_mode else LogLevel.INFO.value
@@ -69,7 +70,8 @@ class LoggingService:
69
70
 
70
71
  def debug(self, message: str):
71
72
  """Log debug message"""
72
- self.logger.debug(message)
73
+ if self.debug_mode:
74
+ self.logger.debug(message)
73
75
 
74
76
  def info(self, message: str):
75
77
  """Log info message"""
@@ -36,7 +36,6 @@ DOCTEST_FORMAT = 3
36
36
 
37
37
  class Service:
38
38
  def __init__(self):
39
- self.debug_mode: bool = False
40
39
  self.test_strategy: int = 0
41
40
  self.test_format: int = 0
42
41
  self.file_path = None
@@ -78,7 +77,7 @@ class Service:
78
77
  test_cases = self.analysis_service.generate_test_cases()
79
78
 
80
79
  if os.environ.get("RUNNING_IN_DOCKER") is not None:
81
- self.debug(f"Serializing test cases {test_cases}")
80
+ self.logger.debug(f"Serializing test cases {test_cases}")
82
81
  self.serialize_test_cases(test_cases)
83
82
  return None # Exit early in analysis-only mode
84
83
 
@@ -151,7 +150,7 @@ class Service:
151
150
  """Run coverage analysis on the generated tests."""
152
151
  Service.wait_for_file(test_file)
153
152
  file_path_to_use = self.generated_file_path if self.test_strategy == AST_STRAT else self.file_path
154
- print(f"File path to use for coverage: {file_path_to_use}")
153
+ self.logger.debug(f"File path to use for coverage: {file_path_to_use}")
155
154
  coverage_output = ""
156
155
 
157
156
  try:
@@ -179,7 +178,7 @@ class Service:
179
178
  """Parse coverage output and save to database."""
180
179
  # Skip if running in Docker or DB service is None
181
180
  if os.environ.get("RUNNING_IN_DOCKER") is not None or self.db_service is None:
182
- self.debug("Skipping database operations in Docker container")
181
+ self.logger.debug("Skipping database operations in Docker container")
183
182
  return
184
183
 
185
184
  try:
@@ -370,27 +369,26 @@ class Service:
370
369
  functions = inspect.getmembers(cls, inspect.isfunction)
371
370
  return functions
372
371
 
373
- @staticmethod
374
- def resolve_module_path(module_name):
372
+ def resolve_module_path(self, module_name):
375
373
  """Resolve a module name to its file path by checking multiple locations."""
376
374
  direct_path = f"/controller/{module_name}.py"
377
375
  if os.path.exists(direct_path):
378
- print(f"Found module at {direct_path}")
376
+ self.logger.debug(f"Found module at {direct_path}")
379
377
  return direct_path
380
378
 
381
379
  testgen_path = f"/controller/testgen/{module_name}.py"
382
380
  if os.path.exists(testgen_path):
383
- print(f"Found module at {testgen_path}")
381
+ self.logger.debug(f"Found module at {testgen_path}")
384
382
  return testgen_path
385
383
 
386
384
  if '.' in module_name:
387
385
  parts = module_name.split('.')
388
386
  potential_path = os.path.join('/controller', *parts) + '.py'
389
387
  if os.path.exists(potential_path):
390
- print(f"Found module at {potential_path}")
388
+ self.logger.debug(f"Found module at {potential_path}")
391
389
  return potential_path
392
390
 
393
- print(f"Could not find module: {module_name}")
391
+ self.logger.debug(f"Could not find module: {module_name}")
394
392
  return None
395
393
 
396
394
  def visualize_test_coverage(self):
@@ -408,13 +406,6 @@ class Service:
408
406
  if hasattr(self ,'analysis_service'):
409
407
  self.analysis_service.set_reinforcement_mode(mode)
410
408
 
411
- def set_debug_mode(self, debug: bool):
412
- self.debug_mode = debug
413
-
414
- def debug(self, message: str):
415
- if self.debug_mode:
416
- self.logger.debug(message)
417
-
418
409
  def _get_test_case_id(self, test_case_name: str) -> int:
419
410
  """
420
411
  Retrieve the test case ID from the database based on the test case name.
@@ -464,13 +455,13 @@ class Service:
464
455
  def execute_and_store_unittest(self, file_path_to_use, test_file):
465
456
  import unittest
466
457
  loader = unittest.TestLoader()
467
- print(f"Discovering tests in: {os.path.dirname(file_path_to_use)} with pattern: {os.path.basename(test_file)}")
458
+ self.logger.debug(f"Discovering tests in: {os.path.dirname(file_path_to_use)} with pattern: {os.path.basename(test_file)}")
468
459
  test_module = os.path.relpath(test_file,
469
460
  start=os.getcwd()) # Get relative path from the current working directory
470
461
  test_module = test_module.replace("/", ".").replace("\\", ".").rstrip(".py") # Convert to module name
471
462
  if test_module.startswith("."):
472
463
  test_module = test_module[1:] # Remove leading dot if present
473
- print(f"Test module: {test_module}")
464
+ self.logger.debug(f"Test module: {test_module}")
474
465
  suite = loader.loadTestsFromName(test_module)
475
466
  runner = unittest.TextTestRunner()
476
467
  result = runner.run(suite)
@@ -506,7 +497,7 @@ class Service:
506
497
 
507
498
  results = self.db_service.get_test_file_data(test_file_name)
508
499
  if not results:
509
- print(f"No data found for file: {test_file_name}")
500
+ self.logger.debug(f"No data found for file: {test_file_name}")
510
501
  return
511
502
 
512
503
  from tabulate import tabulate
testgen/testgen.db ADDED
Binary file
File without changes
@@ -0,0 +1,81 @@
1
+ import pytest
2
+
3
+ import testgen.code_to_test.boolean as boolean
4
+
5
+ def test_bin_and_0():
6
+ args = (False, False)
7
+ expected = False
8
+ result = boolean.bin_and(*args)
9
+ assert result == expected
10
+
11
+ def test_bin_and_1():
12
+ args = (True, True)
13
+ expected = True
14
+ result = boolean.bin_and(*args)
15
+ assert result == expected
16
+
17
+ def test_bin_and_2():
18
+ args = (True, False)
19
+ expected = False
20
+ result = boolean.bin_and(*args)
21
+ assert result == expected
22
+
23
+ def test_bin_xor_3():
24
+ args = (False, True)
25
+ expected = True
26
+ result = boolean.bin_xor(*args)
27
+ assert result == expected
28
+
29
+ def test_bin_xor_4():
30
+ args = (False, False)
31
+ expected = False
32
+ result = boolean.bin_xor(*args)
33
+ assert result == expected
34
+
35
+ def test_bin_xor_5():
36
+ args = (True, True)
37
+ expected = False
38
+ result = boolean.bin_xor(*args)
39
+ assert result == expected
40
+
41
+ def test_bin_xor_6():
42
+ args = (True, False)
43
+ expected = True
44
+ result = boolean.bin_xor(*args)
45
+ assert result == expected
46
+
47
+ def test_status_flags_7():
48
+ args = (True, False, True)
49
+ expected = 'admin-unverified'
50
+ result = boolean.status_flags(*args)
51
+ assert result == expected
52
+
53
+ def test_status_flags_8():
54
+ args = (True, True, False)
55
+ expected = 'user-verified'
56
+ result = boolean.status_flags(*args)
57
+ assert result == expected
58
+
59
+ def test_status_flags_9():
60
+ args = (False, True, True)
61
+ expected = 'admin-verified'
62
+ result = boolean.status_flags(*args)
63
+ assert result == expected
64
+
65
+ def test_status_flags_10():
66
+ args = (True, True, True)
67
+ expected = 'admin-verified'
68
+ result = boolean.status_flags(*args)
69
+ assert result == expected
70
+
71
+ def test_status_flags_11():
72
+ args = (True, False, False)
73
+ expected = 'user-unverified'
74
+ result = boolean.status_flags(*args)
75
+ assert result == expected
76
+
77
+ def test_status_flags_12():
78
+ args = (False, True, False)
79
+ expected = 'inactive'
80
+ result = boolean.status_flags(*args)
81
+ assert result == expected
@@ -0,0 +1,83 @@
1
+ import unittest
2
+
3
+ import testgen.generated_boolean as generated_boolean
4
+
5
+ class TestNone(unittest.TestCase):
6
+
7
+ def test_bin_and_0(self):
8
+ args = (True, True)
9
+ expected = True
10
+ result = generated_boolean.bin_and(*args)
11
+ self.assertEqual(result, expected)
12
+
13
+ def test_bin_and_1(self):
14
+ args = (True, False)
15
+ expected = False
16
+ result = generated_boolean.bin_and(*args)
17
+ self.assertEqual(result, expected)
18
+
19
+ def test_bin_and_2(self):
20
+ args = (False, True)
21
+ expected = False
22
+ result = generated_boolean.bin_and(*args)
23
+ self.assertEqual(result, expected)
24
+
25
+ def test_bin_xor_3(self):
26
+ args = (True, True)
27
+ expected = False
28
+ result = generated_boolean.bin_xor(*args)
29
+ self.assertEqual(result, expected)
30
+
31
+ def test_bin_xor_4(self):
32
+ args = (True, False)
33
+ expected = True
34
+ result = generated_boolean.bin_xor(*args)
35
+ self.assertEqual(result, expected)
36
+
37
+ def test_bin_xor_5(self):
38
+ args = (False, True)
39
+ expected = True
40
+ result = generated_boolean.bin_xor(*args)
41
+ self.assertEqual(result, expected)
42
+
43
+ def test_status_flags_6(self):
44
+ args = (True, True, True)
45
+ expected = 'admin-verified'
46
+ result = generated_boolean.status_flags(*args)
47
+ self.assertEqual(result, expected)
48
+
49
+ def test_status_flags_7(self):
50
+ args = (True, True, False)
51
+ expected = 'user-verified'
52
+ result = generated_boolean.status_flags(*args)
53
+ self.assertEqual(result, expected)
54
+
55
+ def test_status_flags_8(self):
56
+ args = (True, False, True)
57
+ expected = 'admin-unverified'
58
+ result = generated_boolean.status_flags(*args)
59
+ self.assertEqual(result, expected)
60
+
61
+ def test_status_flags_9(self):
62
+ args = (True, False, False)
63
+ expected = 'user-unverified'
64
+ result = generated_boolean.status_flags(*args)
65
+ self.assertEqual(result, expected)
66
+
67
+ def test_status_flags_10(self):
68
+ args = (False, True, True)
69
+ expected = 'admin-verified'
70
+ result = generated_boolean.status_flags(*args)
71
+ self.assertEqual(result, expected)
72
+
73
+ def test_status_flags_11(self):
74
+ args = (False, True, False)
75
+ expected = 'inactive'
76
+ result = generated_boolean.status_flags(*args)
77
+ self.assertEqual(result, expected)
78
+
79
+ def test_status_flags_12(self):
80
+ args = (False, False, True)
81
+ expected = 'admin-unverified'
82
+ result = generated_boolean.status_flags(*args)
83
+ self.assertEqual(result, expected)
@@ -3,6 +3,7 @@ import os
3
3
  from typing import Dict, List, Set
4
4
  import coverage
5
5
 
6
+ from testgen.service.logging_service import get_logger
6
7
  import testgen.util.coverage_utils
7
8
  from testgen.models.test_case import TestCase
8
9
  import pygraphviz as pgv
@@ -12,6 +13,7 @@ class CoverageVisualizer:
12
13
  self.service = None
13
14
  self.cov = coverage.Coverage(branch=True)
14
15
  self.covered_lines: Dict[str, Set[int]] = {}
16
+ self.logger = get_logger()
15
17
 
16
18
  def set_service(self, service):
17
19
  self.service = service
@@ -27,9 +29,9 @@ class CoverageVisualizer:
27
29
  self.covered_lines[func_def.name].update(covered)
28
30
 
29
31
  if func_def.name in self.covered_lines:
30
- print(f"Covered lines for {func_def.name}: {self.covered_lines[func_def.name]}")
32
+ self.logger.debug(f"Covered lines for {func_def.name}: {self.covered_lines[func_def.name]}")
31
33
  else:
32
- print(f"No coverage data found for {func_def.name}")
34
+ self.logger.debug(f"No coverage data found for {func_def.name}")
33
35
 
34
36
  def generate_colored_cfg(self, function_name, output_path):
35
37
  """Generate colored CFG for a function showing test coverage"""
@@ -54,7 +56,7 @@ class CoverageVisualizer:
54
56
  try:
55
57
  tree = ast.parse(source_code)
56
58
  ast_functions = [node.name for node in ast.walk(tree) if isinstance(node, ast.FunctionDef)]
57
- print(f"Functions found by AST: {ast_functions}")
59
+ self.logger.debug(f"Functions found by AST: {ast_functions}")
58
60
 
59
61
  return self._create_basic_cfg(source_code, function_name, output_path)
60
62
 
@@ -55,7 +55,7 @@ def get_import_info(filepath: str) -> Dict[str, str]:
55
55
  'file_dir': file_dir
56
56
  }
57
57
 
58
- print(f"INFO: {info}")
58
+ #print(f"INFO: {info}")
59
59
 
60
60
  return info
61
61