主要内容

polyspace.test.CoverageTestOptions Class

R2026b

Namespace: polyspace.test

(Python) Configure automatic test generation to meet coverage objectives

Since R2026b

Description

This Python® class configures automatic test generation to achieve specified structural coverage metrics (such as Decision, Condition, and MC/DC) and related objectives. Use this class with polyspace.test.generateTests to augment your tests for missing coverage.

Coverage-based test generation targets industry-standard metrics and can include relational boundary objectives (for example, for operators like >, ==). You can also set floating-point absolute and relative tolerances for comparisons used during objective satisfaction, and extend test generation using existing coverage results.

Creation

Description

opts = polyspace.test.CoverageTestOptions() creates a coverage test-generation options object opts with default property values.

example

Properties

expand all

The coverage metric level to target, specified as an enumeration member of the polyspace.project.CoverageMetricLevel class. The level determines which structural coverage goals the test generator attempts to satisfy.

ValueDescription
CoverageMetricLevel.DECISION

The generated tests achieve full decision coverage.

CoverageMetricLevel.CONDITION_DECISION

The generated tests achieve full condition coverage, in addition to full decision coverage.

CoverageMetricLevel.MCDC

The generated tests achieve full MC/DC coverage, in addition to full condition and decision coverage.

Whether to generate tests for full relational boundary coverage, specified as a Boolean. When this property is set to True, for each relational operator in the tested function such as == or <, the generated tests must test the operator with equal operand values and values that differ by a tolerance. The tolerance value is 1 for integers, and needs to be specified for floating-point numbers.

Absolute tolerance value for relational boundary coverage, specified as a floating-point number. The tolerance value applies only to relational operators that have floating-point operands.

Relative tolerance value for relational boundary coverage, specified as a floating-point number. The tolerance value applies only to relational operators that have floating-point operands.

Whether to limit test generation to satisfy coverage objectives only within the function under test instead of traversing into other reachable code, specified as a Boolean. Use this property to keep test scope focused.

Set a maximum test generation time in seconds. If the time limit is exceeded, test generator stops and returns any tests created up to that point.

Path to an existing coverage-results file (.psprof file) or a polyspace.test.CoverageResults object.

By default, the test generation process does not consider existing tests. In other words, even if the current tests satisfy some of the coverage objectives, the process generates as many tests as required for full coverage, ignoring the current tests in the project. Set this property if you want to generate additional tests after taking into account current tests.

Examples

collapse all

Generate tests that target full decision coverage for a function.

Create a project, add your source files, and parse the code. Then create options and generate tests for the saturate function. Finally, run the tests and verify that they have achieved full decision coverage for the saturate_value function.

## Import modules
import polyspace.project
import polyspace.test
import os

## Create project
examples_path = os.path.join(polyspace.__install_path__, "polyspace", 
                            "examples", "doc_pstest", "getting_started_test_manager")

proj = polyspace.project.Project("myProject.psprjx")

## Add source files and include path
proj.Code.Files.add(os.path.join(examples_path, "algo.c"))
proj.Code.Files.add(os.path.join(examples_path, "saturate.c"))
proj.IncludePaths.add(os.path.join(examples_path))

## Parse code - returned object contains list of functions and other source code data
codeInfo = polyspace.project.parseCode(proj)

## Get function
func = codeInfo.getFunctionBySignature("int saturate_value(int)")

## Set coverage objective to DECISION for test generation
cOpts = polyspace.test.CoverageTestOptions()
cOpts.Level = polyspace.project.CoverageMetricLevel.DECISION

## Set function-specific test generation options
cfg = polyspace.test.FunctionTestGenerationConfiguration(func)

## Set the coverage metric level to DECISION in active test configuration of the project
proj.ActiveTestConfiguration.CoverageOptions.Level = polyspace.project.CoverageMetricLevel.DECISION

## Generate tests
testGenResults = polyspace.test.generateTests(proj, cfg, cOpts)

## Run generated tests
testRunResults = polyspace.test.run(
      proj,
      ProfilingSelection=polyspace.test.ProfilingSelection.COVERAGE
)

# Read code coverage results
profilingResults = testRunResults.Profiling
coverageResults = profilingResults.Coverage

# Read decision coverage results
decisionCoverageResults = coverageResults.getCoverageInfo("decision")

# Loop through decision coverage details
# Raise exception if a decision in "saturate_value" is not fully covered
for details in decisionCoverageResults.Details:
    if (details.Function == "saturate_value") and not(details.IsCovered):
        raise RuntimeError("A decision in the target function is not fully covered.")

Inspect the contents of the decisionCoverageResults object. It shows full coverage for all decisions in the saturate_value function.

By default, the test generation process does not consider existing tests. To generate only as many tests as needed after taking into account existing tests, provide the coverage results based on existing tests.

Create a project, add your source files, and parse the code. Then add a test to your project that covers only one decision in the target function whichQuadrant partially. Run the user-added test and print coverage results.

## Import modules
import polyspace.project
import polyspace.test
import os

## Create project
examples_path = os.path.join(polyspace.__install_path__, "polyspace", 
                            "examples", "doc_pstest", "coverage_tests")

proj = polyspace.project.Project("myProject.psprjx")

## Add source file and include path
proj.Code.Files.add(os.path.join(examples_path, "src","example.c"))
proj.IncludePaths.add(os.path.join(examples_path, "src"))

## Parse code - returned object contains list of functions and other source code data
codeInfo = polyspace.project.parseCode(proj)

## Get function
func = codeInfo.getFunctionBySignature("uint32_t whichQuadrant(int32_t, int32_t)")

## Create test suite and test case
mySuite = proj.TestSuites.create("which_quadrant_tests")
simpleTest = mySuite.TestCases.create("which_quadrant_handwritten_test")

## Create test step for a simple test
simpleStep = simpleTest.TestSteps.createTabular("which_quadrant_simpleStep", func)

## Update inputs and assessments that are automatically created
simpleStep.Inputs["x"].Value = "1"
simpleStep.Inputs["y"].Value = "1"
simpleStep.Assessments["pst_call_out"].Value = "1u"

# Set the coverage metric level to DECISION in the active test configuration of the project
proj.ActiveTestConfiguration.CoverageOptions.Level = polyspace.project.CoverageMetricLevel.DECISION

## Run user-added test
testRunResults = polyspace.test.run(
      proj,
      ProfilingSelection=polyspace.test.ProfilingSelection.COVERAGE
)

## Read decision coverage results
coverageResults = testRunResults.Profiling.Coverage
decisionCoverageResults = coverageResults.getCoverageInfo("decision")

## Loop through decision coverage details and print coverage results
for details in decisionCoverageResults.Details:
    if (details.Function == "whichQuadrant"):
        percentCoverage = ((details.CoveredCount + details.JustifiedCount) / details.TotalCount)
        print(f"Coverage of '{details.Text}': {percentCoverage:.2%}")

You get an output like this:

Coverage of 'x > 0 && y > 0': 50.00%
Coverage of 'x < 0 && y > 0': 0.00%
Coverage of 'x < 0 && y < 0': 0.00%

Create test generation options and generate additional tests for the whichQuadrant function to achieve full decision coverage. Run all the tests (user-add and generated) and verify that they have achieved full decision coverage for the whichQuadrant function.

## Set coverage objective to DECISION for test generation
## Specify current coverage results object
cOpts = polyspace.test.CoverageTestOptions()
cOpts.Level = polyspace.project.CoverageMetricLevel.DECISION
cOpts.CurrentCoverageResults = coverageResults

## Set function-specific test generation options
cfg = polyspace.test.FunctionTestGenerationConfiguration(func)

# Generate tests
testGenResults = polyspace.test.generateTests(proj, cfg, cOpts)

# Run all (user-added and generated)  tests
testRunResults = polyspace.test.run(
      proj,
      ProfilingSelection=polyspace.test.ProfilingSelection.COVERAGE
)

## Read decision coverage results
coverageResults = testRunResults.Profiling.Coverage
decisionCoverageResults = coverageResults.getCoverageInfo("decision")

## Loop through decision coverage details and print coverage results
for details in decisionCoverageResults.Details:
    if (details.Function == "whichQuadrant"):
        percentCoverage = ((details.CoveredCount + details.JustifiedCount) / details.TotalCount)
        print(f"Coverage of '{details.Text}': {percentCoverage:.2%}")

You get an output that indicates that your test suites now achieve full decision coverage for the target function.

Coverage of 'x > 0 && y > 0': 100.00%
Coverage of 'x < 0 && y > 0': 100.00%
Coverage of 'x < 0 && y < 0': 100.00%

Version History

Introduced in R2026b