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년 전66회 조회
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일 전

로그인하지 않았습니다. 로그인해야 답변을 게시할 수 있습니다.

좋은 답변은 질문에 명확하게 답하고 건설적인 피드백을 제공하며 질문자의 전문적인 성장을 장려합니다.

질문 답변하기에 대한 가이드라인

관련 콘텐츠