2025 幎 11 æ 19 æ¥ã¯ãAWS ã®ãã¹ã API ã§ãã TestState API ã䜿çšãã AWS Step Functions ã®ããŒã«ã«ãã¹ãæ©èœåŒ·åã«ã€ããŠçããã«ãç¥ããããããšæããŸãã ãããã®æ©èœåŒ·å㯠TestState API çµç±ã§å©çšã§ãããããä»»æã®ãã¹ããã¬ãŒã ã¯ãŒã¯ã䜿çšããŠéçºãã·ã³äžã§ã¯ãŒã¯ãããŒå®çŸ©ãããŒã«ã«ã«æ€èšŒãããšã©ãŒåŠçãã¿ãŒã³ãããŒã¿å€æããµãŒãã¹ã®ã¢ãã¯çµ±åããã¹ãããèªåãã¹ãã¹ã€ãŒããæ§ç¯ã§ããŸããä»åã®ãªãªãŒã¹ã«ãã£ãŠããŒã«ã«ãŠããããã¹ãã®ããã® API ããŒã¹ã®ã¢ãããŒããå°å
¥ãããã®ã§ã Amazon Web Services (AWS) ã«ãããã€ããªããŠãå
æ¬çãªãã¹ãæ©èœã«ããã°ã©ã çã«ã¢ã¯ã»ã¹ã§ããããã«ãªããŸãã 匷åããã TestState API ã«ã¯ã次㮠3 ã€ã®äž»èŠæ©èœãå°å
¥ãããŠããŸãã ã¢ãã¯ãµããŒã â ããŠã³ã¹ããªãŒã ã®ãµãŒãã¹ãåŒã³åºãããšãªãã¹ããŒãåºåãšãšã©ãŒãã¢ãã¯ã§ãããããã¹ããŒããã·ã³ããžãã¯ã®çã®ãŠããããã¹ããå¯èœã«ãªããŸããTestState ã¯ãSTRICT (ãã¹ãŠã®å¿
é ãã£ãŒã«ããæ€èšŒããããã©ã«ãã¢ãŒãïŒãPRESENT (ãã£ãŒã«ãã®ã¿ã€ããšååãæ€èšŒ)ãNONE (æ€èšŒãªã) ã® 3 ã€ã®æ€èšŒã¢ãŒãã䜿çšããŠã¢ãã¯ã¬ã¹ãã³ã¹ã AWS API ã¢ãã«ã«ç
§ãããŠæ€èšŒããããšã§ãå¿ å®åºŠã®é«ããã¹ããå®çŸããŸãã ãã¹ãŠã®ã¹ããŒãã¿ã€ãã®ãµããŒã â Map ã¹ããŒã (ã€ã³ã©ã€ã³ããã³åæ£)ãParallel ã¹ããŒããã¢ã¯ãã£ããã£ããŒã¹ã® Task ã¹ããŒãã.sync ãµãŒãã¹çµ±åãã¿ãŒã³ã.waitForTaskToken ãµãŒãã¹çµ±åãã¿ãŒã³ãªã©ã®é«åºŠãªã¹ããŒããå«ãããã¹ãŠã®ã¹ããŒãã¿ã€ãããã¹ãã§ããããã«ãªããŸãããããã¯ãã¹ããŒãã®é·ç§»ããšã©ãŒåŠçãããŒã¿å€æãªã©ã®å¶åŸ¡ãããŒããžãã¯ãæ€èšŒããããã«ãã¯ãŒã¯ãããŒå®çŸ©å
šäœã§ TestState API ã䜿çšãããŠããããã¹ããäœæã§ããããšãæå³ããŸãã åã
ã®ã¹ããŒãã®ãã¹ã â æ°ãã StateName ãã©ã¡ãŒã¿ã䜿çšããŠãå®å
šãªã¹ããŒããã·ã³å®çŸ©å
ã§ç¹å®ã®ã¹ããŒãããã¹ãããŸããå®å
šãªã¹ããŒããã·ã³å®çŸ©ã 1 床æäŸããã ãã§ãåã¹ããŒããååã§åå¥ã«ãã¹ãã§ããŸããå®è¡ã³ã³ããã¹ããå¶åŸ¡ããŠãç¹å®ã®ãªãã©ã€è©Šè¡ãMap ã®ã€ãã¬ãŒã·ã§ã³é çªããšã©ãŒã·ããªãªããã¹ãã§ããŸãã 匷åããã TestState ã®äœ¿çšãéå§ãã 匷åããã TestState ã®æ°æ©èœãé ã远ã£ãŠèŠãŠãããŸãããã ã·ããªãª 1: æ£åžžãªçµæãã¢ãã¯ãã 1 ã€ç®ã®æ©èœã¯ã¢ãã¯ãµããŒãã§ãããã®æ©èœã䜿çšããŠãå®éã® AWS ãµãŒãã¹ãå€éšã® HTTP ãªã¯ãšã¹ããããåŒã³åºãããšãªãã¯ãŒã¯ãããŒããžãã¯ããã¹ãã§ããŸãããŠããããã¹ãããã°ããè¡ãããã«ãµãŒãã¹ã¬ã¹ãã³ã¹ãã¢ãã¯ããããçµ±åãã¹ãã®ããã«å®éã® AWS ãµãŒãã¹ã䜿ã£ãŠãã¹ããããã§ããŸããã¢ãã¯ã¬ã¹ãã³ã¹ã䜿çšãããšãã« AWS Identity and Access Management (IAM) èš±å¯ã¯å¿
èŠãããŸããã 以äžã¯ãæ£åžžãª AWS Lambda 颿°ã¬ã¹ãã³ã¹ãã¢ãã¯ããæ¹æ³ã§ãã aws stepfunctions test-state --region us-east-1 \ --definition '{ "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": {"FunctionName": "process-order"}, "End": true }' \ --mock '{"result":"{\"orderId\":\"12345\",\"status\":\"processed\"}"}' \ --inspection-level DEBUG ãã®ã³ãã³ãã¯ãå®éã«é¢æ°ãåŒã³åºãããšãªã Lambda åŒã³åºãã¹ããŒãããã¹ãããŸããTestState ã¯ãã¢ãã¯ã¬ã¹ãã³ã¹ã Lambda ãµãŒãã¹ API ã¢ãã«ã«ç
§ãããŠæ€èšŒããŠããã¹ãããŒã¿ããµãŒãã¹ããå®éã«è¿ããããã®ãšäžèŽããããšã確èªããŸãã ã¬ã¹ãã³ã¹ã«ã¯ãå®è¡ãæ£åžžã«è¡ãããããšãšãè©³çŽ°ãªæ€æ»ããŒã¿ã衚瀺ãããŸã (DEBUG æ€æ»ã¬ãã«ã®äœ¿çšæïŒã { "output": "{\"orderId\":\"12345\",\"status\":\"processed\"}", "inspectionData": { "input": "{}", "afterInputPath": "{}", "afterParameters": "{\"FunctionName\":\"process-order\"}", "result": "{\"orderId\":\"12345\",\"status\":\"processed\"}", "afterResultSelector": "{\"orderId\":\"12345\",\"status\":\"processed\"}", "afterResultPath": "{\"orderId\":\"12345\",\"status\":\"processed\"}" }, "status": "SUCCEEDED" } ã¢ãã¯ã¬ã¹ãã³ã¹ãæå®ãããšãTestState ããã®ã¬ã¹ãã³ã¹ã AWS ãµãŒãã¹ã® API ã¢ãã«ã«ç
§ãããŠæ€èšŒããã¢ãã¯ãããããŒã¿ãæåŸ
ãããã¹ããŒãã«åŸã£ãŠããã®ã確èªãããããå®éã® AWS ãµãŒãã¹ã³ãŒã«ãå¿
èŠãšããã«å¿ å®åºŠã®é«ããã¹ããç¶æã§ããŸãã ã·ããªãª 2: ãšã©ãŒç¶æ
ãã¢ãã¯ãã ãšã©ãŒç¶æ
ãã¢ãã¯ããŠãšã©ãŒåŠçããžãã¯ããã¹ãããããšãå¯èœã§ãã aws stepfunctions test-state --region us-east-1 \ --definition '{ "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": {"FunctionName": "process-order"}, "End": true }' \ --mock '{"errorOutput":{"error":"Lambda.ServiceException","cause":"Function failed"}}' \ --inspection-level DEBUG ãã®ã³ãã³ã㯠Lambda ãµãŒãã¹äŸå€ãã·ãã¥ã¬ãŒãããã®ã§ãAWS ç°å¢å
ã§ãšã©ãŒãå®éã«çºçãããããšãªããã¹ããŒããã·ã³ãã©ã®ããã«å€±æãåŠçããã®ããæ€èšŒã§ããŸãã ã¬ã¹ãã³ã¹ã«ã¯ã倱æããå®è¡ãšãšã©ãŒã®è©³çްã衚瀺ãããŸãã { "error": "Lambda.ServiceException", "cause": "Function failed", "inspectionData": { "input": "{}", "afterInputPath": "{}", "afterParameters": "{\"FunctionName\":\"process-order\"}" }, "status": "FAILED" } ã·ããªãª 3: Map ã¹ããŒãããã¹ããã 2 çªç®ã®æ©èœã¯ããããŸã§ãµããŒããããŠããªãã£ãã¹ããŒãã¿ã€ãã®ãµããŒãã远å ããŸãã以äžã¯ãDistributed Map ã¹ããŒãããã¹ãããæ¹æ³ã§ãã aws stepfunctions test-state --region us-east-1 \ --definition '{ "Type": "Map", "ItemProcessor": { "ProcessorConfig": {"Mode": "DISTRIBUTED", "ExecutionType": "STANDARD"}, "StartAt": "ProcessItem", "States": { "ProcessItem": { "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": {"FunctionName": "process-item"}, "End": true } } }, "End": true }' \ --input '[{"itemId":1},{"itemId":2}]' \ --mock '{"result":"[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]"}' \ --inspection-level DEBUG ã¢ãã¯çµæã¯ãè€æ°ã¢ã€ãã ã®åŠçããã®å®å
šãªåºåã衚ããŠããŸãããã®å Žåãã¢ãã¯é
åãæåŸ
ããã Map ã¹ããŒãã®åºå圢åŒãšäžèŽããå¿
èŠããããŸãã ã¬ã¹ãã³ã¹ã¯ãé
åå
¥åãæ£åžžã«åŠçãããããšã瀺ããŠããŸãã { "output": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]", "inspectionData": { "input": "[{\"itemId\":1},{\"itemId\":2}]", "afterInputPath": "[{\"itemId\":1},{\"itemId\":2}]", "afterResultSelector": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]", "afterResultPath": "[{\"itemId\":1,\"status\":\"processed\"},{\"itemId\":2,\"status\":\"processed\"}]" }, "status": "SUCCEEDED" } ã·ããªãª 4: Parallel ã¹ããŒãããã¹ããã è€æ°ã®ãã©ã³ããåæã«å®è¡ãã Parallel ã¹ããŒããåæ§ã«ãã¹ãã§ããŸãã aws stepfunctions test-state --region us-east-1 \ --definition '{ "Type": "Parallel", "Branches": [ {"StartAt": "Branch1", "States": {"Branch1": {"Type": "Pass", "End": true}}}, {"StartAt": "Branch2", "States": {"Branch2": {"Type": "Pass", "End": true}}} ], "End": true }' \ --mock '{"result":"[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]"}' \ --inspection-level DEBUG ã¢ãã¯çµæã¯ããã©ã³ãããšã« 1 ã€ã®èŠçŽ ãæã€é
åã§ããå¿
èŠããããŸããTestState ã䜿çšããããšã«ãããã¢ãã¯ããŒã¿æ§é ãå®éã® Parallel ã¹ããŒãå®è¡ã§çæããããã®ãšäžèŽããããšãããããŸãã ã¬ã¹ãã³ã¹ã«ã¯ã䞊åå®è¡ã®çµæã衚瀺ãããŸãã { "output": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]", "inspectionData": { "input": "{}", "afterResultSelector": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]", "afterResultPath": "[{\"branch1\":\"data1\"},{\"branch2\":\"data2\"}]" }, "status": "SUCCEEDED" } ã·ããªãª 5: å®å
šãªã¯ãŒã¯ãããŒå
ã§åã
ã®ã¹ããŒãããã¹ããã StateName ãã©ã¡ãŒã¿ã䜿çšããŠãå®å
šãªã¹ããŒããã·ã³å®çŸ©å
ã§ç¹å®ã®ã¹ããŒãããã¹ãã§ããŸãã以äžã¯ãåäžã®ã¹ããŒãããã¹ãããäŸã§ãããå®å
šãªã¯ãŒã¯ãããŒå®çŸ©ãæäŸãããã¹ãããã¹ããŒããæå®ããã®ãäžè¬çã§ãã aws stepfunctions test-state --region us-east-1 \ --definition '{ "Type": "Task", "Resource": "arn:aws:states:::lambda:invoke", "Parameters": {"FunctionName": "validate-order"}, "End": true }' \ --input '{"orderId":"12345","amount":99.99}' \ --mock '{"result":"{\"orderId\":\"12345\",\"validated\":true}"}' \ --inspection-level DEBUG ãã®ã³ãã³ãã¯ãç¹å®ã®å
¥åããŒã¿ã䜿çšã㊠Lambda åŒã³åºãã¹ããŒãããã¹ããããã®ã§ãTestState ããã®å
¥åãã©ã®ããã«åŠçããã¹ããŒãå®è¡ãéããŠå€æããã®ãã瀺ããŸãã ã¬ã¹ãã³ã¹ã«ã¯ãå
¥åã®åŠçãšæ€èšŒã®è©³çްã衚瀺ãããŸãã { "output": "{\"orderId\":\"12345\",\"validated\":true}", "inspectionData": { "input": "{\"orderId\":\"12345\",\"amount\":99.99}", "afterInputPath": "{\"orderId\":\"12345\",\"amount\":99.99}", "afterParameters": "{\"FunctionName\":\"validate-order\"}", "result": "{\"orderId\":\"12345\",\"validated\":true}", "afterResultSelector": "{\"orderId\":\"12345\",\"validated\":true}", "afterResultPath": "{\"orderId\":\"12345\",\"validated\":true}" }, "status": "SUCCEEDED" } ãããã®æ©èœåŒ·åã¯ã䜿ãæ
£ããããŒã«ã«éçºãšã¯ã¹ããªãšã³ã¹ã Step Functions ã¯ãŒã¯ãããŒã«åãå
¥ããããã倿Žã AWS ã¢ã«ãŠã³ãã«ãããã€ããåã«ãããã«é¢ãããã£ãŒãããã¯ãå³åº§ã«åŸãããšãã§ããŸããèªåãã¹ãã¹ã€ãŒããäœæããã¯ã©ãŠãå®è¡ãšåãä¿¡é Œæ§ã¬ãã«ã§ãã¹ãŠã® Step Functions ç¹åŸŽéãæ€èšŒã§ããããããããã€æã«ã¯ãŒã¯ãããŒãæåŸ
ã©ããã«åäœãããšããèªä¿¡ãåŸãããŸãã ç¥ã£ãŠããããããš çæç¹ã¯ä»¥äžã®ãšããã§ãã å¯çšæ§ â 匷åããã TestState æ©èœã¯ãStep Functions ããµããŒããããŠãããã¹ãŠã® AWS ãªãŒãžã§ã³ ã§ãå©çšããã ããŸãã æé â TestState API ã³ãŒã«ã¯ AWS Step Functions ã«å«ãŸããŠããã远å ã®æéã¯ããããŸããã ãã¬ãŒã ã¯ãŒã¯äºææ§ â TestState 㯠HTTP ãªã¯ãšã¹ããè¡ãããšãã§ãããã¹ãŠã®ãã¹ããã¬ãŒã ã¯ãŒã¯ (JestãpytestãJUnit ãªã©) ã§åäœããŸãããããã€åã«ãç¶ç¶çã€ã³ãã°ã¬ãŒã·ã§ã³ãšç¶ç¶çããªããªãŒ (CI/CD) ãã€ãã©ã€ã³ã§ã¯ãŒã¯ãããŒãèªåçã«æ€èšŒãããã¹ãã¹ã€ãŒããäœæã§ããŸãã ç¹åŸŽéãµããŒã â 匷åããã TestState ã¯ãDistributed Map ã¹ããŒããParallel ã¹ããŒãããšã©ãŒåŠçãJSONATA åŒãªã©ããã¹ãŠã® Step Functions ç¹åŸŽéããµããŒãããŸãã ããã¥ã¡ã³ã â ããŸããŸãªæ§æã«å¯Ÿãããªãã·ã§ã³ã®è©³çްã«ã€ããŠã¯ TestState ããã¥ã¡ã³ã ãæŽæ°ããããªã¯ãšã¹ãããã³ã¬ã¹ãã³ã¹ã¢ãã«ã«ã€ããŠã¯ API ãªãã¡ã¬ã³ã¹ ãåç
§ããŠãã ããã TestState ãéçºã¯ãŒã¯ãããŒã«çµ±åããŠã匷åãããããŒã«ã«ãã¹ããä»ããå§ããŸãããã ããããŒãã«ãã£ã³ã°! â Donnie åæã¯ ãã¡ã ã§ãã