bxparks / AUnit

Unit testing framework for Arduino platforms inspired by ArduinoUnit and Google Test. Used with EpoxyDuino for continuous builds.
MIT License
179 stars 16 forks source link

Better documentation using a simple use case #65

Closed joesan closed 3 years ago

joesan commented 3 years ago

Could the documentation be made a little bit better by doing a step-by-step instruction using a simple use case (could be as simple as the Arduino blink example), run the unit tests in a GitHub action?

bxparks commented 3 years ago

Documentation can always be better from someone's perspective probably, but I'm pretty much at the limit of how much time and effort I'm willing spend on it for this project. I have a whole bunch of examples in https://github.com/bxparks/AUnit/tree/develop/examples and https://github.com/bxparks/AUnit/tree/develop/tests. I recently added a new documentation for Continuous Integration (https://github.com/bxparks/AUnit#ContinuousIntegration). I consider using GitHub Actions to be an advanced usage. It became available only recently, so I expect people using it to be advanced users. Most Arduino libraries have only a fraction of the documentation that I provide here, and most people don't read the README.md anyway.

joesan commented 3 years ago

I tired to look into this example here https://github.com/bxparks/AUnit/blob/develop/examples/basic/basic.ino but I fail to understand what the need for the loop method and the setup method is for?

joesan commented 3 years ago

Here is a simple Blink unit test that I tired, but I have a few questions that I need some help / clarifications:

#line 2 "Blink.ino"

// Adapted from:
// https://github.com/mmurdoch/arduinounit/blob/master/examples/basic/basic.ino

#include <AUnit.h>

test_led_builtin_pin_number(void) {
  assertEqual(13, LED_BUILTIN);
}

test_led_state_high(void) {
  digitalWrite(LED_BUILTIN, HIGH);
  assertEqual(HIGH, digitalRead(LED_BUILTIN));
}

test_led_state_low(void) {
  digitalWrite(LED_BUILTIN, LOW);
  assertEqual(LOW, digitalRead(LED_BUILTIN));
}

//----------------------------------------------------------------------------
// setup() and loop()
//----------------------------------------------------------------------------

void setup() {
  delay(2000); // wait for stability on some boards to prevent garbage Serial
  Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux

  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
   TestRunner::run();
}

First of all I'm not sure if what I did is correct and secondly, I do not understand what is the need for the loop and setup functions here. Ideally, I would want to test my code in the src folder, but I'm not doing that in this simple example. So assuming that this is what I have in my src folder for the Blink sketch:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

Where in my AUnit test I'm calling this setup and loop function? This is what I doi not understand!

bxparks commented 3 years ago

I'm afraid that I don't understand what you don't understand. The setup() and loop() functions are the same 2 functions that must appear in every Arduino program. An AUnit test is just another Arduino program.

Also, it does not make any sense to unit test an LED blink program. There is nothing to test. You also seem to think you can read the value of the LED_BUILTIN after writing to it. You cannot, which means you don't understand the difference between an OUTPUT mode and an INPUT mode of a pin. Therefore, I get the impression that you are new to Arduino programming. I suggest forgetting about unit testing for a while, and just play with Arduino programs so that you understand how it works. Then think about how to use unit testing for some of your more complicated stuff.

joesan commented 3 years ago

The blink is a simple example. My question was I have the Blink sketch in my src folder and this blink sketch contains the necessary functions for Arduino which is the setup and loop (other complex codebase might contain other methods), but here just for simplicity, assume that these two methods exists. Now I need to write unit tests that tests these two methods. So I go into the test folder, create the test file. Shouldn't this test file call the setup and loop methods of the Blink sketch in the src folder and assert the resutls?

bxparks commented 3 years ago

It sounds like you have a confused understanding of how Arduino programs work, maybe due to your experiences with other unit testing frameworks in other languages and environments. I have 2 questions for you that may help you (or not):

1) The entry point of every C/C++ program is a function called main(). This is true even for Arduino programs. But Arduino programs don't have a main(). How is that possible? Hint: https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/main.cpp

2) Every AUnit test is just a normal Arduino program, because it was originally intended to run on the actual microcontroller. Think about how a normal Arduino program can become a unit test program, given the constraint (1) above.

If those 2 questions are still confusing, then I recommend not worrying about unit testing, until AUnit starts to make sense to you. The entire source code of AUnit is available for you to read and study, and the README.md file is extensive. You need to work with what you got.

bxparks commented 3 years ago

I'm going to close this because there is no work to be done by me.