とんかつ時々あんどーなつ

〜たとえ低空でも飛行していられるように〜

Bonfire Frontend #5 に行ってきた

yj-meetup.connpass.com

今日のテーマは「テストと自動化」

f:id:kasaharu:20200205234243j:plain

タイムテーブルはこんな感じだった

  • 中期プロジェクトでe2eテストを導入してみて感じたこと
  • Vueのテスト手法とVRTのすすめ
  • Yahoo! JAPAN トップページ リニューアルとテストについて

中期プロジェクトでe2eテストを導入してみて感じたこと

メモ

  • E2E を始めるのは開発が落ち着いてから
  • 狙い
    • 工数削減 → クリティカルで人力では大変なケースを自動化したい
    • 品質向上 → 本当に人力が必要な探索的テストなどをするために単純な作業は自動化しておく
  • 導入までは簡単 → 何年くらいメンテしているんだろう?
  • E2E テストのためのセレクタの選定が難しそう → data 属性とかで工夫する
  • Visual Regression Test も導入したい
  • Google Testing Blog というものがあるらしい

Vueのテスト手法とVRTのすすめ

メモ

  • 軽めの案件にはテストはいらない → LP 作成に E2E テストいらないのは、そう
  • どういうテストが何に適しているか
  • Vue ではブラックボックステストが推奨されている
    • Component が一つの責務で作るのが推奨されているから
  • E2E テスト → 開発終盤に QA が人力でやったりする
  • Visual Regression Test → 画像の比較、そこそこ重い
  • reg-suit

Yahoo! JAPAN トップページ リニューアルとテストについて

メモ

  • テストピラミッドは守る → 最下層のユニットテストを手厚くする
  • reg-suit 人気
  • deploy 時に E2E テストが実行される
  • テストも自動化も継続が大事

懇親会

f:id:kasaharu:20200205234634j:plain いつものありました

感想

ユニットテスト手厚くは個人的に結構意識できていると思うからやっぱ E2E の導入フェーズだなーと改めて思えてよかった。

ただ、E2E テストの環境もない状態からいきなりクロスブラウザのことまで考えると失敗しそうだからまず Chrome に絞って導入してみるのがよさそう。 「とりあえず Chrome でやってみる」はそんなに時間かからない印象だから必要なのは始める気持ちな気がする。ちゃんと素振りしよう。

フォーム周りの人力でやっても結構めんどくさそうな操作から自動化がするのがコスパ良さそう。 Visual Regression Test も気にはなるが、今は QA 観点で効率化したいと思ってるから E2E テストからかなーと思えた。

本編と関係ないけど勉強会ちゃんと机あるのいいなー。

属性バインディングとプロパティバインディングの違い

Angular のデータバインディングの種類に「属性バインディング」と「プロパティバインディング」があるが明確に違いがわかっていなかったのでメモ

属性バインディングとプロパティバインディングの違い

  • そもそも HTML 属性か DOM プロパティかの違いがある

  • HTML 属性の場合 button に disabled があるだけでその button は無効になる

<button disabled>Button</button>
  • disabled 属性をロジックによって着脱したい場合は以下のように書く
<button [attr.disabled]="condition ? 'disabled' : null">Button</button>
  • disabled プロパティを使う場合は以下のように書く
<button [disabled]="condition ? true : false">Button</button>

違い

  • attr. を付けると属性バインディングになる
  • プロパティバインディングは値に boolean を渡せばよいが、属性バインディングには null か no-null が必要
  • 対象の HTML 要素に同じ名前のプロパティと属性がある場合は「プロパティバインディング」を使ったほうが、条件式は簡潔になる(boolean を返す条件式にすればよいので)
  • しかし、場合によっては HTML 要素の属性にしかないものもあるのでその場合は「属性バインディング」を使うことになりそう

参考

Angular の「構造ディレクティブを書く」を読む

構造ディレクティブとは

angular.jp

ドキュメントを見ると以下のように定義されている。

構造ディレクティブは HTML のレイアウトを担当します。 それらは、通常は要素を追加、削除、または操作することによって、 DOM の 構造 を構築または再構成します。

「構造ディレクティブを書く」を読みながら理解する

構造ディレクティブを書く では NgIf の逆をおこなう UnlessDirective の作成をする。

<p *appUnless="condition">Show this sentence unless the condition is true.</p>

上記では conditionfalse のときに p 要素の中のメッセージが表示される。

アスタリスク接頭辞 を読むと *ng-template を使用した記述のシンタックスシュガーであることがわかる。 つまり上記のコードは以下と同等になる。

<ng-template [appUnless]="condition">
  <p>Show this sentence unless the condition is true.</p>
</ng-template>

<ng-template> にもある通り <ng-template> は HTML をレンダリングするための要素であるが構造ディレクティブなしでは実施に表示はされない。

そのため構造ディレクティブがどのように <ng-template> を表示しているか見ていく。

TemplateRef と ViewContainerRef

構造ディレクティブを自作するためには TempalteRef と ViewContainerRef が必須になる。

TemplateRef は <ng-template> の内容を取得することができる。

取得した内容は ViewContainerRef を通して埋め込むことができる。(埋め込んだ view を clear することも可能)

読了 : エラスティックリーダーシップ

読んだ本

https://www.amazon.co.jp/dp/4873118026

感想

チームには 3 つのフェーズがあると書いてありそれぞれ「サバイバルフェーズ」「学習フェーズ」「自己組織化フェーズ」と呼んでいた。 そもそもチームのフェーズについて考えたことがなかったので目からウロコであった。

フェーズによってチームの状況が異なるので、当然リーダーに求められる役割も変わる。つまりリーダに求めること、リーダーが求められることを考える前にチームのフェーズを正しく認識するべき、と改めて思った。

メモ

各フェーズに求められるリーダーのタイプ

  • サバイバルフェーズ / 指揮統制型
  • 学習フェーズ / コーチ型
  • 自己組織化フェーズ / ファシリテーター

既存の Angular アプリに Scully を入れてみた

既存の Angular アプリに Scully を入れてみたのでそのメモ

github.com

Scully とは

  • Angular 用の静的サイトジェネレーター(SSG)
  • 各ページを pre rendering する
  • Node.js v10.x 以上、Angular v9.x 以上が必要(今だと v9 RC を使う必要がある)

導入

インストール

$ yarn ng add @scullyio/init
yarn run v1.21.1
$ ng add @scullyio/init
Installing packages for tooling via yarn.
Installed packages for tooling via yarn.
    ✅️ Added dependency
    ✅️ Import HttpClientModule into root module
UPDATE package.json (1992 bytes)
UPDATE src/app/app.module.ts (827 bytes)
UPDATE src/polyfills.ts (3039 bytes)
UPDATE src/app/app.component.ts (301 bytes)
✔ Packages installed successfully.
    ✅️ Update package.json
CREATE scully.config.js (65 bytes)
UPDATE package.json (2052 bytes)
✨  Done in 174.11s.
  • インストールすると ↑ こんなログが出る

ビルド

  • Scully のビルドには Angular アプリがビルドされている必要がある
$ yarn ng build
$ yarn scully
  • ビルドすると dist/static/ 配下に成果物ができる
    • Scully 用の routes の scully-routes.json も一緒に生成される
  • production 用にする場合は $ yarn ng build --prod でビルドする
  • ローカルで動かすときは $ yarn scully:serve を使うと 1864 ポートで起動する

デプロイ

  • もともと Angularfire で Firebase hosting にデプロイしていたので firebase.json の public を dist/static に変更

結果

  • HTML がレンダリングされた状態でレスポンスが返ってくるようになった
Scully 導入前 Scully 導入後
Scully 導入前
Scully 導入後
  • ほとんどロジックがないアプリケーションだったこともあると思うが、想定していたよりも resources のサイズや load time の変化はなさそう
  • SSG 化するまでのステップは簡単だった

CircleCI から GitHub Actions への移行

Angular で作っているアプリの CI を CircleCI から GitHub Actions に移行したのでそのメモ。

CircleCI でやっていたこと

  • npm パッケージのインストール
    • インストール後の node_moduels をキャッシュ
  • build
  • unit test
    • テスト結果は Artifacts に保存

GitHub Actions の導入

事前準備

  • リポジトリの Actions タブから新規でセットアップする
    Get started with GitHub Actions
    Get started with GitHub Actions
  • 選択するのは Node.js
    • Set up this workflow を押す

Node.js
Node.js

  • .github/workflows/nodejs.yml の Edit ページが出るのでファイル名だけ .github/workflows/ci.yml に変えてコミットする
name: Node CI
on: [push]
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [8.x, 10.x, 12.x]
    steps:
      - uses: actions/checkout@v1
      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node-version }}
      - name: npm install, build, and test
        run: |
          npm ci
          npm run build --if-present
          npm test
        env:
          CI: true

今回やった設定

  • node-version は 12.x 系だけでいいので node-version: [12.x] に変更
  • パッケージマネージャーを npm から Yarn に変更
         uses: actions/setup-node@v1
         with:
           node-version: ${{ matrix.node-version }}
-      - name: npm install, build, and test
+      - name: yarn install, build, and test
         run: |
-          npm ci
-          npm run build --if-present
-          npm test
+          yarn
+          yarn build
+          yarn test
         env:
           CI: true
  • node_modules/ を cache に保存
         uses: actions/setup-node@v1
         with:
           node-version: ${{ matrix.node-version }}
+      - name: Cache node modules
+        uses: actions/cache@v1
+        with:
+          path: node_modules
+          key: ${{ runner.OS }}-yarn-${{ hashFiles('**/yarn.lock') }}
+          restore-keys: |
+            ${{ runner.OS }}-yarn-
       - name: yarn install, build, and test
         run: |
           yarn
           yarn test:ci
         env:
           CI: true
+      - name: Archive code coverage results
+        uses: actions/upload-artifact@v1
+        with:
+          name: code-coverage-report
+          path: coverage/Portfolio

感想

  • 設定は簡単でわかりやすい
  • おおよそのことは CircleCI と同じことができる
  • Artifact の upload は見れるが CircleCI みたいにブラウザで見れないのが難点…

2019 年振り返り & 2020 年の抱負

平成 → 令和
平成 → 令和

目標の振り返り

  • 2019 年の抱負は これ
  • Angular を使ったアプリケーションを個人で作る
  • 月 1 くらいで Qiita か Medium に記事を書く
    • Qiita は Advent Calendar の追い込み入れても 4 件、Medium は 7 件書いたところで Medium 使うのをやめてしまった
    • Medium やめてからははてなブログに戻って 4 件書いたので全部で 15 記事書いたことになる
  • 筋トレする
    • してない
  • 定期的に振り返る
    • 定期的に振り返っていないので筋トレをしていない…

あったこと色々

  • 会社主催の Classi Angular Night を 4 回やることで 4 回の発表機会があった
    • 発表資料 もそれなりに見てもらっていてよかった
  • 初めてライブビューイングを見たけど直接現地に行かなくてもイベントを楽しめるので、なるほどこれは画期的だなと思った
  • EM 系のポッドキャストを聞いたり勉強会に行ったりと少し興味を持った
  • lacolaco さんがアドバイザーになってつよつよエンジニアと働く機会を得た
  • Angular 日本ユーザー会のスタッフ を始めた
    • ng-japan みたいな大きなイベントがどうやって開催されていくのかを知れたり純粋に人のつながりができたりしてとてもよかった
  • ng-japan と builderscon の CFP を出してみた
    • どっちも採択はされなかったけど、実際に CFP を考えてみたりネタを考えてみたりしたので経験にはなった
  • ちょっとだが OSS にコントリビュートした
    • いつも自分が使っている OSS に少しでも貢献できるのがとても嬉しいことだと知ったしもっと続けていきたい
  • スタバのロースタリーにハマった
  • ユーザー会のつながりでハンズオンのチューターをやった

改めて振り返ってもめちゃくちゃ色々あった一年だった。

2020 年の抱負

  • 来年も引き続き社外で発表をする
    • 今年が 4 回だったので 5 回以上を目指す
    • CFP も出す
  • 英語の勉強をする
    • どこかで TOEIC を受ける
  • うっかり体重が増えてしまったのでまたランニングをする
  • 日々インプット / アウトプットを意識する
    • 月に 1 冊は技術書を読む
    • 月に 1 回はブログを書く(年 12 回じゃなくて月 1 回を目指す)