add a code independent unit test writing example

pull/10391/head
Lari-Matias Orjala 2019-04-12 15:13:08 +03:00
parent 2641fb38ce
commit a4308426da
1 changed files with 134 additions and 60 deletions

View File

@ -104,76 +104,149 @@ You can also set custom compiler flags and other configurations supported by CMa
#### Example #### Example
With the following steps, you can write a simple unit test. In this example, `rtos/Semaphore.cpp` is a class under test. With the following steps, you can write a simple unit test. In this example we will create dummy classes to be tested. Then we will create and configure unit tests for a class. Finally we will stub all external dependencies.
1. Create a directory for unit test files in `UNITTESTS/rtos/Semaphore`. 1. Create the following dummy classes in `mbed-os/example`:
1. Create a test configuration file `UNITTESTS/rtos/Semaphore/unittest.cmake` with the following content:
**MyClass.h**
``` ```
#ifndef MYCLASS_H_
#define MYCLASS_H_
namespace example {
class MyClass {
public:
int myFunction();
};
}
#endif
```
**MyClass.cpp**
```
#include "MyClass.h"
#include "OtherClass.h"
namespace example {
int MyClass::myFunction() {
OtherClass o = OtherClass();
return o.otherFunction();
}
}
```
**OtherClass.h**
```
#ifndef OTHERCLASS_H_
#define OTHERCLASS_H_
namespace example {
class OtherClass {
public:
int otherFunction();
};
}
#endif
```
**OtherClass.cpp**
```
#include "OtherClass.h"
namespace example {
int OtherClass::otherFunction() {
return 1;
}
}
```
1. Create a directory for MyClass unit tests in `UNITTESTS/example/MyClass`.
1. Create a configuration file and a source file for MyClass unit tests in `UNITTESTS/example/MyClass`:
**unittest.cmake**
```
# Add here additional test specific include paths
set(unittest-includes ${unittest-includes}
../example
)
# Add here classes under test
set(unittest-sources set(unittest-sources
../rtos/Semaphore.cpp ../example/MyClass.cpp
) )
# Add here test classes and stubs
set(unittest-test-sources set(unittest-test-sources
stubs/mbed_assert_stub.c example/MyClass/test_MyClass.cpp
stubs/Kernel_stub.cpp stubs/OtherClass_stub.cpp
rtos/Semaphore/test_Semaphore.cpp
) )
``` ```
1. Stub all external dependencies. Create stubs `UNITTESTS/stubs/mbed_assert_stub.c` and `UNITTESTS/stubs/Kernel_stub.cpp` if they don't already exist.
1. Update header stubs with any missing type or function declarations. **test_MyClass.cpp**
1. Create a test source file `UNITTESTS/rtos/Semaphore/test_Semaphore.cpp` with the following content:
``` ```
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "rtos/Semaphore.h" #include "example/MyClass.h"
static osStatus_t retval = osOK; class TestMyClass : public testing::Test {
static uint32_t count = 0;
// Test stubs
osStatus_t osSemaphoreAcquire(osSemaphoreId_t semaphore_id, uint32_t timeout)
{
return retval;
}
osStatus_t osSemaphoreDelete(osSemaphoreId_t semaphore_id)
{
return retval;
}
osStatus_t osSemaphoreRelease(osSemaphoreId_t semaphore_id)
{
return retval;
}
uint32_t osSemaphoreGetCount(osSemaphoreId_t semaphore_id)
{
return count;
}
osSemaphoreId_t osSemaphoreNew(uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr)
{
return (void *)&count; // Just a dymmy reference
}
class TestSemaphore : public testing::Test {
protected: protected:
rtos::Semaphore *sem; example::MyClass *obj;
virtual void SetUp() virtual void SetUp()
{ {
sem = new rtos::Semaphore(); obj = new example::MyClass();
} }
virtual void TearDown() virtual void TearDown()
{ {
delete sem; delete obj;
} }
}; };
TEST_F(TestSemaphore, constructor) TEST_F(TestMyClass, constructor)
{ {
EXPECT_TRUE(sem); EXPECT_TRUE(obj);
}
TEST_F(TestMyClass, myfunction)
{
EXPECT_EQ(obj->myFunction(), 0);
} }
``` ```
1. Stub all external dependencies. Create the following stub in `UNITTESTS/stubs`:
**OtherClass_stub.cpp**
```
#include "example/OtherClass.h"
namespace example {
int OtherClass::otherFunction() {
return 0;
}
}
```
This example does not use any Mbed OS code, but if your unit tests do then remember to update header stubs in `UNITTESTS/target_h` and source stubs in `UNITTESTS/stubs` with any missing type or function declarations.
### Building and running unit tests ### Building and running unit tests
Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake and a Make program directly. Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake and a Make program directly.
@ -187,6 +260,7 @@ Use Mbed CLI to build and run unit tests. For advanced use, you can run CMake an
* Add `-DCMAKE_MAKE_PROGRAM=<value>`, `-DCMAKE_CXX_COMPILER=<value>` and `-DCMAKE_C_COMPILER=<value>` to use a specific Make program and compilers. * Add `-DCMAKE_MAKE_PROGRAM=<value>`, `-DCMAKE_CXX_COMPILER=<value>` and `-DCMAKE_C_COMPILER=<value>` to use a specific Make program and compilers.
* Add `-DCMAKE_BUILD_TYPE=Debug` for a debug build. * Add `-DCMAKE_BUILD_TYPE=Debug` for a debug build.
* Add `-DCOVERAGE=True` to add coverage compiler flags. * Add `-DCOVERAGE=True` to add coverage compiler flags.
* Add `-Dgtest_disable_pthreads=ON` to run in a single thread.
* See the [CMake manual](https://cmake.org/cmake/help/v3.0/manual/cmake.1.html) for more information. * See the [CMake manual](https://cmake.org/cmake/help/v3.0/manual/cmake.1.html) for more information.
1. Run a Make program to build tests. 1. Run a Make program to build tests.