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?

質問済み 2年前67ビュー
1回答
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
回答済み 13日前

ログインしていません。 ログイン 回答を投稿する。

優れた回答とは、質問に明確に答え、建設的なフィードバックを提供し、質問者の専門分野におけるスキルの向上を促すものです。

質問に答えるためのガイドライン

関連するコンテンツ