How can I unit test Arduino code?

后端 未结 20 732
情深已故
情深已故 2020-12-07 06:53

I\'d like to be able to unit test my Arduino code. Ideally, I would be able to run any tests without having to upload the code to the Arduino. What tools or libraries can he

相关标签:
20条回答
  • 2020-12-07 07:13

    I have considerable success unit testing my PIC code by abstracting out the hardware access and mocking it in my tests.

    For example, I abstract PORTA with

    #define SetPortA(v) {PORTA = v;}
    

    Then SetPortA can easily be mocked, without adding overhead code in the PIC version.

    Once the hardware abstraction has been tested a while I soon find that generally code goes from the test rig to the PIC and works first time.

    Update:

    I use a #include seam for the unit code, #including the unit code in a C++ file for the test rig, and a C file for the target code.

    As an example I want to multiplex four 7 segment displays, one port driving the segments and a second selecting the display. The display code interfaces with the displays via SetSegmentData(char) and SetDisplay(char). I can mock these in my C++ test rig and check that I get the data I expect. For the target I use #define so that I get a direct assignment without the overhead of a function call

    #define SetSegmentData(x) {PORTA = x;}
    
    0 讨论(0)
  • 2020-12-07 07:14

    There is a project called ncore, which provides native core for Arduino. And allows you to write tests for Arduino code.

    From the project description

    The native core allows you to compile and run Arduino sketches on the PC, generally with no modification. It provides native versions of standard Arduino functions, and a command-line interepreter to give inputs to your sketch that would normally come from the hardware itself.

    Also on the "what do I need to use it" section

    If you want to build the tests, you'll need cxxtest from http://cxxtest.tigris.org. NCORE has been tested with cxxtest 3.10.1.

    0 讨论(0)
  • 2020-12-07 07:14

    Use Proteus VSM with an Arduino library to debug your code or to test it.

    It is a best practice before getting your code onboard, but be sure with timings because the simulation does not run realtime as they run on the board.

    0 讨论(0)
  • 2020-12-07 07:15

    Try Autodesk circuit simulator. It allows to test Arduino code and circuits with many other hardware components.

    0 讨论(0)
  • 2020-12-07 07:19

    I built arduino_ci for this purpose. Although it's limited to testing Arduino libraries (and not standalone sketches), it enables unit tests to be run either locally or on a CI system (like Travis CI or Appveyor).

    Consider a very simple library in your Arduino Library directory, called DoSomething, with do-something.cpp:

    #include <Arduino.h>
    #include "do-something.h"
    
    int doSomething(void) {
      return 4;
    };
    

    You'd unit test it as follows (with a test file called test/is_four.cpp or some such):

    #include <ArduinoUnitTests.h>
    #include "../do-something.h"
    
    unittest(library_does_something)
    {
      assertEqual(4, doSomething());
    }
    
    unittest_main()  // this is a macro for main().  just go with it.
    

    That's all. If that assertEqual syntax and test structure looks familiar, it's because I adopted some of Matthew Murdoch's ArduinoUnit library that he referred to in his answer.

    See Reference.md for more information about unit testing I/O pins, the clock, Serial ports, etc.

    These unit tests are compiled and run using a script contained in a ruby gem. For examples of how to set that up, see the README.md or just copy from one of these examples:

    • A practical example, testing a Queue implementation
    • Another set of tests on another Queue project
    • A complex example, simulating a library that controls an interactive device over a SoftwareSerial connection as part of the Adafruit FONA library
    • The DoSomething example library shown above, used to test arduino_ci itself
    0 讨论(0)
  • 2020-12-07 07:20

    In case you are interested in running an INO sketch and checkout the serial output, I have a working implementation of that in my Arduino NMEA checksum project.

    The following script takes the file and uses Arduino CLI to compile it to a HEX file which is then loaded to SimAVR which evaluates it and prints the serial output. Since all Arduino programs run forever without really having an option of killing themselves (exit(0) doesn't work), I let the sketch run for a few seconds and then diff the captured output with expected output.

    Download and extract Arduino CLI (in this case version 0.5.0 - latest at the time of writing):

    curl -L https://github.com/arduino/arduino-cli/releases/download/0.5.0/arduino-cli_0.5.0_Linux_64bit.tar.gz -o arduino-cli.tar.gz
    tar -xvzf arduino-cli.tar.gz
    

    Now you can update the index and install the appropriate core:

    ./arduino-cli core update-index
    ./arduino-cli core install arduino:avr
    

    Assuming your sketch is named nmea-checksum.ino, to get ELF and HEX, run:

    ./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino
    

    Next up, SimAVR to run the HEX (or ELF) - I build from source because the latest release didn't work for me:

    sudo apt-get update
    sudo apt-get install -y build-essential libelf-dev avr-libc gcc-avr freeglut3-dev libncurses5-dev pkg-config
    git clone https://github.com/buserror/simavr.git
    cd simavr
    make
    

    Successful compilation will give you simavr/run_avr which you can use to run the sketch. Like I said, timeout it otherwise it will never terminate:

    cd simavr
    timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true
    

    The generated file will have ANSI color code control characters wrapping the serial output, to get rid of those:

    cat nmea-checksum.ino.clog | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > nmea-checksum.ino.log
    cat nmea-checksum.ino.log
    

    Now all you need to do is compared this file to a known good file:

    diff nmea-checksum.ino.log ../../nmea-checksum.ino.test
    

    If there are no differences, diff will exit with code 0, otherwise the script will fail.

    0 讨论(0)
提交回复
热议问题