In this section:
Generating Test Suites
A test suite is a container for test cases and must be created before test cases can be added:
- Choose Parasoft> Show View> Test Case Explorer to open the Test Case Explorer view
- Choose a project in the Test Case Explorer tree
- Choose Parasoft> Test Using> Builtin> Unit Testing> Generate Test Suites to generate empty test suites for the project
You can also add an empty test suite manually by right-clicking on a project or folder in the Test Case Explorer and choosing Add New> Test Suite
Test Suite Data Storage
All test suite data (including test cases) is stored in a test suite file located under the C++test Project directory. This file and other C++test-generated test artifacts should be managed within a Software Configuration Management system.
Editing Test Suites
- Double-click a test suite in the Test Case Explorer tree to open the Test Suite Editor
- Click in a field of the Globals editor to configure global variables for the test suite (see Test Case Steps Reference, for more details). These variables be used in test cases later.
- Choose File> Save to save test suite after changes
The updated test suite is ready to be executed.
Creating Test Cases
- Open the Test Case Explorer and right-click on a test suite
- Choose Add New> Test Case using Editor…
- When prompted, enter test case name and click OK; an empty Test Case Editor opens
- Choose a function from the Create test case for drop-down list and click (+) button; a default test case for selected function opens
- Review and modify input values (Variables) and expected output values (Assertions); see Default Test Case, for more information on the structure of the default test case
- Save the test case to add it to the test suite
The new test case will appear in the Test Case Explorer tree and can be executed. See Executing Test Cases, for instructions on running test cases.
Default Test Case
The default test case represents a standard test case for a given function. It contains the following steps that will be executed in the order described below when you run the test case:
- Variables: All required input values (pre-conditions) will be set. Input values include global variables, local variables (parameters to tested function), and test object (when testing member functions). By default, standard values for a given type (0, null, default constructor, etc.) will be used as input values to be reviewed/modified by the test case author.
- Call: The tested function will be called using pre-condition values set in the Variables step.
- Assertions: The actual output values will be compared against expected values (post-conditions). Output values include function return value, global variables, and member variables (when testing member functions). By default, standard values for a given type (0, null etc.) will be used as expected values to be reviewed/modified by the test case author.
You can also customize the structure of your test cases. See Working with Steps.
Editing Test Cases with the Test Case Editor
Only test cases created with Test Case Editor (see Creating Test Cases) can be edited with the editor. Automatically generated test cases (see Generating Test Cases), test cases created in the Code Editor, or test cases created with the Test Case Wizard (see Adding Test Suites and Test Cases with the Graphical Test Case Wizard) are not editable with the Test Case Editor.
- Open the Test Case Explorer view and double-click a test case
- Modify the test case structure or specific parameters (see Working with Steps)
- Choose File> Save to save your changes to the test case
Working with Steps
In the Test Case Editor, each test case is represented by a sequence of steps. During runtime, the steps are executed in order from top to bottom as defined in the Editor. Various steps are available in the Editor that implement a particular functionality:
- Variables: set-up input values
- Call: call tested function
- Assertions: verify post-condition values
- Reports: report test case values
- Stubs: configure stub
- Parameters: enable test case parameterization
- Code: insert custom code snippet
See Test Case Steps Reference for more details on available Steps.
The default test case uses only a subset of available steps (see Default Test Case). If needed, you can customize a test case to implement a specific scenario by defining the test case flow with various steps configured in the desired order. For example, additional Stubs configuration can be performed prior to executing a sequence of function Calls. Additionally, specific input/output values can be reported.
Adding a New Step
- In the Test Case Editor, choose a step from the Add new drop-down menu
- Click (+) button; the new step will be appended to the test case
- Click and drag steps to reorder them as needed
Removing an Existing Step
In the Test Case Editor, click (-) button next to a step. The step will be removed from the test case.
Reordering Steps
In the Test Case Editor, click on a step handle (four-way arrow) to drag and drop steps into order.
Duplicating Steps
In the Test Case Editor, click on a step handle (four-way arrow) to drag and drop a step while pressing the CTRL key.
Copying Steps from Another Test Case
- Open two Test Case Editor windows and place them side-by-side.
- Click on a step handle (four-way arrow) and drag the step from one editor to the other.
Typical Test Case Customizations
Configuring Stub Behavior
You may need to configure stub behavior to implement certain testing scenarios and to ensure a consistent runtime environment. Using the Dynamic Stub Configuration feature, you can place stub configurations directly into the test case definition, so each test case may have its own unique stub configuration. The Test Case Editor provides a dedicated step for stub configuration. You can configure stubs for setting up a desired return value of the stub, switch between stub and original, and more.
Additional Details about Stub Behavior Configuration
- The stub function must have been auto-generated or manually created using C++test 10.3 or later to configure stub behavior.
- Available stub functions are presented in the Stubs view (Parasoft> Show View> Stubs).
- Stub functions that are not configured in a test case (with Stubs step) will behave according to the stub definition (auto-generated stub will return default value: 0, false, null).
- Stubs steps must be placed before the Call step that the stub configuration is intended to use.
Supported Stubs Step Configuration Actions
Modifying Return Value for Functions Returning Simple Type Values
- Select SET RETURN VALUE from the Action drop-down list
- Specify a function name in the Function column - be sure that the stub function exists
- Specify the return value in the Parameters column
- (Optional) Specify condition for when the value should be returned (Condition column)
If multiple SET RETURN VALUE actions are specified, they will be processed from top to bottom. The last action that meets the condition will take effect.
If the CALL ORIGINAL action is also specified for a given function and condition, it will override the SET RETURN VALUE action and the original function will be called.
For modifying complex type return values, use the CUSTOM ACTION with the approach described in Basic Approach to Working with Complex Types.
Modifying Stub Parameters for Simple Type Values
- Select SET PARAMETERS from the Action drop-down list
- Specify a function name in the Function column - be sure that the stub function exists
Specify stub parameters in the Parameters column using
<stub parameter name>=<value>
syntax. A semicolon-separated list is also supported. Examples:paramA=100; paramB=localVar; paramC=ByRef(globalVar) arrayParamD[3]=10
- (Optional) Specify condition for when the parameters should be modified (Condition column)
If multiple SET PARAMETERS actions are specified for the same parameter, they will be processed from top to bottom. The last action that meets the condition will take effect.
If the CALL ORIGINAL action is also specified for a given function and condition, the original function will be called with modified parameters.
For modifying complex type parameters, use the CUSTOM ACTION with the approach described in the Basic Approach to Working with Complex Types.
Calling Original Function for Functions with Original Definition Available
- Select CALL ORIGINAL from the Action drop-down list
- Specify a function name in the Function column - be sure stub function exists
- (Optional) Specify a condition for when the original function should be called (Condition column)
Configuring Expected Number of Calls
- Select EXPECT NUMBER OF CALLS from the Action drop-down list
- Specify a function name in the Function column - be sure stub function exists
- Specify the expected number of calls in the Parameters column
Configuring Expected Call Sequence
- Select EXPECT CALL SEQUENCE from the Action drop-down list
- Specify a sequence of function names (comma separated) in the Function column - be sure stub functions exist
Defining Custom Action on Stub Call
- Select USE CUSTOM ACTION from the Action drop-down list
- Specify function name in the Function column - be sure stub function exists
- Specify custom actions in the Parameters column - the action is defined with the Stubs API -for more details, see Dynamic Stubs Configuration.
(Optional) Specify a condition for custom action execution (Condition column)
Custom action will be represented in C / C++ code using Stubs API as:CPPTEST_ON_CALL("<Function>")->[If()-><Condition>->]<Parameters>
This action can be used to manipulate complex type values - as described in the Basic Approach to Working with Complex Types.
About C Test Cases
When entering values into the Stubs step, C++test will automatically detect the type for constant values, as well as the Parameters API. For other values (variables, expressions), the type of value must be explicitly specified using the Stubs API, e.g., Int(<value>), Float(<value>).
This is not required for C++ test cases.
Syntax for Defining Conditions
Use the following syntax to define conditions (i.e., SET RETURN VALUE, CALL ORIGINAL, USE CUSTOM ACTION).
Simplified Syntax
<name of stub parameter> <operator> <value>
Examples:
paramA == 10 (condition will be met if "paramA" stub parameter equals 10) paramB > 100 (condition will be met if "paramB" stub parameter is greater than 100)
PPTEST_NCALLS <operator> <number of calls>
Examples:
CPPTEST_NCALLS == 10 (condition will be met for 10th call to stub function) CPPTEST_NCALLS < 5 (condition will be met during the first 4 calls to stub function)
Extended Syntax
- Stubs API can be used to build complex conditions; see Dynamic Stubs Configuration.
Example:If().Arg("param1").Greater().Value(10)
Simplified and Extended syntax cannot be mixed in a single condition.
Adding Test Case Parameterization
You can use the Parameters step when the testing scenario requires the execution of the same test with a different set of pre- and post-condition values. You can define an arbitrary set of variables in a parameters table. Each variable has its own column with a unique user-assigned name. Parameterized test cases will be executed independently for each row of values.
Variables defined in Parameters can be used in various steps, for example:
- as initializers of pre-condition variables (Variables)
- as expected post-condition values (Assertions)
- as stub configuration parameters - stub return value, number of calls, etc. (Stubs)
Variables from the Parameters table can be accessed using the following Parameters API. These access functions define the parameter type:
CPPTEST_DS_GET_BOOL("<column name with bool values>")
CPPTEST_DS_GET_C_STR("<column name with string values>")
CPPTEST_DS_GET_FLOAT("<column name with float values>")
CPPTEST_DS_GET_INTEGER("<column name with integer values>")
Press CTRL+SPACE in the target to access the Parameters API step.
Additional Parameter Step Details
- Only simple type values are supported by the Parameters Step.
- There should be only one Parameters step in a given test case. If multiple Parameters Steps are defined, only the first (non-empty) will be used.
The following example shows a parameterized test case forprocessValue(int,int):
input values, expected output, stub return value, number of calls
Reporting Values and Messages
Use the Reports step to report values from a test case. This step provides a set of reporting functions that will print values of a given type (e.g., CPPTEST_REPORT_INTEGER(), CPPTEST_REPORT_FLOAT(),
etc.). The functions are available in the Type drop-down list. After the reporting function is selected, the required parameters appear in the P1-P3 columns.
Alternatively, you can use the Message step to print a simple text message during runtime. This step can be used for outputting traceability identifiers or for debugging purposes.
The output of Reports and Message steps will be printed to the console and can also be included in Unit Testing Reports.
Inserting Custom Code Snippets
You can add complex logic to a test case using the Code step, which implements a custom C or C++ code snippet. The code snippet can be placed anywhere in the test case definition, but the location of the step is important due to top-to-bottom execution order. The code snippet may use variables defined with preceding Variables steps. Variables introduced by the Code may be reused by subsequent steps.
The Test Case Editor will not validate correctness of the custom code entered into Code step. Syntax errors will be reported during test case execution.
Test Case Steps Reference
The Test Case Editor provides the following Steps, which can be used as basic building blocks when defining a test case.
Assertions
Assertions verify the actual values against expected values. They are usually used for checking output values (post-conditions).
Type
Available assertion types can be selected from the drop-down list. For complete list of supported assertion types see Test Case Validation Macros.
P1, P2, P3, P4 (Additional Parameters)
The available parameters depend on the assertion type. Press CTRL+SPACE with a parameter field selected for a list of known variables.
Corresponding C / C++ Code
<Type>([<P1>, <P2>, <P3>, <P4>]);
Call
The Call step allows you to call a tested function. Multiple Call steps can be used in a single test case to define a sequence of calls. The Test Case Editor will not validate the correctness of call parameters entered.
Return
The Return field is a variable for storing the return value. Leave empty if a return value is not needed. Press CTRL+SPACE for a list of known types.
Name
The Name field is the function name. For a member function, the Name field should also contain an object variable (object.mFunction or object->mFunction
). Press CTRL+SPACE for a list of known variables.
Parameters
You can enter a comma-separated list of parameters in this field. Any valid C / C++ parameter is accepted (constant, variable, expression, etc.). Press CTRL+SPACE for a list of known variables.
Corresponding C / C++
<Return> =] <Name>(<Parameters>);
Code
The code field allows you to enter a custom C / C++ code snippet to be executed when running a test case. The code can use symbols already defined in preceding steps. Subsequent steps can use symbols introduced by the Code step. The Test Case Editor will not validate the syntax of entered code.
Corresponding C/C++ Code
<Code>
Globals
Globals are variable definitions, initializations, and assignments specific to the test suite. Global variables can be used in later test cases. Globals are only available in the Test Suite Editor.
Type
Enter the type of global variable in the Type field (required). Press CTRL+SPACE for a list of known types.
Name
Enter the name of the global variable in the Name field (required). A warning will be reported if multiple variables with the same name are defined.
Value
Enter the initialized value you want assigned to the variable in the Value field. Any valid C / C++ initializer is accepted (constant, expression, etc.). Press CTRL+SPACE for a list of known variables.
Corresponding C / C++ Code
<Type> <Name> [= <Value>];
Message
Enter a simple text message into the Message step and it will be printed out during test execution using CPPTEST_REPORT(). The Message step is useful for traceability or debugging purposes. The text will be printed as-is (no variables or expressions allowed) with all quotation marks escaped.
Corresponding C / C++ Code
CPPTEST_REPORT(“<Message>”);
Parameters
Use the Parameters step to set test parameters. Test cases will be executed for each row in the step independently. Only one Parameters step is allowed in a single test case. Values from the Parameters step can be accessed using the Parameters API. The Parameters step has two modes: Built-in (table) mode and Data Source mode.
Built-in (table) Mode
Enable the Built-in (table) option to enter values directly in the Parameters editor:
In this mode, each column (A, B, C, etc.) represents a variable, and each row represents a vector of data that will be used during test case execution.
Data Source Mode
Enable the Data source option and enter the name of an existing data source. Holding down the Control key while pressing the Space key shows the names of available data sources:
After entering the name of data source, the following actions are available:
- Update column names: loads column names of specified data source. Loaded column names will be listed in a Parameters step.
- Create new data source: if the name entered does not match an existing data source, a new data source will be created with the name
- Edit data source: opens the data source editor for the specified data source
- Open data source file: opens data source file for specified CSV or Excel data source
This mode uses existing data sources that have already been defined, including rows and column names. You can click the Update column names button to display the column names of the existing data sources. Only column names can be displayed when clicking the Update column names button; rows from existing data sources are not displayed in this mode.
Corresponding C / C++ Code
N/A
Reports
You can set messages in the Reports step that print with runtime values during test execution. This step may be used for printing input / output values or for debugging purposes.
Type
Choose a type of report from the available types in the Type the drop-down-list. For complete list of supported assertion types, see Test Case Validation Macros.
P1, P2, P3 (Additional Parameters)
The available parameters depend on the report type. Press CTRL+SPACE for a list of known variables.
Corresponding C / C++ Code
<Type>([<P1>, <P2>, <P3>]);
Stubs
The Stubs step sets the configuration for current test case. This step should be placed before the Call step for which the configuration is intended. See also Configuring Stub Behavior.
Action
The Action field specifies the stub behavior or expectations. Available actions appear in the drop-down list. The following Actions are supported:
- SET RETURN VALUE: modifying return value (for simple types only)
- SET PARAMETERS: modifying stub parameters
- CALL ORIGINAL: calling original functions
- USE CUSTOM ACTION: performing custom action on stub call
- EXPECT NUMBER OF CALLS: configuring expected number of calls
- EXPECT NUMBER OF CALLS MORE THAN: configuring expected number of calls
- EXPECT NUMBER OF CALLS LESS THAN: configuring expected number of calls
- EXPECT NUMBER OF CALLS IN RANGE: configuring expected number of calls
- EXPECT CALL SEQUENCE: configuring expected call sequence
Function
Specify the function-identifier for the stub function that the configuration should be applied to in the Function field. Enter a comma-separated sequence of function identifier calls for the EXPECT CALL SEQUENCE action.
Function identifiers are strings used to identify the stub. By default, stubs generated by C++test use identifiers in the following pattern: [parent::]<function_name>
. The parent::
prefix is added only if the function/method is a class or namespace member. Only a direct parent is added. In the case of template class methods, template parameters are omitted in the parent name.
C++test uses the same function-identifier for all overloaded versions of the function. If necessary, you may introduce unique function-identifiers for each overloaded stub function by modifying stub definitions. This will allow you to distinguish stubs for overloaded functions/methods.
Parameters
The available parameters depend on the action type. Press CTRL+SPACE for a list of known variables, Parameters API and Stubs API.
Condition
You can specify optional conditions in the Condition field. The available conditions depend on the type of action. Press CTRL+SPACE for a list of known variables, Parameters API, and Stubs API.
Corresponding C / C++ Code
/* SET RETURN VALUE */ CPPTEST_ON_CALL("<Function>")[-><Condition>]->Arg("__return")->Assign()-><Parameters>; /* SET PARAMETERS */ CPPTEST_ON_CALL("<Function>")[-><Condition>]->Arg("<param1>")->Assign()-><value representation>->Arg("<param2">)->Assign()-><value representation>... /* CALL ORIGINAL */ CPPTEST_ON_CALL("<Function>")[-><Condition>]->Arg("__callOrig")->Assign()->Int(1); /* USE CUSTOM ACTION */ CPPTEST_ON_CALL("<Function>")[-><Condition>]-><Parameters>; /* EXPECT NUMBER OF CALLS */ CPPTEST_EXPECT_NCALLS("<Function>", <Parameters>); /* EXPECT NUMBER OF CALLS MORE THAN */ CPPTEST_EXPECT_NCALLS_MORE_THAN("<Function>", <Parameters>); /* EXPECT NUMBER OF CALLS LESS THAN */ CPPTEST_EXPECT_NCALLS_LESS_THAN("<Function>", <Parameters>); /* EXPECT NUMBER OF CALLS IN RANGE */ CPPTEST_EXPECT_NCALLS_IN_RANGE("<Function>", <Parameters>); /* EXPECT CALL SEQUENCE */ CPPTEST_EXPECT_CALL_SEQUENCE()->Add("<Function>")->Add("<Function>")... ;
Variables
Use the Variables step to specify variable definitions, initializations, and assignments. Both local and global variables can be added to this step. Variables are usually used to set up input values (preconditions).
Type
The Type field specifies the type of a variable. Leave the field empty to set a global variable. Press CTRL+SPACE for a list of known types.
Name
Enter a name for the variable in the Name field. Names are required. For member variables, the name should also contain the object variable (object.mVariable or object->mVariable
). A warning will be reported if multiple variables with the same name are defined. Press CTRL+SPACE for a list of known variables.
Value
Enter a value in the Value field to initialize and assign the value to the variable. Any valid C / C++ initializer is accepted (constant, expression, function call, etc.). Press CTRL+SPACE for a list of known variables.
Corresponding C / C++ Code
[<Type>] <Name> [= <Value>];