Add an integration test for branch tracking
#
# SPDX-License-Identifier: LGPL-3.0-or-later
#
+import importlib
from unittest.mock import MagicMock
import pytest
@@ -11,6 +12,8 @@ from bytecode import BasicBlock, Instr
from pynguin.coverage.branch.branchcoveragegoal import Branch
from pynguin.coverage.branch.branchpool import INSTANCE
+from pynguin.instrumentation.branch_distance import BranchDistanceInstrumentation
+from pynguin.testcase.execution.executiontracer import ExecutionTracer
@pytest.fixture
@@ -24,6 +27,21 @@ def basic_block():
return MagicMock(BasicBlock)
+@pytest.fixture
+def simple_module():
+ simple = importlib.import_module("tests.fixtures.instrumentation.simple")
+ simple = importlib.reload(simple)
+ return simple
+
+
+@pytest.fixture
+def tracer_mock():
+ tracer = MagicMock(ExecutionTracer)
+ tracer.register_code_object.side_effect = range(100)
+ tracer.register_predicate.side_effect = range(100)
+ return tracer
+
+
def test_register_branchless_method(branch_pool):
branch_pool.register_branchless_function("foo", 42)
assert branch_pool.branchless_functions == {"foo"}
@@ -77,3 +95,35 @@ def test_get_branch_for_block_non_existing(branch_pool, basic_block):
def test_get_id_for_registered_block(branch_pool):
with pytest.raises(ValueError):
branch_pool._get_id_for_registered_block(None)
+
+
+@pytest.mark.parametrize(
+ "function_name, branchless_function_count, branches_count",
+ [
+ pytest.param("simple_function", 1, 0),
+ pytest.param("cmp_predicate", 0, 1),
+ pytest.param("bool_predicate", 0, 1),
+ pytest.param("for_loop", 0, 1),
+ pytest.param("full_for_loop", 0, 1),
+ pytest.param("multi_loop", 0, 3),
+ pytest.param("comprehension", 1, 2),
+ pytest.param("lambda_func", 1, 1),
+ pytest.param("conditional_assignment", 0, 1),
+ pytest.param("conditionally_nested_class", 2, 1),
+ ],
+)
+def test_integrate_branch_distance_instrumentation(
+ simple_module,
+ tracer_mock,
+ branch_pool,
+ function_name,
+ branchless_function_count,
+ branches_count,
+):
+ function_callable = getattr(simple_module, function_name)
+ instr = BranchDistanceInstrumentation(tracer_mock)
+ function_callable.__code__ = instr._instrument_code_recursive(
+ function_callable.__code__, True
+ )
+ assert branch_pool.get_num_branchless_functions() == branchless_function_count
+ assert len(list(branch_pool.all_branches)) == branches_count
