TDD with PlatformIO #1
Tags: tdd, cpp, vscode, platformio
Published: 2021-05-23 21:03:31

hi all, this is my first post on this amazing platform. 

I'd like and I'll try to use this tool to talk about my hobbies, or at least, what was my job when I was I developer... but you know, who is born developer will be always a developer, it's a matter of finding the right place to spread the passion :)

another thing before starting: sorry for my english, this is not my natural language and I'll write smoothly so I'm sure you'll find some errors. 

Let's start now

## TDD development
first of all, a brief introduction to TDD and why everyone should use it. 
One of the agile principles state: 
> principle 3) Deliver working software frequently, from a couple of weeks to a couple of months, with a preference to the shorter timescale.

> principle 9) Continuous attention to technical excellence and good design enhances agility.

this two princicples could be in contrast as if I have to deliver frequently, it means about 2 or 3 weeks, how can pay attention on techincal excellence and good design, by experimenting new technologies and making refactoring to my code?
This is a nice questions and of course when the agile manifesto was written the solution was ready and belong to the XP programming formalized by ser Kent Beck. 

_Test Driven Development_ is a rivolutionary approach to coding, more then _Test_ I'd like to use _Experiments_ as it's an empirical approach very similar to the Galileo's scientific  method: you have to prove your thesis by short experiments that step by step prove your hypothesis. 
THe flow has three steps: red, green, refactoring. Red means that your very first experiment will fail, second means that you make the smaller possible modification to let you test run, third means that between each step, after learning something new with your experiments, you can improve your code by refactoring it! Simple! This is what I've learn, for academical concepts please google tdd and you'll find all you need, I close this chapter by suggesting you this book: 
- Test-Driven Development: By Example. Addison-Wesley. (ISBN 978-0321146533)

##Preparing the Environment (on Windows)
1. install [vscode](https://code.visualstudio.com/download)
2. install [platformio extension](https://platformio.org/install/ide?install=vscode). This is a very nice framework built in python (fashion && trendy). It helps in developing on different microcontrollers managing all the tool chain needed to compile and upload the firmware. In my opionion it's great for **multi file management** and **unit testing**, these are the reasons why I've chosen to leave the very straightforward arduino IDE in favour of it.  
3. platformIO load the tool chain for the microcontroller you choose and let you run unit tests as firmware getting the test results from Serial. Ok, that's great but I've to test also some logic that don't need Arduino features like I/O, sleeps, interrupts... and I don't want to wait: I'm trying to use TDD, I'll run a lot of tests. [platformIO native](https://platformio.org/platforms/native/) can help us.
    Install it from console
    ```
    > pio platform install native
    ```
    and configure it on platformio.ini on your platformIO new project adding these lines
    ```
    [env:desktop]
    platform = native
    ```
4. Before using it, as noted [here](https://docs.platformio.org/en/latest/plus/unit-testing.html#test-types) we need to install _GCC_ as host compiler. On Windows  the simpler way is by installing [msys2](https://www.msys2.org/#installation), a collection of unix clone tools. Following the intructions you can find all the steps needed to install GCC, it's very simple. Important: at the end add the bin folder to the PATH variable
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i0y4tb94euo90splw779.png)
5. Let's try the unit testing. Add a dummy test like this on _test_ folder
    ```cpp
    #include<unity.h>

    void test_assert_running_desktop(){
        TEST_ASSERT_TRUE(true);
    }

    int main(int argc, char const *argv[])
    {
        UNITY_BEGIN();
        RUN_TEST(test_assert_running_desktop);
        UNITY_END();
        return 0;
    }
    ```
    from console call the pio command to run the test
    ```
    pio test -v -e desktop 
    ```
    test should pass
    ![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jpu360wadjjp6fjpvgx3.png)

That's all for today, ah... right, last thing: I configured the platformio unit testing to run native if is set up the _desktop_ environment when calling _pio test_. What happen if I'll have to make also arduino unit tests? How can I select tests to be run in a desktop environment and tests to be run on board? There's a solution that I've seen on an example on [github](https://github.com/platformio/platformio-examples/tree/develop/unit-testing/calculator). First, move unit tests to two different subfolders like _test/desktop_ and _test/arduino_ and then add a _test__ignore_ filter on platformio.ini in this way 
```
[env:uno]
platform = atmelavr
board = uno
framework = arduino
test_ignore = desktop

[env:desktop]
platform = native
test_ignore = arduino
```
based on the -e parameter pio will launch only desktop or arduino unit test. 

Hope it can help, see you next week with the first tdd development cycle.