Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
# Test-Driven Development with Arduino
In this lab you will learn how to carry out the process of Test-Driven development (TDD) using the Arduino framework. We will be using the PlatformIO command-line tools. There is [detailed documentation](https://docs.platformio.org/en/latest/plus/unit-testing.html#remote) covering the implementation of the [Unity](http://www.throwtheswitch.org/unity/) tools.
## 1 Understanding the Code
You should now use the IDE to open the `exercises/02_tdd/temp/` directory which contains a simple Arduino sketch with a library. Lets look at the files. As you can see there are some additional ones:
```
├── lib
│   ├── avg
│   │   ├── avg.cpp
│   │   └── avg.h
│   └── readme.txt
├── platformio.ini
├── readme.md
├── src
│   └── main.cpp
└── test
└── test_desktop
└── test_avg.cpp
```
1. The `lib/` directory contains our custom library. This is where we will build the business logic for our software. It will be thoroughly unit tested.
2. The `test/` directory contains the unit testing files that will be used to test the library code.
## 2 Running the Unit Tests
We will be executing our test suite from the terminal by invoking the `pio` command together with the `test` subcommand. Make sure you [create an account](https://docs.platformio.org/en/latest/userguide/account/cmd_register.html) and [log in](https://docs.platformio.org/en/latest/userguide/account/cmd_login.html).
You should also ensure the `gcc` toolchain is installed on your computer. Run the command `gcc`. If this is not found you will need to install, the instructions differ depending on your operating system:
1. MacOS: `brew install gcc`
2. Ubuntu: `apt install gcc`
3. Windows 10: install [Cygwin](https://sourceware.org/cygwin/) and make sure you pick the gcc tools from the selection of software it can install.
```shell
$ pio test -v -e native
================================== [SUMMARY] ==================================
Environment nodemcuv2 [SKIP]
Environment native [SUCCESS]
========================= [SUCCESS] Took 0.32 seconds =========================
===================== [test/test_desktop] Testing... (2/2) =====================
/test_avg.cpp:11:test_add_single_val:FAIL: Expected 0 Was 42 [FAILED]
-----------------------
1 Tests 1 Failures 0 Ignored
FAIL
=============================== [TEST SUMMARY] ================================
test/test_desktop/env:nodemcuv2 [IGNORED]
test/test_desktop/env:native [FAILED]
========================== [FAILED] Took 0.33 seconds ==========================
```
Notice that the test suite fails!
## 3 Test-Driven Development
You are now going to modify the code to ensure that the test passes. The test adds a single value to the library. It then reads the average value which should match the value we passed (but it doesn't). We are going to apply TDD principles.
### 3.1 Define Requirements as a Test
For this first iteration, this has already been done, look in the `test_avg.cpp` file.
### 3.2 Write Code to pass the Test
We now need to write just enough code to pass the test. Edit the `lib/avg/avg.cpp` file. Test your code by running the test suite. Stop as soon as the test passes.
### 3.3 Refactor the Code
The third and final step is to tidy up the code, making sure the tests still pass.
### 3.4 Test Your Understanding
Now apply the TDD principles to fix the following issues, this will take 6 TDD iterations:
1. If I send 2 values to the library, the average should be calculated based on the 2 values. Try adding 42 and 24, it should return 33.
1. If the result is wrong perhaps you needed to call the `avg_clear()` function at the start of each test.
2. If the average is a floating point number it should round up if the average is 0.5 or above:
1. If I pass values of 42 and 23 the average should be 33.
2. If I pass values of 42, 11, 17, the average should be 23.
3. The library should return the average of the last 5 values passed so if I add 6 values it should ignore the first one we added.
1. If I pass the values 1, 2, 3, 4, 5 the average should be 3.
2. If I pass the values 1, 2, 3, 4, 5, 6 the average should be 4.
3. If I pass the values 1, 2, 3, 4, 5, 6, 7 the average should be 5.
For an extension task, use TDD to implement an average function that returns the mean reading since the device was powered up.
## 4 Integrate into an Arduino Project
The final step is to use your custom library to create a complete temperature and humidity sensor.
1. Connect a DHT11 sensor and capture the temperature and display in the serial monitor.
2. If you are using the Lolin32 board you should also display the temperature on the screen.
2. Use your custom library to smooth the reading using a rolling average, display this next to each raw reading (including the screen if available).
3. Capture the humidity as well as temperature and display this next to the temp values.
4. How could you modify your library to smooth both the temperature and humidity?
1. You may need to make changes to your library.
2. Don't forget to apply the TDD methdology!