Comments (5)
If anyone wants to take this on, please start a discussion here before beginning work.
from arduino.
Firmata can largely be unit tested using the following mechanisms:
- Use
Firmata.begin(Stream&)
with an in-memory stream to test serial reads and writes - Attach callback functions for capturing and checking processed input data
The only functions which cannot be tested this way are blinkVersion()
and pin13strobe()
which directly use Arduino functions (pinMode()
and digitalWrite()
). Some small refactoring would likely be needed to test them.
Also this method won't test any functionality in StandardFirmata.ino
. I'd suggest the best way to get this under test would be to move as much of it into a separate library which can be tested as above. Doing this will likely require wrapping the Arduino functions so that they can be stubbed out for testing. This would make StandardFirmata.ino
into a very thin wrapper around this library. There could be overlap with this and the implementation for issue #25 (configurable firmata).
Here's a potential starting unit test sketch using ArduinoUnit (https://github.com/mmurdoch/arduinounit - a library I maintain). I'd be happy to add to these tests if we think this is a sensible approach . All the unit tests are of the form test(<test_name>)
:
#include <Firmata.h>
#include <ArduinoUnit.h>
// Allows full control of a stream for testing purposes
class InMemoryStream : public Stream
{
public:
virtual ~InMemoryStream()
{
}
size_t write(uint8_t val)
{
_bytesWritten += (char) val;
return size_t(1);
}
void flush()
{
}
const String& bytesWritten()
{
return _bytesWritten;
}
void nextByte(byte b)
{
_nextByte = b;
}
int available()
{
return 1;
}
int read()
{
return _nextByte;
}
int peek()
{
return _nextByte;
}
private:
String _bytesWritten;
byte _nextByte;
};
TestSuite suite;
void setup()
{
Serial.begin(9600);
}
void loop()
{
suite.run();
}
// Helper function for checking strings
void assertStringsEqual(Test& __test__, const char* expected, const String& actual)
{
size_t expectedLength = strlen(expected);
assertEquals(expectedLength, actual.length());
for (size_t i = 0; i < strlen(expected); i++)
{
assertEquals(expected[i], actual[i]);
}
}
test(beginPrintsVersion)
{
InMemoryStream stream;
Firmata.begin(stream);
char expected[] =
{
0xF9, // Version reporting identifier
2, // Major version number
3, // Minor version number
0
};
assertStringsEqual(__test__, expected, stream.bytesWritten());
}
// Helper function to simplify tests
void processMessage(const byte* message, size_t length)
{
InMemoryStream stream;
Firmata.begin(stream);
for (size_t i = 0; i < length; i++)
{
stream.nextByte(message[i]);
Firmata.processInput();
}
}
// Record digital port and value for checking in a test
byte _digitalPort;
int _digitalPortValue;
void writeToDigitalPort(byte port, int value)
{
_digitalPort = port;
_digitalPortValue = value;
}
test(processWriteDigital_0)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, 0, 0 };
processMessage(message, 3);
assertEquals(0, _digitalPortValue);
}
test(processWriteDigital_127)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, 127, 0 };
processMessage(message, 3);
assertEquals(127, _digitalPortValue);
}
test(processWriteDigitalStripsTopBit)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, B11111111, 0 };
processMessage(message, 3);
assertEquals(B01111111, _digitalPortValue);
}
test(processWriteDigital_128)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, 0, 1 };
processMessage(message, 3);
assertEquals(128, _digitalPortValue);
}
test(processWriteLargestDigitalValue)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, 0x7F, 0x7F };
processMessage(message, 3);
// Maximum of 14 bits can be set (B0011111111111111)
assertEquals(0x3FFF, _digitalPortValue);
}
test(defaultDigitalWritePortIsZero)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE, 0, 0 };
processMessage(message, 3);
assertEquals(0, _digitalPort);
}
test(specifiedDigitalWritePort)
{
Firmata.attach(DIGITAL_MESSAGE, writeToDigitalPort);
byte message[] = { DIGITAL_MESSAGE + 1, 0, 0 };
processMessage(message, 3);
assertEquals(1, _digitalPort);
}
from arduino.
I think this is a good start. I've created a new branch called unit-tests and created a test directory and unit sub directory. Please open a pull request against unit-tests. Thanks!
from arduino.
I guess we also need test-stubs of Servo, I2C and OneWire etc... to unit-test the more advanced features?
from arduino.
Yeah we need to merge dev into configurable or at least copy the test code to the configurable branch. Then we can add a unit test for each feature class (at least in theory... some features may be more difficult to test than others if not impossible without writing extra methods just to test, but I don't want to go down that route with a microcontroller).
from arduino.
Related Issues (20)
- Analog pin as digital. HOT 3
- Analog Pins on Constant Voltage HOT 1
- Additional Firmata Java library
- Inconsistent state for additional analog pins (A6 - A11) on Arduino Leonardo HOT 1
- Pyfirmata and arduino leonardo mouse and keyboard abilities HOT 2
- T HOT 1
- Error compiling for board Arduino Uno. HOT 1
- Error compiling Firmata for board Arduino Nano Every HOT 8
- Error when compiling StandardFirmata 2.5.8 for Ardbox Analog HF + Wifi from Industrialshields HOT 2
- broken link in readme.md
- Last released version is from 2018 despite a lot of new work being merged HOT 10
- How to change TX RX pin for Nano HOT 3
- To drive a Servo what Capabilities do i need from a board? HOT 2
- Ethernet server mode versus client mode HOT 1
- Arduino HOT 1
- Arduino Nano Every doesn't report A6 and A7 on StandardFirmata HOT 3
- add Arduino UNO R4 MINIMA to boards.h please HOT 11
- [Question] How to add support for Jolly-dev to StandardFirmataWiFi HOT 9
- Firmata for Raspberry Pi Pico HOT 1
- Problem compiling firmata for Giga R1 Wifi board HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from arduino.