平素より、弊社には格別のご厚情を賜り厚くお礼申し上げます。
誠に勝手ながら、下記のとおり年末年始休業とさせていただきます。
■休業期間:2025年12月27日(土)~2026年1月4日(日)
休業期間中のご連絡については、5日(月)以降、順次ご対応させて頂きます。
ご迷惑おかけしますが、宜しくお願い申し上げます。
平素より、弊社には格別のご厚情を賜り厚くお礼申し上げます。
誠に勝手ながら、下記のとおり年末年始休業とさせていただきます。
■休業期間:2025年12月27日(土)~2026年1月4日(日)
休業期間中のご連絡については、5日(月)以降、順次ご対応させて頂きます。
ご迷惑おかけしますが、宜しくお願い申し上げます。
誠に勝手ながら、弊社では下記の期間につきまして夏季休業とさせて頂きます。
期間中はご不便ご迷惑をおかけ致しますが、何卒ご了承くださいますよう
お願い申し上げます。
・夏季休業期間:2025年8月13日(火)~8月15日(金)
尚、12日(火)は弊社休暇促進日となり、職員の出社は限られますので、
対応等は翌週18日(月)以降とさせて頂きます。
以上、宜しくお願い申し上げます。

どうも、小野です。今回はWebアプリにおけるE2Eテストツール「Playwright」を紹介します。E2Eテストと言えば、ブラウザの操作をテストコードとして実装していくイメージだと思いますが、こちらのツールを利用すると、ブラウザ操作を記録でき、それをコード化してくれます。もちろんある程度の修正は必要になりますが、1からコードを書く必要がないためとても効率的です。
以下のアプリケーションをインストールしてください。
次に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連携も可能です。
テスト自動化を導入して、低コストで高品質なモノを作りましょう。

どうも、小野です。私はずっとWebアプリ開発を行ってきたので、スマホアプリ開発は未経験です。興味本位で軽く触ったことはありますが、初心者同然です。最近、Android開発のデベロッパーに登録したこともあり、勉強し始めたところです。(iOSは1年単位の更新があるので登録していません) まず、スマホアプリ開発の方法として、以下の2つがあると思います。
Android、iOSそれぞれのネイティブ言語で開発する
クロスプラットフォームフレームワークを利用して開発する。
今回はネイティブ言語をそれぞれ学習するのは大変なので、後者について検討してみます。現在、クロスプラットフォームなフレームワークには主にReact NativeとFlutterが主流となっています。 React NativeとFlutterの比較は他の記事にもたくさんあるのでそちらを参考にしていただき、ここでは私がReact Nativeを選択した理由をお話したいと思います。(正確にはReact Native+Expoです。) 選択した理由としては3つあります。
TypeScriptで開発が可能
ストアを介さずにアップデートが可能
開発OSに制限がない
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にはこのような機能はありません。
通常、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を採用しました。 もし、アプリ開発の方法で悩んでたら判断材料として参考にしていただけると幸いです。
久しぶりの技術記事です。今回はタイトルにもあるとおりJavaのディファクトスタンダードでもあるフレームワークSpringBootのアプリケーションをAPI Gateway+Lambdaに構築する方法をご紹介します。
昔はLambdaのランタイムとしてJavaを利用することは、JVM起動時間が遅いため避けられてきましたが、「Lambda SnapStart」機能の追加により起動速度が向上し、実用的に利用できるようになりました。このアップデートによりアーキテクチャの選択肢としてJavaも実用的なものとなっています。
※今回はSnapStartの設定は行いません。
こちらのページよりインストーラーをダウンロードします。

ダウンロードが完了したらインストーラーを実行し、インストールを行います。
インストールが完了したら、コマンドプロンプトを起動し、以下のコマンドを実行します。
> 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ランタイムが使用しており、ローカルとの環境の差分をなくすためです。
こちらのページよりバイナリをダウンロードします。

ダウンロードしたファイルを解凍し、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 --version aws-cli/2.22.34 Python/3.12.6 Windows/11 exe/AMD64
上記の結果が表示されればセットアップ完了です。
こちらのページを参考にインストールを行います。
コマンドプロンプトを起動し、以下のコマンドを実行します。
> sam --version SAM CLI, version 1.132.0
上記の結果が表示されればセットアップ完了です。
コマンドプロンプトを起動し、以下のコマンドを実行します。
> 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日(金)
また、その他、土日祝際日はお休みとなります。
宜しくお願い申し上げます。