https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1edb9aef-2ee6-45a3-bb4a-5effaec4d2e8/cdk-testing.jpg

Several people have asked me about unit testing CDK applications recently. The questions often go something like this:

“Because it can be in Python or TS, people bring up unit testing for CDK, whereas it’s not even thought about with Serverless Framework, SAM or Terraform. What are your thoughts on this?”

“I have so many tests for my CDK application that they are kind of a pain to maintain. Am I doing this right?”

“Whenever I change my CDK code I also have to change the test, that just doesn’t feel right. That doesn’t feel right… feels like I’m just repeating myself with these tests.”

These are all valid questions, so let’s take a moment to reflect on them.

Testing with purpose

I’m all for testing. Testing is a big part of my serverless workshop and I have dedicated a lot of time to figuring out the best ways to test serverless architectures.

Tests help us reduce defects and build better software, but they also come with costs. They take time to conceive (coming up with good test cases is not always easy), write and maintain.

You should consider the return on investment with everything you do. Because your time is valuable and one of the most scarce resources for your business.

Testing for testing’s sake is pointless and tests that deliver no value have no place in your codebase.

Lack of testing for IaC

Infrastructure management tools come in many flavours.

Tools such as Serverless framework, SAM and Terraform use a declarative approach. They offer limited or no programmability, so you can’t easily introduce business logic into your infrastructure-as-code configurations. This is a blessing for most because what resources are created and how they are configured should be obvious at a glance. I shouldn’t have to spend hours studying a codebase just to figure out if a Lambda function is provisioned, or what IAM permissions it has.

By and large, IaC tools that rely on a declarative don’t require unit testing because:

a) There is no business logic. There are no “behaviours” that need to be validated using different inputs.

b) CloudFormation already ensures your IaC code is syntactically correct.

But being syntactically correct doesn’t mean your IaC is semantically correct. That is, your resources are configured correctly and give you the behaviour that you expect.

Can you use unit tests to ensure a Serverless/SAM/CloudFormation project is semantically correct?

Technically yes. But in practice, probably not. Here’s why.