はじめに
みなさん、Cypress使ってますか?
CypressはJavascriptベースで動作するE2Eテストを作るフレームワークです。
cypress.io
CypressはTypescriptでUTテストと同じノリで簡単に書けるのでとても気に入ってます。
CypressはE2Eテストフレームワークですが、
自分の所属するチームではE2Eテストの実行以外に本番環境向けのWebアプリケーションのヘルスチェックにも活用しています。
ヘルスチェックの内容としては以下で、
-
遷移した画面で各情報が適切に表示されているか?
- websocketは繋がっている?
- 映像は配信されている?
- 地図は描画されている?
- 地図上にマーカーやラインなどが描画されている?
- etc...
-
初期表示や画面遷移での表示までのスループットが過度に遅くなっていないか?
などです。
その中で、今回はCypress上でのスループットの計測について一工夫必要だったので紹介します。
最初の実装(スループット計測)
it("スループット計測", () => {
// NOTE: step1 ブラウザ起動〜画面1表示
cy.log("ブラウザ起動〜画面1表示 計測開始");
let start = new Date();
cy.visit('/helloworld');
// 画面1
// 画面1の要素が表示されていること
cy.get(ATTRIBUTE.DISPLAY1)
.should("be.visible")
.then(() => {
// 計測終了
cy.log("ブラウザ起動〜画面1表示 計測終了");
const end = new Date();
const msTime = end.getTime() - start.getTime();
const s = msTime / 1000;
cy.log("ブラウザ起動〜画面1表示 経過時間");
cy.log(`スループットは ${s.toString()}秒でした`);
});
// NOTE: 画面遷移
cy.get("#go-next-page").click();
// NOTE: step2 画面1〜画面2
cy.log("画面1〜画面2表示 計測開始");
start = new Date();
// 画面2の要素が表示されていること
cy.get(ATTRIBUTE.DISPLAY2)
.should("be.visible")
.then(() => {
// 計測終了
cy.log("画面1〜画面2表示 計測終了");
const end = new Date();
const msTime = end.getTime() - start.getTime();
const s = msTime / 1000;
cy.log("画面1〜画面2表示 経過時間");
cy.log(`スループットは ${s.toString()}秒でした`);
});
});
概要としては、
- 最初のページが表示されるまでの時間を計測
- 最初のページが表示された状態から、遷移先のページに移って表示されるまでの時間を計測
というE2Eテストの内容です。
一見良さそうに見えますが、このコードは問題があります。
「最初のページが表示された状態から、遷移先のページに移って表示されるまでの時間を計測」
この確認の最初の計測開始時にstart
にnew Date()
を代入し直して開始時間を取り直しています。
しかしここで取得した時間は画面1が表示されているタイミングでの取得時間ではなく、
最初の
let start = new Date();
とほぼ同じタイミングでの取得時間が入ります。
よって、画面1〜画面2表示 計測終了
時に計測した時間は、
ブラウザ起動〜画面2表示 となってしまっているのです。
修正した実装
実は、cy.log
の後にも.then
でチェーンさせて任意の処理を実行することができます。
これを使って、
cy.log("画面1〜画面2表示 計測開始");
が実行された際に開始時間を取り直すようにしていきます。
it("正常性確認とスループット計測", () => {
+ let start:Date;
// NOTE: step1 ブラウザ起動〜画面1表示
cy.log("ブラウザ起動〜画面1表示 計測開始")
+ .then(()=>{
+ start = new Date();
+ });
- let start = new Date();
cy.visit('/helloworld');
// 画面1
// 画面1の要素が表示されていること
cy.get(ATTRIBUTE.DISPLAY1)
.should("be.visible")
.then(() => {
// 計測終了
cy.log("ブラウザ起動〜画面1表示 計測終了");
const end = new Date();
const msTime = end.getTime() - start.getTime();
const s = msTime / 1000;
cy.log("ブラウザ起動〜画面1表示 経過時間");
cy.log(`スループットは ${s.toString()}秒でした`);
});
// NOTE: step2 画面遷移
cy.get("#go-next-page").click();
// NOTE: step2 画面1〜画面2
cy.log("画面1〜画面2表示 計測開始")
+ .then(()=>{
+ start = new Date();
+ });
- start = new Date();
// 画面2の要素が表示されていること
cy.get(ATTRIBUTE.DISPLAY2)
.should("be.visible")
.then(() => {
// 計測終了
cy.log("画面1〜画面2表示 計測終了");
const end = new Date();
const msTime = end.getTime() - start.getTime();
const s = msTime / 1000;
cy.log("画面1〜画面2表示 経過時間");
cy.log(`スループットは ${s.toString()}秒でした`);
});
});
まとめ
以上のように修正を加えることで想定通りの取りたいスループットを計測することができました