Automated Verification, Assertions & Write Window Diagnostics
Automated regression testing requires verifying that an ECU meets response time contracts (e.g. responding within 50ms) and that signal ranges remain within tolerance. Assertions flag violations immediately, and structured logging in the CANoe Write Window provides color-coded diagnostics for test engineers.
Overview & Key Concepts
CAPL (CAN Application Programming Language) is used to script and automate tasks for testing and simulation in automotive systems, especially for CAN (Controller Area Network) communication. Two key concepts in CAPL are Assertions and Logging, which are crucial for debugging, verification, and ensuring that your code behaves as expected.
Assertions in CAPL
An Assertion is used to verify that a certain condition holds true during the execution of the script. If the condition is not true, the assertion fails and an error message is logged. Assertions help catch bugs or misbehavior early, ensuring that certain assumptions or invariants are true while the system is running.
Why Use Assertions?
Verification: You can verify that input values, system states, or conditions are as expected.
Error detection: Assertions detect unexpected behavior, such as incorrect data, invalid ranges, or miscommunication.
Debugging: They simplify debugging by isolating where the code is deviating from expected behavior.
Syntax and Usage
In CAPL, assertions are typically done using the assert keyword.
assert(expression);
Where:
expression is a condition (usually a boolean expression) that is expected to be true.
If the condition evaluates to false, the script will stop, and an error message will be displayed indicating where the assertion failed.
Example of Assertions
variables
{
int speed;
int temperature;
}
on start
{
speed = 50;
temperature = 80;
// Assert that speed is within the expected range
assert(speed >= 0 && speed <= 120); // Passes
// Assert that temperature is within the expected range
assert(temperature >= 0 && temperature <= 100); // Fails and stops script execution
}
In the example:
The first assertion checks that the speed is between 0 and 120. Since speed = 50, it passes.
The second assertion checks that the temperature is between 0 and 100. Since temperature = 80, it passes. If the temperature were set to 120, the assertion would fail, and an error message would appear.
Handling Assertion Failures
If an assertion fails, the script halts. However, you can add custom failure handling or recovery code if necessary.
on start
{
int value = 150;
// Assert that value is within the acceptable range
if (value < 0 || value > 100)
{
output("Assertion failed: value out of range.");
return; // Handle failure gracefully
}
assert(value >= 0 && value <= 100);
}
In this case, the assertion will be bypassed by manually checking the condition before using assert.
Logging in CAPL
Logging is the process of writing output to the console or a log file to track the execution flow, record variable values, and understand the system’s behavior during runtime. It is important for tracking the internal state, debugging issues, and providing information about script behavior.
Why Use Logging?
Debugging: Logs help in identifying where things go wrong by providing a trace of script execution.
Monitoring: It helps monitor the behavior of the system, especially in long-running tests or simulations.
Audit Trail: Keeps track of events that occur, which can be helpful for review or debugging after a test completes.
CAPL Logging Functions
The primary function used for logging is output(). It prints messages to the output console.
output("Your message here.");
Example of Logging
variables
{
int speed;
int temperature;
}
on start
{
speed = 50;
temperature = 85;
// Log information
output("Starting test...");
output("Initial speed: %d km/h", speed); // Logs the value of speed
output("Initial temperature: %d°C", temperature); // Logs the value of temperature
// Conditional logging
if (speed > 100)
{
output("Speed is greater than 100 km/h");
}
else
{
output("Speed is within safe range.");
}
}
In this example:
The script outputs information about the initial values of speed and temperature to the console.
Conditional logging checks whether the speed exceeds 100 and logs the appropriate message.
Formatted Output
CAPL allows formatted output similar to printf in C. You can use format specifiers like %d, %s, %f, etc., to print variables.
%d for integers
%f for floating-point numbers
%s for strings
int temperature = 75;
output("Current temperature: %d°C", temperature); // Output: Current temperature: 75°C
Advanced Logging Techniques
In CAPL, you can log more complex data structures or control the verbosity level of logging using additional techniques. For instance, using trace and log can provide more detailed logs in some CAPL environments.
trace("This is a detailed trace message with variable value: %d", temperature);
The trace level is usually more detailed than the standard output.
Logging with File Output
While output() sends information to the console, in some cases, you may need to log data to a file. You would typically do this in combination with file I/O functions (not directly in CAPL but through the environment or external scripts).
Combining Assertions and Logging
You can use both assertions and logging together to enhance the reliability and traceability of your code. For example, logging can be used to record the values of variables before an assertion to understand why it failed.
Example Combining Assertions and Logging
variables
{
int speed;
int temperature;
}
on start
{
speed = 130; // Intentional error (out of range)
temperature = 90;
// Log current values before assertion
output("Checking values before assertion:");
output("Speed: %d km/h, Temperature: %d°C", speed, temperature);
// Assert that speed is within the valid range
assert(speed >= 0 && speed <= 120); // This will fail, but we log the values first
}
In this example:
The script logs the values of speed and temperature before performing the assertion.
When the assertion fails (because speed = 130), the logs provide context to help understand why the failure occurred.
Conclusion
Assertions in CAPL ensure that conditions expected during script execution hold true. They are helpful for verifying assumptions, catching bugs early, and ensuring that the system behaves as expected.
Logging provides insights into the internal state of the system, assisting in debugging and monitoring system behavior. You can use formatted output for variable values and add custom messages based on conditions.
By using assertions and logging together, you create robust, traceable, and maintainable CAPL scripts that are easier to debug and verify during simulation and testing.
- Excessive `write()` calls inside high-frequency event handlers (like every 1ms) can degrade CANoe execution performance. Use severity filters or condition checks.
- Remember that `write()` outputs to the CANoe application window; to write permanent disk logs, use CAPL file I/O functions or CANoe test reports.
Select your answer for each question below to receive immediate correctness evaluation and in-depth technical rationale.
Write an `on signal EngineSpeed` handler that asserts `$EngineSpeed <= 6500.0`. If the assertion fails, log an error message to the Write Window using severity 3 with the exact timestamp and RPM, and increment a global `gAssertionFailures` counter.
Verified CAPL implementation:
variables {
long gAssertionFailures = 0;
}
on signal EngineSpeed {
if ($EngineSpeed > 6500.0)
{
gAssertionFailures++;
writeLineEx(0, 3, "[ASSERTION FAILED @ %d ms] EngineSpeed exceeded redline! Value: %.1f RPM",
timeNow() / 100, $EngineSpeed);
}
}