advertisement
Lumi4 -- Unit and Integration Tests
Unit and integration tests
I mentioned in a previous post that I found it more difficult to differentiate between unit and integration tests. But this distinction was critical to implementing tests that could cover frameworks designed to interact with embedded systems. At least, from my perspective. Below is a summary of how I'm structuring the tests for the Lumi4 codebase.
Lumi4.Tests
The unit tests namespace will contain all tests that cover methods that can be operated independently, without communication with any system other than the program itself.
For example,
[Test class]
public class constructor
{
[Test method]
public void WifiCentralManagerConstructor_Null_Exception()
{
bool ThrewNull = false;
try
{
WifiCentralManager wifiCentralManager = new WifiCentralManager(null);
}
catch (Exception ex)
{
ThrewNull = true;
}
Assert.IsTrue(ThewNull);
}
}
The test above covers a constructor method, which should always be able to be executed effectively without any communication with a
Lumi4.Integration tests
In a previous post I reviewed the epiphanic difference between integration and unit testing. Integration tests are actually intended for code that depends on external systems; database query result, characters from a file stream, or characters from a UART device. For Lumi4 there are three systems on which the program depends.
- Remote Bluetooth device(s)
- Remote Wifi device(s)
- Intel HEX file streaming
For the first two I have decided to focus on integration testing instead of mocks and backups. My reasoning is twofold: I most likely modify the firmware on the remote devices. Secondly, I still don't understand drills and stubs. Trying to focus on MVP.
Of course, when I finally made a plan of action, a new struggle arose. Much of my Bluetooth and Wifi handling depended on asynchronous callbacks. And this is not the easiest thing to address in MSTesting (which is the test suite I'm using for this iteration). However, in the end, I hacked the following logic
[Test method]
Public asynchronous task Search_FindsWebServer_ValidIp()
{
var localNetwork = Lumi4IntegrationTestSettings.LocalIP;
WifiCentralManager wifiCentralManager = new WifiCentralManager(localNetwork);
bool devicefound = false;
wifiCentralManager.DiscoveredDevice += delegate(object obj, arguments DiscoveredDeviceEventArgs)
{
if (args.DiscoveredPeripheral != null) { device found = true; }
};
wifiCentralManager.Search(90, 120);
await Task.Delay(Lumi4IntegrationTestSettings.SearchWifiCallbackDelay);
Assert.IsTrue(device found);
}
There are some inputs that are mostly provided manually for testing, for example, the local IP and the target device IP. At the top of the method there is a flag that will identify if the device was found. It then takes this information, sets up a method delegate (callback), and attempts to communicate with the device. Finally, there is an asynchronous delay whose purpose is to allow the search enough time to execute correctly. If the test finds the device within the given time, the callback is triggered and the flag is set to true. Otherwise it returns with error.
I'm not sure about the validity, but it's what I got (so far).
advertisement
Related Articles
advertisement