Test Step Function with CDK - Best Practice

0

I created a simple test function with a task that invokes lambda.

    Function weatherToday = Function.Builder.create(this, "WeatherToday")
        .code(Code.fromAsset(getClass().getClassLoader().getResource("lambda/weather_today").getPath()))
        .runtime(Runtime.NODEJS_14_X)
        .architecture(Architecture.ARM_64)
        .handler("WeatherToday.handler")
        .timeout(Duration.seconds(25))
        .build();

    IChainable getCurrentWeather = LambdaInvoke.Builder.create(this, "Get Current Weather")
        .lambdaFunction(weatherToday)
        .retryOnServiceExceptions(true)
        .build();

    Pass hotState = new Pass(this, "It is HOT!");
    Pass coldState = new Pass(this, "It is COLD!!");

    Choice isItHot = new Choice(this, "Is it Hot?")
        .when(Condition.numberGreaterThanEquals("$.Payload.temp_f", 90), hotState)
        .otherwise(coldState);

    IChainable chain = Chain.start(getCurrentWeather).next(isItHot);

    StateMachine.Builder.create(this, "IsItHotNow").definition(chain).timeout(Duration.seconds(60))// best practice
        .build();
  }

Assuming this is the best practice, I wanted to write a test that checks whether the states transition or are chained as intended. When pulling in the DefinitionString for the given state function

 "DefinitionString": {
          "Fn::Join": [
            "",
            [
              "{\"StartAt\":\"Get Current Weather\",\"States\":{\"Get Current Weather\":{\"Next\":\"Is it Hot?\",\"Retry\":[{\"ErrorEquals\":[\"Lambda.ServiceException\",\"Lambda.AWSLambdaException\",\"Lambda.SdkClientException\"],\"IntervalSeconds\":2,\"MaxAttempts\":6,\"BackoffRate\":2}],\"Type\":\"Task\",\"Resource\":\"arn:",
              {
                "Ref": "AWS::Partition"
              },
              ":states:::lambda:invoke\",\"Parameters\":{\"FunctionName\":\"",
              {
                "Fn::GetAtt": [
                  "WeatherToday53196B63",
                  "Arn"
                ]
              },
              "\",\"Payload.$\":\"$\"}},\"Is it Hot?\":{\"Type\":\"Choice\",\"Choices\":[{\"Variable\":\"$.Payload.temp_f\",\"NumericGreaterThanEquals\":90,\"Next\":\"It is HOT!\"}],\"Default\":\"It is COLD!!\"},\"It is COLD!!\":{\"Type\":\"Pass\",\"End\":true},\"It is HOT!\":{\"Type\":\"Pass\",\"End\":true}},\"TimeoutSeconds\":60}"
            ]
          ]
        }

The above is an array of strings with inlined intrinsic ASL functions. There does not seem to be a good way to get the state definitions to resemble the typical state function definition file as json without the intrinsic functions. My thoughts are if I can get the appropriate state machine definition as a json format of ASL it will be easier to test for the expected states.

Please let me know if there is a way to do this or what may be the best practice approach?

asked 2 years ago62 views
1 Answer
0

Hello! This Fine-grained assertions section (at the bottom of that section there is a Step Function example) may be of help that makes use of the assertions module. In particular for Step Function definitions, the Match.serializedJson() matcher might be useful. In theory that could help you assert your Tasks are transitioning or chaining as expected.

Another approach using the Matching lib could be something like the following (Typescript snippet example)

...
    it('Get Current Weather should transition to "Is it Hot?", () => {
      const GET_WEATHER= 'Get Current Weather'
      const IS_IT_HOT = "Is it Hot?"
      template.hasResourceProperties('AWS::StepFunctions::StateMachine', {
        DefinitionString: {
          'Fn::Join': [
            '',
            Match.arrayWith([
              Match.stringLikeRegexp(
                `("${GET_WEATHER}":{"Next":"${IS_IT_HOT}").*`,
              ),
            ]),
          ],
        },
      });
    });
...

Hope this gives you some ideas!

David
answered 3 days ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions