Unit testing a AWS #Lambda function with #Cloudwatch
Unit testing is primarily used to detect breaking code changes, but it can also be used to detect breaking changes in external environments, if run periodically.
So, imagine your code connects to an external database, that is operated by a third party. Perhaps they might suddenly change something without telling you, and your code breaks in the middle of the night, with no warning. In fact the first alert you’ll get will be an irate customer.
I’m assuming a serverless environment running Node on Lambda.
So, firstly, I set up a special entry point for my Lambda function, so that it knows it’s under test; In my case, was the following
exports.handler = function (event, context) {
if (typeof event.request == “undefined”)
{
console.log(“Lambda called via Cloudwatch”);
console.log(event);
console.log(event.test);
testing.selectTest(event.test,function(){
context.succeed();
});
return;
}
Which, in my case, was if the lambda function was being called via cloudwatch, rather than alexa, it wouldn’t have a event.request element, but would have a event.test element.
Now, “testing” is a javascript file, which selects a test as follows;
module.exports.selectTest = function(testName,callback)
{var testMethod = null;
if (testName == “testA”) testMethod = testA;testMethod(
function(pass)
{
console.log(pass);
console.log(testName + ” passed”);
},
function(fail)
{
console.log(fail);
console.log(testName + ” failed”);
email.send({..} )}
In this case, it would just console.log the output, unless, it failed, it would email me with the warning.
An individual test would be defined as
function testA(pass, fail)
{
myIntent.Search(function(result)
{
if(result == “Fail“)
{
fail(result);
}
else
{
pass(result);
}
});
}
myIntent.Search is outside of the scope of this example, but in this example, imagine it returns “Fail” on Failure, and some other string on success.
Now, to schedule this regularly, then you create a CloudWatch Rule, where you set the event source to a schedule of 1 day (in my case), and the target to your lambda function. You set the input to a constant JSON text of {“test”: “testA”}, or whatever the name of your test is.
Hopefully, this will mean if someone unplugs your database, you will get an alert before your customers discover it’s down.