software unit testing with vectorcast/c++ · software unit testing vectorcast/c++ provides a...
TRANSCRIPT
V0 | 2019-11-19
Software Testing TechDay – November 19, 2019
Software Unit Testing with VectorCAST/C++
2
White-Box Testing on host / on target VectorCAST/C++
Software Unit Testing
VectorCAST/C++ provides a natural way to define low-level software unit test cases, eliminates the need to write and maintain test driver code, and makes those tests
available to all the developers on the team as a reusable asset to validate their work for each code check-in.
3
What is a Unit Test?
Call the function
Check the return value
4
Prove correctness of low-level building blocks before integration
Test error cases that are impossible to test during functional testing (memory fail)
Formalize decisions made by the coder: value ranges, error handling etc. There are always gaps between the functional requirements and the implementation
Requirement: Transmission variant will be a letter between ‘a’ and ‘z’ Code: Implemented with the pre-defined “char” type -128..+127
> Question: What happens if the variant has one of the 230 other values?> Developer-1-> This can’t happen> Developer-2 -> check against range, report error, set value to default
Why Unit Testing?
5
Unit Testing Benefits
Small and Quick to Run•Should be easy to re-run for each code change
Positive Side Effects•Code is more modular•Easier to reuse
Reduces Global Data•You will tend to use global data less•You are more likely to create access methods rather than
directly access global data
Reduces overall effort•Defects diagnosed at a fine grain level•Debugging is limited to scope of the code changes
6
for(int i = 0; i < len; i++){sum += my_filter[(i+readIdx)%BUFFER_SIZE];}return sum/len;}
int myapp_task(){// get value from registerint nextval = myapp_do_dangerous_io();
// add to filter linefilter_add(nextval);
// return the average value as the next delayreturn myapp_get_average();}
int myapp_mainloop(){for(;;){int nextloopdelay = myapp_task();sleep(nextloopdelay);}}
#ifndef TESTINGint main() {printf("!!!Hello World!!!\n");return myapp_mainloop();}#endif
#include <stdio.h>#include <unistd.h>
#define IOMEM_BASE 0x2FF#define VALUE_REG (IOMEM_BASE + 3)
// This must be a power of 2!#define BUFFER_SIZE 8#define MAX_ITEMS (BUFFER_SIZE-1)static int my_filter[BUFFER_SIZE];static int readIdx = 0;static int writeIdx = 0;
int filter_len(){ return (BUFFER_SIZE + writeIdx - readIdx) % BUFFER_SIZE; }
void filter_add(int val) {my_filter[writeIdx] = val;writeIdx = (writeIdx+1) & BUFFER_SIZE-1;if(writeIdx == readIdx) readIdx = (readIdx+1) & BUFFER_SIZE-1;}
#ifndef TESTINGint myapp_do_dangerous_io(){// lets dereference an io mapped register// - on the target it is at address IOMEM_BASE + 3return *((int *)VALUE_REG);}#endif
int myapp_get_average(){int len = filter_len();if(0 == len) return 0;int sum = 0;
Unit Test Driver Code – example code under test
Source: https://meekrosoft.wordpress.com/2009/11/09/unit-testing-c-code-with-the-googletest-framework/
7
TEST_F(MyAppTestSuite, get_average_should_return_zero_on_empty_filter) {ASSERT_EQ(0, myapp_get_average());}
TEST_F(MyAppTestSuite, addFirstFilterValAddsVal) {filter_add(42);ASSERT_EQ(42, my_filter[readIdx]);}
TEST_F(MyAppTestSuite, addFirstReturnsCorrectAverage) {filter_add(42);ASSERT_EQ(42, myapp_get_average());}
TEST_F(MyAppTestSuite, addTwoValuesReturnsCorrectAverage) {filter_add(42);filter_add(40);ASSERT_EQ(41, myapp_get_average());}
TEST_F(MyAppTestSuite, get_average_should_return_average_of_full_filter) {for(int i = 0; i < MAX_ITEMS; i++){filter_add(i);}ASSERT_EQ((0+1+2+3+4+5+6)/MAX_ITEMS, myapp_get_average());}
TEST_F(MyAppTestSuite, get_average_should_return_average_of_wrapped_filter) {for(int i = 0; i < BUFFER_SIZE; i++){filter_add(i);}ASSERT_EQ((1+2+3+4+5+6+7)/MAX_ITEMS, myapp_get_average());}
/// ....test buffer operations......
#include <gtest/gtest.h>
// Hide main#define TESTING// Hide the io function since this will segfault in testingint fake_register;int myapp_do_dangerous_io(){return fake_register;}#include "myapp.c"
class MyAppTestSuite : public testing::Test{void SetUp(){memset(&my_filter, 0, sizeof(my_filter));readIdx = 0;writeIdx = 0;}
void TearDown(){}};
TEST_F(MyAppTestSuite, myapp_task_should_return_correct_delay_for_one_element) {fake_register = 10;EXPECT_EQ(10, myapp_task());}
TEST_F(MyAppTestSuite, myapp_task_should_return_correct_delay_for_two_elements) {fake_register = 10;myapp_task();fake_register = 20;EXPECT_EQ(15, myapp_task());}
Unit Test Driver Code – example driver
Source: https://meekrosoft.wordpress.com/2009/11/09/unit-testing-c-code-with-the-googletest-framework/
8
VecorCAST Unit Test Case
9
C, C++, Ada Embedded Unit Testing
Source Code
Unit(s)
Under Test Real
Dependents
(.obj files)
Stubbed
Dependents
Unit(s)
Under Test
Test Harness
Test
Driver
10
On-Target Embedded Unit Testing
Host Environment Target/Simulator
VectorCAST RSP
Test Harness
Tests
parse raw
source code
auto generate
all drivers
and stubs
PASS
FAIL
PASS
PASS
100% Coverage
Test Reports
Execute
Tests
Pass/Fail Results
and
Code CoverageEthernet, Serial Link, JTAG
Source Code
11 © 2018. Vector North America Inc. All rights reserved. Any distribution or copying is subject to prior written approval by Vector. V0 | 2019-11-19
Authors:Harry Campbell
For more information about Vectorand our products please visit
www.vector.com