主要内容

polyspace.project.CallSequenceAssessment Class

R2026b

Namespace: polyspace.project

(Python) Access and configure function call sequence assessment for test step

Since R2026b

Description

This Python® class represents a function call sequence assessment for a test step. A call sequence assessment verifies that your code under test calls specific functions in a defined order during test execution. For each function in the sequence, you can optionally enable assessments for the input parameters passed to that function.

Each test step, whether tabular or scripted, can have one call sequence assessment. Use the CallSequenceAssessment property of a polyspace.project.TabularTestStep or polyspace.project.ScriptedTestStep object to access this class.

A function call sequence assessment fails when:

  • The functions are not called in the expected order.

  • One or more of the input parameter assessments fail.

Note

Function call sequences are strict. Once you include a function in the call sequence, the assessment checks for all calls to that function. If the function is called before, after, or in between the expected calls you specify, the call sequence assessment fails.

Creation

Description

callSeq = step.CallSequenceAssessment returns the CallSequenceAssessment object for a polyspace.project.TabularTestStep or polyspace.project.ScriptedTestStep object step. Each test step has exactly one CallSequenceAssessment object. You do not create this object directly. Instead, you access it from the test step and add function calls to it.

example

funcCall = step.CallSequenceAssessment.FunctionCalls.create(Fcn) creates a FunctionCallAssessment object and appends it to the end of the call sequence for the test step step. The argument Fcn is a polyspace.project.Function object obtained from parsing your source code. The order in which you create function calls defines the expected call order. Adding a function to the call sequence also creates assessments for all inputs to that function, but these input parameter assessments are disabled by default. For more information, see the FunctionCalls property.

example

Input Arguments

expand all

Function to add to the call sequence, specified as a polyspace.project.Function object. You can obtain the polyspace.project.Function object by parsing your source code and looking up the function signature. For example:

codeInfo = polyspace.project.parseCode(proj)
Fcn = codeInfo.getFunctionBySignature("CommStatus comm_open(CommChannel *, uint8_t)")

For more information, see polyspace.project.CodeInfo.

Properties

expand all

Ordered list of expected function calls in the call sequence assessment, specified as a polyspace.project.FunctionCallAssessmentList object. Each individual function call in the list is a polyspace.project.FunctionCallAssessment object that has these properties:

  • Function — Reference to the function that is expected to be called at this position in the sequence, specified as a polyspace.project.FunctionReference object. This property is read-only.

  • Assessments — List of input parameter assessments for this function call, specified as a polyspace.project.CallAssessmentList object. Each individual assessment is a polyspace.project.StepAssessment object with these properties:

    • Enabled — Option to use this assessment to determine if the test passes, specified as True or False. The default value is False.

    • Name — Name of the input parameter, specified as a string. This property is read-only.

    • Type — Data type of the input parameter, specified as a string. This property is read-only.

    • Value — Expected value of the input parameter, specified as a string.

    • Comparator — Comparator for the assessment, specified as a polyspace.project.AssessmentComparator enumeration class object. The default value is EQUAL. Other possible values are GREATER, GREATER_EQUAL, LESS, LESS_EQUAL, NONE, and NOT_EQUAL.

This table summarizes how to manage functions in the call sequence, where step is a polyspace.project.TabularTestStep or polyspace.project.ScriptedTestStep object.

Manage Functions in the Call Sequence

ActionCommand
Add function to sequence

Obtain a polyspace.project.CodeInfo object codeInfo by parsing your source code. Add a function to the end of the call sequence:

func = codeInfo.getFunctionBySignature("CommStatus comm_open(CommChannel *, uint8_t)")
step.CallSequenceAssessment.FunctionCalls.create(func)
Adding a function to the call sequence creates assessments for each input to that function. These input parameter assessments are disabled by default. For more information on enabling or modifying the input parameter assessments for each function call in the sequence, see Manage Parameter Assessments for Functions in the Call Sequence.

Access individual function call by index

step.CallSequenceAssessment.FunctionCalls[Idx]

Remove function from sequence
  • Remove a function call by index:

    step.CallSequenceAssessment.FunctionCalls.pop(Idx)
  • Remove the last function call:

    step.CallSequenceAssessment.FunctionCalls.pop()
Remove all function calls
step.CallSequenceAssessment.FunctionCalls.clear()

This table summarizes how to manage assessments on input parameters for a function call funcCall in a call sequence.

Manage Parameter Assessments for Functions in the Call Sequence

ActionCommand
Access individual assessments
  • Index using numeric location:

    funcCall.Assessments[Idx]
  • Index using the name of the input parameter:

    funcCall.Assessments["baud_rate"]
Enable an input assessment to check for an exact value

funcCall.Assessments["port"].Enabled = True
funcCall.Assessments["port"].Value = "2"

Create new input assessments to check for a range of values

Create additional assessments for the same parameter to check a range of values:

lower = funcCall.Assessments.create("port")
lower.Enabled = True
lower.Comparator = AssessmentComparator.GREATER_EQUAL
lower.Value = "1"

upper = funcCall.Assessments.create("port")
upper.Enabled = True
upper.Comparator = AssessmentComparator.LESS_EQUAL
upper.Value = "8"

Remove assessment
  • Remove an assessment by name:

    funcCall.Assessments.pop("port")

    If you were checking for a range of values and have multiple assessments for the same input parameter, removing an assessment by name removes all assessments with the specified name.

  • Remove an assessment by index:

    funcCall.Assessments.pop(Idx)
  • Remove the last assessment in the list:

    funcCall.Assessments.pop()
Remove all assessments
funcCall.Assessments.clear()

Examples

collapse all

Create a project that tests whether send_message calls comm_open, comm_configure, comm_transmit, and comm_close in the expected order, and verify the values of input parameters passed to each function.

This example uses the source files in the folder polyspaceroot\polyspace\examples\doc_pstest\call_sequence\src. Here, polyspaceroot is the Polyspace® installation folder, for instance, C:\Program Files\Polyspace\R2026b.

The header file comm_driver.h defines the data types and function prototypes and the source file comm_driver.c implements the communication driver.

Create a project, add the sources, and parse the code to obtain function handles.

import polyspace.project
import polyspace.test
import os

examples_path = os.path.join(polyspace.__install_path__, "polyspace",
                            "examples", "doc_pstest", "call_sequence", "src")

# Create project and add source files
proj = polyspace.project.Project("commDriverProject.psprjx")
proj.Code.Files.add(os.path.join(examples_path, "comm_driver.c"))
proj.IncludePaths.add(examples_path)

# Parse code and get function handles
codeInfo = polyspace.project.parseCode(proj)
send_message = codeInfo.getFunctionBySignature(
    "CommStatus send_message(uint8_t, uint32_t, const uint8_t *, uint16_t)")
comm_open = codeInfo.getFunctionBySignature(
    "CommStatus comm_open(CommChannel *, uint8_t)")
comm_configure = codeInfo.getFunctionBySignature(
    "CommStatus comm_configure(CommChannel *, uint32_t)")
comm_transmit = codeInfo.getFunctionBySignature(
    "CommStatus comm_transmit(CommChannel *, const uint8_t *, uint16_t)")
comm_close = codeInfo.getFunctionBySignature(
    "CommStatus comm_close(CommChannel *)")

Create a test case with a tabular step for send_message and set input values.

suite = proj.TestSuites.create("CommDriverSuite")
testCase = suite.TestCases.create("VerifyProtocolOrder")
step = testCase.TestSteps.createTabular("testSendMessage", send_message)
step.Inputs["port"].Value = "2"
step.Inputs["baud_rate"].Value = "115200"
step.Inputs["length"].Value = "3"

# Create a pointer target for the "data" input
dataType = codeInfo.getType("const uint8_t[3]")
dataTarget = testCase.TestData.create("dataInput", dataType)
for k, v in enumerate([0xAA, 0xBB, 0xCC]):
    dataTarget[k].Value = str(v)
step.Inputs["data"].Value = dataTarget

Add a call sequence assessment. The order in which you add function calls defines the expected call order.

step.CallSequenceAssessment.FunctionCalls.create(comm_open)
step.CallSequenceAssessment.FunctionCalls.create(comm_configure)
step.CallSequenceAssessment.FunctionCalls.create(comm_transmit)
step.CallSequenceAssessment.FunctionCalls.create(comm_close)

Enable the following input parameter assessments to verify the arguments passed to each function call.

openCall = step.CallSequenceAssessment.FunctionCalls[0]
openCall.Assessments["port"].Enabled = True
openCall.Assessments["port"].Value = "2"

configCall = step.CallSequenceAssessment.FunctionCalls[1]
configCall.Assessments["baud_rate"].Enabled = True
configCall.Assessments["baud_rate"].Value = "115200"

transmitCall = step.CallSequenceAssessment.FunctionCalls[2]
transmitCall.Assessments["length"].Enabled = True
transmitCall.Assessments["length"].Value = "3"

Run the test and filter the results using the InCallSequence property of the AssessmentResult object to show only call sequence assessment results.

res = polyspace.test.run(proj)
testCaseResult = res.TestSuiteResults[0].TestCaseResults[0]
stepResult = testCaseResult.TestStepResults[0]
callSeqResults = [a for a in stepResult.AssessmentResults if a.InCallSequence]
for r in callSeqResults:
    print(f"{r.Expression}: {'Passed' if r.Passed else 'Failed'}")

The output shows that the functions were called in the expected order and the input argument assessments passed:

Tests Summary
|            |      Total |     Passed |     Failed | Incomplete
|------------|------------|------------|------------|------------
|     Suites |          1 |          1 |          0 |          0
|      Tests |          1 |          1 |          0 |          0
Done running tests
comm_open(CommChannel *, uint8_t): Passed
  port == 2: Passed
comm_configure(CommChannel *, uint32_t): Passed
  baud_rate == 115200: Passed
comm_transmit(CommChannel *, const uint8_t *, uint16_t): Passed
  length == 3: Passed
comm_close(CommChannel *): Passed
Call Sequence: Passed

Limitations

To add a function to a call sequence, the function must be supported for mocking. For more information, see Identify Why Function Is Not Supported for Mocking.

Version History

Introduced in R2026b