Jestでテストを書こう
フロントのテスト本当に難しいですよね、しっかり書いている人を見ると尊敬します。
最近新規のサービスを開発していて、フロントはNuxtで作っているので、storeやcomponentのテストを書いてはいるものの、Nuxtの知見やフロントのテストコードを書くことがあまりなかったので悪戦苦闘しています。
新規というところもあって自由に設計できるので、自動化できる部分は自動化して楽をしたいと思い、CI/CDを行っています。
CI/CDのアーキテクチャ
テストコードの進捗
カバレッジ100を目指しテストコードを書いていますが、進捗はなかなか厳しいです。
stores
Tests: 8 skipped, 630 passed, 638 total Branchの数値が悪いけど、630 個テスト書いて、まあまあかなと思っています。
components
Tests: 303 skipped, 417 passed, 720 total componentのテストが思った以上に難しくて進捗が悪いです。417/720 道のりはまだ長い、もっと頑張らないと日々思う
最後
まだまだ課題が多いいフロントのテストですが、デブレやバグを無くすため、日々頑張っています
Github Actionのset-envとadd-path非推奨
2020/10/1 set-envとadd-pathがセキュリティ上の問題により非推奨、現在ではもう使えなくなっていますね https://github.blog/changelog/2020-10-01-github-actions-deprecating-set-env-and-add-path-commands/
ACTIONS_ALLOW_UNSECURE_COMMANDS
を追加すると動くようですが、追加するより直した方が良いですね
set-env
今まで
echo '::set-env name=ENV::dev'
変更後
echo 'ENV=dev' >> $GITHUB_ENV
add-path
今まで
echo '::add-path::/tmp'
変更後
echo echo '/tmp' >> $GITHUB_PATH
env、pathとも同じような書き方ですね、変更が少なくてよかった!! しかし警告が出ていても、github action上はOKになっているので、全く気づきませんでした今後警告をどのようにして補足していくか課題です。
Lambda + Goでネストされたアプリケーションを構築
LambdaでGoを使ったAPIを作成したときの話 あるサービスでGoを採用し、Lambda上でapiを作成することになった、最初は小規模の認識で開発を行っていたが、仕様がどんどん膨らみ気づいた時にはエンドポイントが150を超え、そしてやってきたリソース制限
Template format error: Number of resources, 206, is greater than maximum allowed, 200
ネストさせることで回避できることを知り、ネストするもsam build
できず、結局ネストされた各アプリケションを個別にビルドし、マージするシェルを書いて運用していた。
苦労した話を書こうと思い調べていると、いつの間にかネストされたアプリケーションのビルドができるようになっていた!!!
https://github.com/aws/aws-sam-cli/issues/1470
前段の話が長くなりましたが、Lambdaでネストされたアプリケーションを簡単に構築できる話です
構築
2つのアプリケーションにネストさせる例です
template.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > lambda-go Sample SAM Template for lambda-go Parameters: Region: Type: String Default: ap-northeast-1 Stage: Type: String Default: Dev ApiDomainName: Type: String Default: api.example.com Resources: # Lambda Application App1Application: Type: AWS::Serverless::Application Properties: Location: app1.yaml Parameters: Region: !Ref Region Stage: !Ref Stage ApiDomainName: !Ref ApiDomainName App2Application: Type: AWS::Serverless::Application Properties: Location: app2.yaml Parameters: Region: !Ref Region Stage: !Ref Stage ApiDomainName: !Ref ApiDomainName
アプリケーション1 app1.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > lambda-go Sample SAM Template for lambda-go # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 10 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: REGION: !Ref Region Parameters: Stage: Type: String Region: Type: String ApiDomainName: Type: String Resources: # ロール App1Role: Type: AWS::IAM::Role Properties: RoleName: app1-role Policies: - PolicyName: app1-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - ec2:CreateNetworkInterface - ec2:DescribeNetworkInterfaces - ec2:DetachNetworkInterface - ec2:DeleteNetworkInterface Resource: '*' AssumeRolePolicyDocument: { Version: "2012-10-17", Statement: [ { Effect: "Allow", Principal: { Service: [ "lambda.amazonaws.com" ] }, Action: [ "sts:AssumeRole" ] } ] } ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Path: / # Api Gateway ApiGateway: Type: AWS::Serverless::Api Properties: StageName: !Ref Stage # Base path mapping ApiGatewayBasePathMapping: Type: AWS::ApiGateway::BasePathMapping Properties: DomainName: !Ref ApiDomainName RestApiId: !Ref ApiGateway BasePath: app1 Stage: !Ref ApiGateway.Stage # Lambda Function Test1Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test1/ Handler: test1 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App1Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test1 Method: GET Test2Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test2/ Handler: test2 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App1Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test2 Method: GET Test3Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test3/ Handler: test3 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App1Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test3 Method: GET
アプリケーション2 app2.yaml
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > lambda-go Sample SAM Template for lambda-go # More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst Globals: Function: Timeout: 10 Environment: # More info about Env Vars: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#environment-object Variables: REGION: !Ref Region Parameters: Stage: Type: String Region: Type: String ApiDomainName: Type: String Resources: # ロール App2Role: Type: AWS::IAM::Role Properties: RoleName: app2-role Policies: - PolicyName: app2-policy PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - ec2:CreateNetworkInterface - ec2:DescribeNetworkInterfaces - ec2:DetachNetworkInterface - ec2:DeleteNetworkInterface Resource: '*' AssumeRolePolicyDocument: { Version: "2012-10-17", Statement: [ { Effect: "Allow", Principal: { Service: [ "lambda.amazonaws.com" ] }, Action: [ "sts:AssumeRole" ] } ] } ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Path: / # Api Gateway ApiGateway: Type: AWS::Serverless::Api Properties: StageName: !Ref Stage # Base path mapping ApiGatewayBasePathMapping: Type: AWS::ApiGateway::BasePathMapping Properties: DomainName: !Ref ApiDomainName RestApiId: !Ref ApiGateway BasePath: app2 Stage: !Ref ApiGateway.Stage # Lambda Function Test10Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test10/ Handler: test10 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App2Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test10 Method: GET Test11Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test11/ Handler: test11 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App2Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test11 Method: GET Test12Function: Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction Properties: CodeUri: ../../test12/ Handler: test12 Runtime: go1.x Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html Role: !GetAtt App2Role.Arn Events: GET: Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api Properties: RestApiId: !Ref ApiGateway Path: /test12 Method: GET
ネスト以外のポイントとして、API GatewayのAPI マッピングを使ってネストされたアプリケーションをマッピングしています。
ApiGatewayBasePathMapping: Type: AWS::ApiGateway::BasePathMapping Properties: DomainName: !Ref ApiDomainName RestApiId: !Ref ApiGateway BasePath: app2 Stage: !Ref ApiGateway.Stage
これをすると、template.yaml
で指定している、ApiDomainName
(api.example.com)で各ネストされたアプリケーションにアクセスできるようになる
例えば、https://api.example.com/app1/test1 とか https://api.example.com/app2/test10 など
*実際に試して頂く場合はApiDomainName
を変更して頂く必要があります
デプロイ
デプロイ時にはcapabilities
にCAPABILITY_AUTO_EXPAND
を指定しデプロイをおこないます、成功するとCloudFormationでネストされたアプリケーションが表示されます
ソース
参考までにソースをあげておきました。