革命のブログ

フレボワークスの社員がブログを通じて情報発信します。

年末年始休業のお知らせ

平素より、弊社には格別のご厚情を賜り厚くお礼申し上げます。
誠に勝手ながら、下記のとおり年末年始休業とさせていただきます。

■休業期間:2025年12月27日(土)~2026年1月4日(日)

休業期間中のご連絡については、5日(月)以降、順次ご対応させて頂きます。

ご迷惑おかけしますが、宜しくお願い申し上げます。

夏季休業のお知らせ

誠に勝手ながら、弊社では下記の期間につきまして夏季休業とさせて頂きます。

期間中はご不便ご迷惑をおかけ致しますが、何卒ご了承くださいますよう

お願い申し上げます。

・夏季休業期間:2025年8月13日(火)~8月15日(金)

尚、12日(火)は弊社休暇促進日となり、職員の出社は限られますので、

対応等は翌週18日(月)以降とさせて頂きます。

以上、宜しくお願い申し上げます。

E2Eテスト自動化ツール「Playwright」を試してみた

どうも、小野です。今回はWebアプリにおけるE2Eテストツール「Playwright」を紹介します。E2Eテストと言えば、ブラウザの操作をテストコードとして実装していくイメージだと思いますが、こちらのツールを利用すると、ブラウザ操作を記録でき、それをコード化してくれます。もちろんある程度の修正は必要になりますが、1からコードを書く必要がないためとても効率的です。

環境構築

以下のアプリケーションをインストールしてください。

  • VSCode
  • Node.js

次にVSCodeにPlaywrightのプラグインをインストールしてください。 https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright

手順

プロジェクト作成

以下のコマンドを実行します。

> mkdir test-playwright
> cd test-playwright
> npm init playwright@latest

Getting started with writing end-to-end tests with Playwright:
Initializing project in '.'
√ Do you want to use TypeScript or JavaScript? · TypeScript
√ Where to put your end-to-end tests? · tests
√ Add a GitHub Actions workflow? (y/N) · false
√ Install Playwright browsers (can be done manually via 'npx playwright install')? (Y/n) · true

VSCodeで作成したフォルダを開きます。

左側のプラグイン一覧から、Playwrightを選択します。

表示されたパネルから「Record new」をクリックします。するとブラウザが表示され、操作した内容が記録されます。

操作の記録が終わると以下のようなコードが作成されました。

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  // 指定のURLを表示
  await page.goto('https://www.frevo-works.co.jp/');
  // 指定のリンクをクリック
  await page.getByRole('link', { name: '会社概要 ABOUT' }).click();
});

このまま実装されたコードを実行してみます。先ほど操作したものが自動で実行されました。

記録されたコードにはあくまでも操作のみであり、検証するためのコードがないため自分で実装する必要があります。

今回は画面に想定した内容が正しく表示されているか検証します。

import { expect, test } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://www.frevo-works.co.jp/');
  await page.getByRole('link', { name: '会社概要 ABOUT' }).click();

  // 検証(追加)
  await expect.soft(page.locator("dl").nth(0).locator("dt")).toHaveText("社名");
  await expect.soft(page.locator("dl").nth(0).locator("dd")).toHaveText("フレボワークス株式会社 FrevoWorks, Inc.");
});

他にも様々な書き方がありますので、公式サイトを確認してください。

検証コードを追加したら実行してみます。

今度はエラーになるように変更します。

import { expect, test } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://www.frevo-works.co.jp/');
  await page.getByRole('link', { name: '会社概要 ABOUT' }).click();

  // 検証
  await expect.soft(page.locator("dl").nth(0).locator("dt")).toHaveText("エラー"); // 変更
  await expect.soft(page.locator("dl").nth(0).locator("dd")).toHaveText("フレボワークス株式会社 FrevoWorks, Inc.");
});

変更したら、実行します。

以下のようにエラーに出力されることが確認できます。

1) [chromium] › tests\test-1.spec.ts:3:5 › test ──────────────────────────────────────────────────

    Error: Timed out 5000ms waiting for expect(locator).toHaveText(expected)

    Locator: locator('dl').first().locator('dt')
    Expected string: "エラー"
    Received string: "社名"
    Call log:
      - expect.soft.toHaveText with timeout 5000ms
      - waiting for locator('dl').first().locator('dt')
        9 × locator resolved to <dt>…</dt>
          - unexpected value "社名"

       6 |
       7 |   // 検証
    >  8 |   await expect.soft(page.locator("dl").nth(0).locator("dt")).toHaveText("エラー");
         |                                                              ^
       9 |   await expect.soft(page.locator("dl").nth(0).locator("dd")).toHaveText("フレボワークス株式会社 FrevoWorks, Inc.");
      10 | });
        at C:\Users\devel\workspace\test-playwright\tests\test-1.spec.ts:8:62

  1 failed
    [chromium] › tests\test-1.spec.ts:3:5 › test ───────────────────────────────────────────────────

おわりに

E2Eテストは複雑というイメージが変わったのではないでしょうか?検証コードは自分で実装が必要だとしても、操作は全て記録できるので大幅なコスト削減につながると思います。今回は割愛しましたが、GithubActionsなどのCI連携も可能です。

テスト自動化を導入して、低コストで高品質なモノを作りましょう。

参考ページ

https://playwright.dev/

React Nativeを選んだ理由とは?

どうも、小野です。私はずっとWebアプリ開発を行ってきたので、スマホアプリ開発は未経験です。興味本位で軽く触ったことはありますが、初心者同然です。最近、Android開発のデベロッパーに登録したこともあり、勉強し始めたところです。(iOSは1年単位の更新があるので登録していません) まず、スマホアプリ開発の方法として、以下の2つがあると思います。

  • Android、iOSそれぞれのネイティブ言語で開発する

  • クロスプラットフォームフレームワークを利用して開発する。

今回はネイティブ言語をそれぞれ学習するのは大変なので、後者について検討してみます。現在、クロスプラットフォームなフレームワークには主にReact NativeとFlutterが主流となっています。 React NativeとFlutterの比較は他の記事にもたくさんあるのでそちらを参考にしていただき、ここでは私がReact Nativeを選択した理由をお話したいと思います。(正確にはReact Native+Expoです。) 選択した理由としては3つあります。

  • TypeScriptで開発が可能

  • ストアを介さずにアップデートが可能

  • 開発OSに制限がない

TypeScriptで開発ができる

TypeScriptは現代のWebフロントエンド開発において最も人気のある言語の一つです。特に以下のような利点があります。

  • 静的型チェックによりバグの早期発見が可能

  • コード補完やリファクタリングのサポートが充実

  • 大規模なアプリケーション開発での保守性が高い

Webフロントエンド開発者にとって、React NativeでTypeScriptが使えることは以下のような大きなメリットがあります:

  • 既存のTypeScriptの知識やベストプラクティスをそのまま活用できる

  • React/React Nativeのコンポーネント開発で型の恩恵を受けられる

  • npmパッケージの型定義を活用でき、安全にライブラリを利用できる

これにより、Webフロントエンド開発からモバイルアプリ開発への移行がスムーズになり、学習コストを大幅に削減することができます。

※FlutterはDartという言語を覚える必要があります。

ストアを介さずにアップデートが可能

アプリをストアを介さずに更新できるOTAアップデート(Over The Air update)が可能です。 React NativeとExpoを組み合わせることで、アプリの新バージョンをサーバーにアップロードし、ユーザーが次回アプリを起動した際に自動的に更新を適用することができます。 これにより、以下のようなメリットがあります。

  • バグ修正や小規模な機能更新を迅速にリリースできる

  • App StoreやGoogle Play Storeのレビュープロセスを待つ必要がない

  • ユーザーが手動でアプリを更新する手間を省ける

ただし、ネイティブコードの変更を伴う更新の場合は、従来通りストアを通じた配布が必要になります。

※Flutterにはこのような機能はありません。

開発OSに制限がない

通常、iOSアプリを開発する場合、ビルドやテストにMacOSが必要となります。これは、iOSの開発環境であるXcodeがMacOS専用のソフトウェアだからです。 しかし、React NativeとExpoを組み合わせ、さらにEAS(Expo Application Services)を利用することで、この制限を回避できます。EASはクラウド上でビルドを実行するため、開発者のローカル環境に依存せず、WindowsやLinuxなど、どのOSからでもiOSアプリの開発が可能になります。 これにより、以下のようなメリットがあります。

  • 開発チームのメンバーが好みのOSを選択できる

  • MacOSの端末を用意する必要がなく、初期コストを抑えられる

  • クラウド上でビルドを行うため、ローカル環境の負荷を軽減できる

※Flutterを利用した場合、iOSアプリ開発にはMacOSが必要になります。

注意点

React Native + Expoには以下のようなデメリットがあるので、それを理解した上でプロジェクトの要件に合わせて適切な判断を行うことが重要です。

  • ネイティブな機能へのアクセスが制限される可能性がある

  • バンドルサイズが大きくなりがち

  • パフォーマンスがネイティブアプリに比べて劣る場合がある

Expoの無料プランには制限がある(ビルド回数制限など) 特に以下の場合は、React Native + Expoの使用を慎重に検討する必要があります。

  • 高度なハードウェア機能を使用する必要がある場合

  • 極めて高いパフォーマンスが要求される場合

  • アプリのサイズを極限まで小さくする必要がある場合

おわりに

注意点にも書きましたが、採用するかどうかはアプリ要件次第ではあるので、慎重に検討する必要があります。私自身、仕事で開発予定はなく、個人で開発する手始めとして調査したところ、学習コストをかけずにできることが最優先ではあったので、ReactNativeを採用しました。 もし、アプリ開発の方法で悩んでたら判断材料として参考にしていただけると幸いです。

AWS SAMとserverless-java-containerを使って、SpringBootアプリケーションを最速で構築してみた

はじめに

久しぶりの技術記事です。今回はタイトルにもあるとおりJavaのディファクトスタンダードでもあるフレームワークSpringBootのアプリケーションをAPI Gateway+Lambdaに構築する方法をご紹介します。

昔はLambdaのランタイムとしてJavaを利用することは、JVM起動時間が遅いため避けられてきましたが、「Lambda SnapStart」機能の追加により起動速度が向上し、実用的に利用できるようになりました。このアップデートによりアーキテクチャの選択肢としてJavaも実用的なものとなっています。

※今回はSnapStartの設定は行いません。

事前準備

  • AWSアカウントを持っていること
  • Administrator権限のIAMユーザが作成されていて、アクセスキー、シークレットキーを発行していること

環境

  • Windows11

手順

JDKのセットアップ

こちらのページよりインストーラーをダウンロードします。

ダウンロードが完了したらインストーラーを実行し、インストールを行います。

インストールが完了したら、コマンドプロンプトを起動し、以下のコマンドを実行します。

> java -version

openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)

上記の結果が表示されればセットアップ完了です。

※JDKのディストリビューションをAmazon Correttoにしているのは、LambdaのJavaランタイムが使用しており、ローカルとの環境の差分をなくすためです。

Mavenのセットアップ

こちらのページよりバイナリをダウンロードします。

ダウンロードしたファイルを解凍し、C:\Program Filesに移動します。

環境変数Pathに C:\Program Files\apache-maven-3.9.9\bin 追加します。

コマンドプロンプトを起動し、以下のコマンドを実行する。

> mvn -v

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Program Files\apache-maven-3.9.9
Java version: 21.0.5, vendor: Amazon.com Inc., runtime: C:\Program Files\Amazon Corretto\jdk21.0.5_11
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

上記の結果が表示されればセットアップ完了です。

AWS CLIのセットアップ

こちらのページを参考にインストールを行います。

コマンドプロンプトを起動し、以下のコマンドを実行します。

> aws --version

aws-cli/2.22.34 Python/3.12.6 Windows/11 exe/AMD64

上記の結果が表示されればセットアップ完了です。

AWS SAMのCLIのセットアップ

こちらのページを参考にインストールを行います。

コマンドプロンプトを起動し、以下のコマンドを実行します。

> sam --version

SAM CLI, version 1.132.0

上記の結果が表示されればセットアップ完了です。

AWSプロファイル設定

コマンドプロンプトを起動し、以下のコマンドを実行します。

> aws configure

AWS Access Key ID [None]: XXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]:

AWS Access KeyとAWS Secret Access KeyにIAMで作成したユーザのものを設定します。

プロジェクト作成

コマンドプロンプトを起動し、以下のコマンドを実行します。

> mkdir C:\workspace
> cd C:\workspace
> mvn archetype:generate -DgroupId=my.service -DartifactId=my-service -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=com.amazonaws.serverless.archetypes -DarchetypeArtifactId=aws-serverless-springboot3-archetype -DarchetypeVersion=2.1.1

作成したプロジェクト内にあるbuild.gradleファイルを削除します。

デプロイ

コマンドプロンプトを起動し、以下のコマンドを実行します。

> sam build

Building codeuri: C:\workspace\my-service runtime: java21 architecture: x86_64 functions: MyServiceFunction
 Running JavaMavenWorkflow:CopySource
 Running JavaMavenWorkflow:MavenBuild
 Running JavaMavenWorkflow:MavenCopyDependency
 Running JavaMavenWorkflow:MavenCopyArtifacts

Build Succeeded

Built Artifacts  : .aws-sam\build
Built Template   : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided

上記の結果が出力されれば、ビルド完了です。

次に以下のコマンドを実行し、デプロイします。

> sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]:
        AWS Region [ap-northeast-1]:
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: N
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: Y
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: N
        MyServiceFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

以下の結果が出力されたらデプロイ完了です。

CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------
Key                 MyServiceApi
Description         URL for application
Value               https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping
---------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

動作確認

コマンドプロンプトを起動し、以下のコマンドを実行します。

> curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping
{"pong":"Hello, World!"}

レスポンスが返ってくることを確認してください。

アプリケーション更新

src\main\java\my\service\controller\PingController.javaを以下のように変更します。

package my.service.controller;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.HashMap;
import java.util.Map;

@RestController
@EnableWebMvc
public class PingController {
    @RequestMapping(path = "/ping", method = RequestMethod.GET)
    public Map<String, String> ping() {
        Map<String, String> pong = new HashMap<>();
        pong.put("pong", "Hello, Serverless!");// メッセージ変更
        return pong;
    }
}

保存したら、以下のコマンドを実行してください。

> sam build
> sam deploy

※sam deplyのオプション「guided」が不要なのは、1回目に実行した際に作成されたsamconfig.tomlに選択した内容が保存されており、2回目以降はこちらのファイルが参照されるためです。

デプロイが完了したら、以下のコマンドを実行し変更されたか確認してください。

> curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping

メッセージが変更されていれば更新成功です。

今回はソースの変更を行いましたが、template.yamlファイルでAWS環境の構築や変更を行うことも可能です。(RDS作成など)

最後に

今回作成したプロジェクトを土台として、開発を進めることが可能になりました。実際のアプリケーションではDBを利用することになると思います。今後、別のブログでアップしていきたいと思います。

参考記事

年末年始の休業のお知らせ

平素より、弊社には格別のご厚情を賜り厚くお礼申し上げます。
誠に勝手ながら、下記のとおり年末年始休業とさせていただきます。

■休業期間:2024年12月28日(土)~2025年1月5日(日)

休業期間中のご連絡については、6日(月)以降、順次ご対応させて頂きます。

ご迷惑おかけしますが、宜しくお願い申し上げます。

夏季休業のお知らせ

弊社は、夏季休業を勝手ながら、以下の通りとさせて頂きます。

休業期間中でのお問い合わせ等は、終了後、順次させて頂きますので、

ご迷惑をお掛けしますが、宜しくお願い申し上げます。

ー 記 ー

自:2024年8月13日(火)

至:2024年8月16日(金)

 

また、その他、土日祝際日はお休みとなります。

宜しくお願い申し上げます。