8

Based on the examples I see, the code assertions are expected json cf template versus the cdk synth generated template.

How do we setup expected json cf template?

  • If we manually create it, that defeats the purpose of using cdk.
  • If we just copy paste the cdk synth output, that defeats the purpose of unit testing it.

Having said that, is there a purpose on having unit tests for CDK code? Maybe I'm missing the idea here. Please do point it out.

matsev
  • 32,104
  • 16
  • 121
  • 156
froi
  • 7,268
  • 5
  • 40
  • 78
  • I never understood the point of the CDK tests as they are presented after running "cdk init". It seems like we are manually checking that CDK can make CF templates. It looks like the test gives me nothing that `cdk diff` or `cdk synth` couldn't. I guess if your CDK stack is a dynamic mess of code that generates wildly differing configurations based on parameters, it might have its use ... I would prefer a test that deployed parts of my code to something like LocalStack and ran som simple tests against that. – mhvelplund Aug 29 '23 at 17:47

2 Answers2

7

aws-cdk has a library of testing utilities that are useful for asserting against stacks. The cdk repo uses it itself for a lot of its own unit tests.

https://www.npmjs.com/package/@aws-cdk/assert

This allows you to do something like

// jest
test('configurable retention period cannot exceed 14 days', () => {
  const stack = new MyStack();
  expect(stack).to(haveResource('AWS::SomeService::SomeResource', {
    SomePropertyOnResource: 'some-value-it-should-have'
  }));
});

This is only supported for CDK apps written in typescript as of now, but the plan is to eventually support all languages cdk supports.

Whether or not you should do this usually is similar to asking whether you should unit test any codebase. If you have a lot of complex business logic happening that does things like conditionally creating resources or otherwise changing your apps behavior, its probably worth getting some coverage in those places. If your app is essentially a bunch of static declarations without conditionals, loops, etc, maybe you can get by with just running cdk diff when making changes and manually verifying your expected changes.

If you're writing custom constructs for reusing in different cdk apps, unit testing those is probably a good idea.

Some relevant docs https://docs.aws.amazon.com/cdk/latest/guide/testing.html

Mitchell Valine
  • 234
  • 1
  • 3
0

An approach that I use, is to create a different project delegated to use the resources that i expect that have been created.

So, from the cdk-init-cluster project, i simply create all the necessary resources using cdk library. Than, after the DEPLOY phase, i run the cdk-init-cluster-test module that is delegated to populate/query/use the resources previously created from the cdk-init-cluster project.

This approach, can only help with few type of resources such as:

  • S3 bucket
  • Lambda
  • AppSync
  • DynamoDB table

The test project is in charge to:

  • Populate the DynamoDB table and retrieve the data.
  • Call the Lambda function with dummy data
  • Call the lambda function with correct data for verify permission behaviour
  • Call appsync (that wrap all the resources above) and verify the result

Then, i remove the data inserted for test. If no exceptions occurs, the test is passed.

alessiosavi
  • 2,753
  • 2
  • 19
  • 38
  • In this scenario, when will the test fail? – froi Feb 14 '20 at 12:42
  • Updated with (unfortunately) not so useful information – alessiosavi Feb 15 '20 at 09:21
  • What you added makes sense. But if I understand correctly, what you are describing is more akin to an integration test. Since the tests would testing against actual AWS services. Do you also do unit tests, only testing the cf template generation? – froi Feb 17 '20 at 16:50
  • Sincerely, i did not find any sense for compare the cf template with a given one. From my side, is necessary to be sure that the environment is up and running, testing the basic use case for be sure that policy and resources are "spawn" correctly. You are right, due to the deploy phase, is an integration test. I haven't found another way to be sure that the environment (from a resources POV) is ready to production. – alessiosavi Feb 17 '20 at 19:51