フロントエンドエンジニアをやっています。
頑張るから読んでほしい。

2019-09 → 2020-03

仕事について

去年の9月にSmartHRのフロントエンドエンジニアとして転職をしました。 3月で入社して6ヶ月になるので、少し振り返ってみようかなあっと思って書いています。

入社してからの3ヶ月

はじめてのお仕事は、比較的小さいアプリのフロントエンドリニューアルのお仕事。

既存のrailsアプリにReact, TypeScriptを入れて、作り直しました。

私にとっては、はじめてのReact, TypeScriptでとても刺激のある3ヶ月でした。

やったことは、

既存railsアプリにWebpackを入れてフロントエンドを切り分けた

既存のRailsアプリにReact, TypeScirptを入れてフロントエンドリニューアルをする際に、最初に悩んだのが、 Reactを入れる、動く環境を作るためにはどうしよう?

でした。  

  1. webpackerをいれる
  2. 自分でwebpackを用意する
  3. 上記以外の何か別の何かの方法...?

上記3つの方法を検討していたのですが、

  • フロント部分の細かな設定がしたい
  • webpackerだと
    • 細かい設定が大変
    • webpackerの学習コストやwebpackのバージョンアップについていけないことが辛い
  • 他のプロダクトと設定を統一したい

という理由から、自分でwebpackを用意し、フロントエンドを切り分けることにしました。

React, TypeScriptで作り直す

はじめてのReact, TypeScriptだったので、慣れるまではとても時間がかかりました。。。(しんどかった…)

苦労したところは、はじめてやることなので時間がかかるでした。

なので、

↑の本を読んだり、先輩に教えて貰ったり、ちょっと早めに出社して勉強したりしながらやっていました。

UIのコンポーネント

もともとスタイルははscssで書かれていたのですが、フロントエンドリニューアルにあたって、Styled Componentsを使用することにしました。

Reactはコンポーネント・ベースでUI開発することに特化したJavaScriptライブラリなので、個人的にはコンポーネント単位でcssを管理したく、コンポーネント単位でスコープが生成されるStyled Componentsで書き直すことにしました。

他のプロダクトもStyled Componentsなので、統一したかったっていうのも理由のひとつです。

UIのコンポーネント設計部分はAtomic Designを採用しました。 フロントエンドリニューアルするプロダクトは開発人数が少ないため、UI設計の共通認識が持ちやすそう、またメンテナンスしやすいUI開発がしたいと思い採用しました。

こちらもはじめてのStyled Components、Atomic Designだったので、

↑のdocsを読んだり、Atomic Designの本を読んだりしてました。

Ruby on Rails

フロントエンドのリニューアルなので、あんまりバックエンド部分は触ることはなかったのですが、 どうしても修正しないといけない箇所があったりで、コードを読んだり、修正したりしてました。

railsはあんまり得意ではなく… 事前にその話をしていたので、先輩がすぐに助けてくれたり、丁寧に教えてくれたりしたおかげで少しだけrailsのこと理解できた気がします。(たぶん)

入社してからの4ヶ月目~今

今年に入ってから、新しいチームに配属になりました。

以前やっていたプロダクトよりも大きいプロダクトで技術スタックはRails, React, TypeScript、 そして半年ほど専任のフロントエンドエンジニアがいなかったチームです。

フロントエンドエンジニアの人数が少ないので、チームのフロントエンドエンジニアは私一人だけです。

私一人で大丈夫かな、私で大丈夫なのかなって不安がたくさんあったのですが、 チームのみんなは、困ってるとすぐに助けてくれたり、いっしょに悩んでくれたり、とても心強く、楽しく開発できています。

今のチームに入ってからやったこと&やっていることは、

tslintをやめた

TSLintは現在非推奨になっています。

なので、TSLintはやめて、eslintに変更しました。

既存のUIをSmartHR UIに変更

SmartHRには共通のコンポーネントライブラリSmartHR UIがあります。 また、SmartHRにはたくさんのプロダクトがあり、プロダクトによっては少しUIが違っていたり、カラーが違っていたりしています。 プロダクト間でのUIの統一をし、多くの人に使いやすいと思ってもらいたいので、既存のUIをSmartHR UIに変更しています。

(まだ途中で、置き換え作業中です。)

フロントエンドの問題点の洗い出し

しばらく専任のフロントエンドがいないプロダクトだったので、 フロントエンド部分のコードを良くしていきたい、底上げをしたいと思っています。

フロントエンドのコードに関して

  • どんな問題点、課題があるのか、
  • 将来的にどうしたいのか

を洗い出しました。

↑を踏まえてフロントエンドの技術顧問の方に相談したり、先輩に相談したり、 チームのみんなにも共有して協力してもらったりしています。

jsのts化

もともとjsで書かれていたのですが、以前チームにいたフロントエンドの先輩が半分以上TypeScriptにしてくれていました。

ですが、まだjs部分が残っています。。。

堅牢性をあげたいので、早くts化を終わらせたいなあと思っているので、ちょっとずつTypeScriptにしようと頑張っています。

ビルド周りの改善

以下は、私がやったことではなく技術顧問の方がやってくださりました。

以前はTypeScriptのコンパイル部分をawesome-typescript-loaderを使用していたのですが、ts-loaderに変更しました。 変更することで、コンパイルの速度が速くなりました。

また、ESModulesのままwebpackに渡すようにしてTreeShakingを有効にしました。

これで本番ビルドのファイルサイズが削減されました。

// tsconfig.json
{ 
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "sourceMap": true,
    ...
    ...
    ...

TypeScriptコードのimport文とexport文がコンパイラによってCommonJSとして変換されるため、Tree Shakingの効果を得るためには明示的にES Modulesをコンパイルオプションで指定するみたいです。

上記2つは、技術顧問の方にPRを出していただいたのですが、私自身ビルド周りが詳しくなく…勉強になりました!

振り返り

半年を振り返ると、はじめてなことばかりで大変だったけど、出来ることが増えて嬉しい気持ちとやりがいがあります。

今やってるプロダクトのフロントエンドが良くなっていくのを感じる度に、私のフロントエンド力も一緒に成長している気持ちになっています。

入社して半年がたち、このままこのプロダクトと一緒に成長していけたらなあ、前職、現職含めお世話になった人にお仕事で恩返しができたらなあ、と日々思いながらお仕事をしています。

2019年振り返り

2019年を

  • WORK
  • STYDY
  • PRODUCT
  • BLOG
  • BOOK
  • MUSIC

で振り返ります。

WORK

お仕事は上手くまとめられなかったので月ごとに簡単にまとめます。

1月

悩み事が多かった気がする。

2月

辛いことがありました。
辛いこともあったけど、嬉しい言葉をかけて貰えたのも2月でした。

3月

UI/UXチームは2人で開発してたけど、webチームとwebメッセージ開発を始める。
先輩と朝勉強をはじめた。
先輩との勉強で一番印象に残ってるのは、
”webはHippy”

4月

きちんとテストすることの大切さを学んだ4月。
web-sdkのリリースを先輩といっしょにやった。
朝活も続いてる。

5月

チーム解体。スクラムの導入。Lessの勉強。
環境の変化に対応するのに大変だったけど、チームのメンバーは最高だった。

6月

sprint planningでのTaskの分割が上手くできない。分からない。
サーバーサイドもインフラもフロントエンドも何も分からない…

7月

頑張れなかった。
会社を辞めた。
何もかも自信がなくなった。
憧れてるエンジニアの人と面談をした。誕生日の日だった。
ブログを読んでくれたり、頑張ってるのを見てくれてた人がいるんだと嬉しい気持ちになった。
もう少しだけ頑張ろうと思った。

8月

ゆっくりすることにした。
音楽を聴いたり、花を飾ったり、本を読んだり、ご飯をちゃんと作るようにした。
夕方よく散歩をした。時々見かける子供とお母さんの会話をぼんやり聞いたりした。

9月

転職した。
はじめて設計含めてフロントエンド開発することになった。
ReactもTypeScriptもはじめてやる。
既存railsアプリにreactを導入した。
webpackerいれるか考えたりした。(いれなかった)

10月

サーバー側のデータをフロントでどうやって取得しようか悩んだりした。
form送信できない…CSRFトークンとは?ってなった。
Smart HR UIにselect boxコンポーネントのPRを出した。嬉しい。

11月

入社後、なんとなくReactとTypeScriptを先輩のコードを参考に書いてたけど、
これじゃだめだ!と思って、朝活を始める。
TypeScriptの勉強を毎日することにした。
少しずつ会社の人に慣れてきた。

12月

先輩が設計に関してPRを出してくれた。とても勉強になった。
リリースまで12月までにできなかったけど作りきった。
自信になった。
少しずつ会社の人に心を開いてきた。

STUDY

今年は、ブラウザについて勉強しました。
もともと仕組みが分からないともやもやして先に進めない性格なので、
ブラウザについて勉強したのは、とても良い経験になったように思います。

ブラウザの仕組みで一番好きなのはParse(構文解析)の部分ですって話を先輩にすると the-super-tiny-compilerを教えてくれたので、コードリーディングしたり写経したりしました。

あとは、テスト技法を少しだけ学んでみたり、React、TypeScriptに挑戦してみたり、Atomic Designについても勉強してみたり。です。

来年は、興味のある分野についてもっと勉強していき、自分の強みを見つけることができたら、なんて思ってます。

PRODUCT

the-super-tiny-compiler.jsを写経したものをブラウザ上で使えるように作ってみたり、
ReactとTypeScriptに慣れたいので、練習のためにReactとTypeScriptでTEA PAGEを作ったり、ポートフォリオを作り直したりしました。

Reduxを使ったアプリを作りたいなあと思ってるのですが、サーバー構築に対して苦手意識があるので、来年はその辺りも含めて何か作ってみたいです。

BLOG

12本書きました。(その内1本は音楽について)

以下の3つは書いてて楽しかったブログ。

今年は、Web、ブラウザについての記事を多く書きました。 去年は15本書いているのですが、内容的には濃い内容を今年は書いている気がするので、来年もこの調子でアウトプットしていきたいです。

BOOK

技術書

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus)

Webフロントエンド ハイパフォーマンス チューニング

Webフロントエンド ハイパフォーマンス チューニング

Atomic Design ~堅牢で使いやすいUIを効率良く設計する

Atomic Design ~堅牢で使いやすいUIを効率良く設計する

実践TypeScript ~	BFFとNext.js&Nuxt.jsの型定義~

実践TypeScript ~ BFFとNext.js&Nuxt.jsの型定義~

booth.pm

小説

トニオ・クレエゲル (岩波文庫)

トニオ・クレエゲル (岩波文庫)

メルヒェン (新潮文庫)

メルヒェン (新潮文庫)

  • 作者:ヘッセ
  • 出版社/メーカー: 新潮社
  • 発売日: 1973/07/03
  • メディア: 文庫

星の王子さま (新潮文庫)

星の王子さま (新潮文庫)

第七官界彷徨 (河出文庫)

第七官界彷徨 (河出文庫)

道をひらく

道をひらく

買ったけど読んでない&読みたい

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)

「実践ドメイン駆動設計」から学ぶDDDの実装入門 (CodeZine Digital First)

  • 作者:青木 淳夫
  • 出版社/メーカー: 翔泳社
  • 発売日: 2019/05/31
  • メディア: オンデマンド (ペーパーバック)

夜と霧 新版

夜と霧 新版

ささやかだけれど、役にたつこと

ささやかだけれど、役にたつこと

かげろうの日記遺文 (講談社文芸文庫)

かげろうの日記遺文 (講談社文芸文庫)

今年はけっこう本を読んだ気がします。
就活してたときに、説明会でもらった道をひらくって本、改めて読むととても滲みました。

ヘッセのアヤメという短編が今年の一番です。

MUSIC

open.spotify.com

open.spotify.com

open.spotify.com

open.spotify.com

www.youtube.com

www.youtube.com

今年はThe World Will Tear Us Apartという京都のバンドのアルバムが冬にリリースされました。
大学生の頃からずっと待っていたのでなんだか感慨深いです。

個人的にDIIVの新しいアルバムが衝撃でした。(良い意味で)

TO 2020

今年は本当に辛かったです。
辛かった分、得たことも多かった一年のように思います。

辛かったこと、得たこともしっかり受け止めて来年もまた少しずつ頑張れたらいいなあ、と思っています。

来年は自分の得意領域を見つけ、深堀りして行ったり、成長を実感できるような年にしていきたいです。

では、2020年も宜しくお願いします。

f:id:cidermitaina:20191229172932p:plain

実践 TypeScriptの読書MEMO1

最近、実践 TypeScriptを読んでいるので読書メモです。

実践TypeScript ~	BFFとNext.js&Nuxt.jsの型定義~

実践TypeScript ~ BFFとNext.js&Nuxt.jsの型定義~

私の知らなかったことをたくさん書いてます。

どんな本

  • TypeScript特有の知識を体系的に学ぶための1冊
    • 集中してTypeScriptの型定義を深く学べる
  • 1部は基礎知識、2部は理解を深める
  • TypeScriptを導入するメリット
    • 分割されたモジュール同士の依存関係を担保する
    • 型システムが、バックエンドからフロントエンドの末端のviewまで一環して不整合ないデータの橋渡しを実現する

目的

  • TypeScriptの型定義きちんと理解したい
    • 型定義ははじめてなので…
  • 最終的にTypeScriptを実践的に使えるようになりたい
  • 先輩のTypeScriptのコードをちゃんと理解できるようになりたい
  • 4章5章をちゃんと読んでTypeScriptのコンパイルエラーの解決慣れしたい

1. 開発環境と設定

1-1. tsconfig.json

TypeScriptコンパイラーの設定ファイル。 tsc --initで作成

tsconfig.json

{
  // teconfig.jsonの初期値
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
}

target

トランスパイル後のECMAScriptのターゲットバージョン。

  • es5
  • es2015
  • esnext

module

コード生成モジュールを指定

  • commonjs
  • amd
    • define()に配列でモジュール名を指定する

strict

型の厳密さを一括して指定

一括で有効になるのは以下の指定

  • noImplicitAny
  • noImplicitThis
  • alwaysStrict
  • strictBindCallApply
  • strictNullChecks
  • strictFunctionTypes
  • strictPropertyInitialization

1-2. 型宣言ファイルの出力

関数定義などの型を通達するために、型宣言ファイル(.d.ts)が利用できる

.d.tsいつ使うんだろう🤔

  • 型情報が消えしまう
  • .d.tsは型定義が分かる
  • JavaScriptで書かれたライブラリには型情報がない…
  • ライブラリ等で使うときは型定義ファイルがあれば、みんなが幸せになれる

1-3. ライブラリの型定義を利用する

npmで配信されているライブラリには、TypeScriptの型定義が存在するものとしないものがある。

DefinitelyTyped

TypeScript型定義ファイル(dts)を用意していないJSライブラリのための型定義ファイル集 @typesで始まるパッケージ

2. TypeScriptの基礎

TypeScriptのもっとも基本的な用語の呼称・利用方法についての章。

2-1. JavaScriptの課題

1. 引数に数値として扱うことのできない値を渡してしまいNaNが表示されてしまう

  • 引数を型注釈で制約する
function expo2(amout: number){
  return amout ** 2
}

2. 計算の途中、数値が文字列に変換されてしまいNaNが返ってくる

  • 関数戻り値に型注釈(アノテーション)を付与。明示的に戻り値を制約。型注釈と定義内容に型不整合がある場合はコンパイルエラーを得ることができる。
function fee(amount): number {
    return amount * 1.4
}

2-2. 基本の型

(私の知らなかった型をまとめてます。)

  • tuple型
    • 固定数の要素がわかっている配列を表現できる
    • 配列の要素ごとに型が違うデータ型が定義できる。
      • let x: [string, number]
  • any型
    • 型の不明な変数を扱うことがある場合に使用することで型チェックを無効にし、コンパイルを通過させる
    • TypeScriptの恩恵を受けることはできないので、できる限りany型が現れないコードを書き、型安全なプロジェクトを目指す。
  • unknown型
    • any型に似ているが、型安全なanyを表したいときに利用する
  • void型
    • any型の反対のようなもの。型が全くないことを表す。
    • 一般に、値を返さない関数の戻り値として利用
  • never型
    • 発生し得ない値の型を表す
    • 返り値が無いことを表すvoid型とは異なり、そもそも関数が正常に終了して値が返ってくるということがあり得ない場合
function func(): never {
   throw new Error('Hi');
 }
 const result: never = func();
  • object型
    • 非プリミティブ型
    • {}を使った型表現ではエラーを得ることができない

2-3. 高度な型

  • Intersection Types
    • 複数の型を一つに結合する
  • Union Types
    • Union Types(共用体)は複数の型のうち一つの型が成立することを示している。
      • let value: boolean | number | string
        • array型を含む要素をUnion Typesにする場合
      • let numberOrString: (number | string)[]
        • Nullable型を表現できる
      • let nullableString: string | null
  • Literal Type
    • String Literal Types
    • 文字列に必要な正確な値を指定できる
    • let users: 'Taro' | 'Jiro'| 'Hanako' (Union Typesと併用)
    • Numeric Literal Types(数値リテラル)
    • Boolean Literal Types(真偽値リテラル)

2-5. アサーション

任意の型に変換することができる。

アサーションは2種類の書き方がある。

  • <変換したい型>値
  • 値 as 変換したい型
let text: any = "this is a string";
let textLength: number = (<string>text).length;
let text: any = "this is a string";
let textLength: number = (text as string).length;

↑ 文字列の文字数を取得するために string に変換して length を呼び出している

<>ではJSXタグとの区別が曖昧になるため、非推奨

2-6. 列挙型

enumを使用すると、列挙型を定義できる。 列挙している属性以外が入ってくると怒ってくれる

3. TypeScriptの型安全

バグを減らすことはTypeScriptを導入する大きな理由の一つであり、

TypeScriptを使いこなすようになるほど、絞り込むという作業がバグを減らす上でいかに重要な作業かということに気づくらしい。

3-1. 制約による型安全

  • アノテーションを用いると、引数や変数定義において、誤った値の代入を防げる。
  • null, undefined
    • 早期return(ガード節、Type Guard)
  • Weak Type
    • すべてのプロパティがオプショナルな型

3-2. 抽象度による型安全

  • 抽象的な型は広く値を受け付けることができる
  • 詳細な型は担保された制約の下で処理を安全に展開できる
  • 抽象的な型・詳細な型がどのようなものであるかを理解し、抽象度をコントロールすることが必要
  • キャスト
    • 変数の型を別の型へ変換すること
  • ダウンキャスト
    • 抽象的な型から詳細な型を付与すること(互換性があるときのみ可能、互換性がない場合は成立しない)
  • アップキャスト
    • 抽象度をあげる
  • インデックスシグネチャ
    • 任意のプロパティを動的に追加することが可能
  • 危険な型の付与
    • Non-null assertion
    • double assertion

4. TypeScriptの型システム

バグを減らすことはTypeScriptを導入する大きな理由の一つ。

TypeScriptを使いこなすようになるほど、絞り込むという作業がバグを減らす上でいかに重要な作業かということに気づくらしい。

4-1. 型の互換性

any型の互換性

  • どんな型にも宣言・代入できる。
  • any型は、どのように扱おうとも危険な型

unknown型の互換性

  • unknown型は、どんな型の値も受け入れることができるTopTypeであり、型の中でもっとも抽象的な型。
    • any型とは異なり安全に扱うことができる型
  • unknown型の値はどんな値なのか分からないため、できることが制限されている。  - (任意の値を代入できる点はany型と同じ、型アサーション等が無いと利用できない。)

{}型の互換性

  • 型に互換性がありため、いずれもコンパイルエラーにはならない。
  • {}という型はオブジェクト以外も受け付けてしまう。(ただし、undefinedとnullはだめ)
  • プリミティブ型は{}型のサブタイプ

5. TypeScriptの高度な型

Generics

  • Genericsを用いると、型の決定を遅延できる。
  • Genericsが割り当てられた型定義に対し、< >の内側に型指定をすることで、導かれる型推論を可変にできる。

基本的な付与

  • Genericsを利用する型を宣言する場合、型名称に続いて<T>のようにT型をエイリアスとして指定する。
  • 慣習的にT, U, Kなどの型エイリアス名称が利用されることが多い。

Genericsを利用する型の宣言

interface Box<T> {
    value: T
}
const box0: Box = { value: 'test' } // Error! Genericsを指定していない
const box1: Box<string> = { value: 'test' }
const box2: Box<number> = { value: 'test' }// Error! Number型ではない





実践TypeScriptの読書MEMO2に続きます。

2019 上半期 聴いたもの

2019年の上半期によく聴いた、印象的だった音楽について。

まず最初に、この半年に聴いた新譜の中でもこれはヤバすぎるな… と思ったのがいくつかあるので以下に。

youtu.be

open.spotify.com

ノルウェー出身19歳の宅録女子らしい。 dead girl in the poolという曲のタイトルで狂気的な印象を受けたけど、

「なんとも言えない不安な気持ちとか、自分は誰であるかというアイデンティティの揺らぎとか、そういった気持ちに根ざした恐怖感を表現したかった」

ということらしい。



open.spotify.com

知り合いに教えてもらった。 甘ったるい感じに歌う声が好きです。



open.spotify.com www.youtube.com

ここ最近で一番衝撃的な新譜でした。

言葉とサウンド(メロディ?音?)が究極に美しいです。 Everythingは特に綺麗。



open.spotify.com

高揚感に溢れます。



open.spotify.com

高熱でぼんやりしてるときって夢でよく京都での大学時代の夢を見るなあと思いながら聴いています。



最近聴いて印象的だったもの。

open.spotify.com

open.spotify.com

open.spotify.com

open.spotify.com

open.spotify.com

open.spotify.com



音楽は相変わらず毎日聴いているし、何か聴いていないときの方が少ないのではないかってくらい聴いています。

自分から何か探すことは減ってきていて、Spotifyが勧めてくれるおすすめの音楽を聴くことが多くなったかもしれないです。 あとは、今まで好きだったバンドの新譜とか、そういうものばかりを聴くことが多かったです。



2019年ではないけど、ここ最近で読んだ本、漫画についても。

草の花 (新潮文庫)

草の花 (新潮文庫)

トニオ・クレエゲル (岩波文庫)

トニオ・クレエゲル (岩波文庫)

メルヒェン (新潮文庫)

メルヒェン (新潮文庫)

星の王子さま (新潮文庫)

星の王子さま (新潮文庫)

風立ちぬ・美しい村 (新潮文庫)

風立ちぬ・美しい村 (新潮文庫)

バースデイ・ストーリーズ (村上春樹翻訳ライブラリー)

バースデイ・ストーリーズ (村上春樹翻訳ライブラリー)

あんまり、楽しい小説は読んでいなくて、言葉の綺麗な小説を探して読んでいました。

ヘッセはなぜか苦手意識があったけど、アヤメは本当に美しくて綺麗な話で... 好きな話のひとつになりました。

あとはスラムダンクを読みました。





ここ最近はこんな感じです。

なんだか疲れているような感じで、いろいろと立ち止まってみるのもいいのかもしれない。と思ったりする日々です。 ゆっくり音楽を聴いたり、ご飯を丁寧に作ってみたり、花を生けたり、好きなお茶を選んで淹れてみたり...

夏休みのつもりでのんびりしています。

夏休みが終わったら、また頑張れるだろうか。



アドレスバーにURLを打ち込んでページが表示されるまで

ブラウザを立ち上げてアドレスバーにURLを打ち込んでEnter押してからページが表示されるまでに (裏側で) 何が起こっているかわかる限り説明してみてください。

という問題に15分何も見ずに考えてみるというのを以前(2月くらい?)やってみたので、そのMEMOです。

予想

何もブラウザに関して勉強せず、15分考えてみた予想(結果)は以下です。 (すごくざっくりしてるので恥ずかしい...)

  • アドレスバーに打ち込んだURLがサーバーに送られる
  • サーバーがURLを受け取る
  • サーバーがデータベース?データサーバー?にURLの情報を探しにいく
  • 見つかったらサーバーがクライアント側にその情報を返す(その情報ってなんだろ?html、css、jsとか?)
  • クライアント側、ブラウザが受け取り、htmlやcssなどをレンダリングする
  • 表示

勉強後

あまりにも書けなかったことがショックだったので、

Webフロントエンド ハイパフォーマンス チューニング

を読んでブラウザのレンダリングの仕組みについて学んでみました。

勉強後、同じように15分何も見ずに考えてみた結果が以下です。

  • アドレスバーにURLを打ち込む
  • ホスト名をIPアドレスに変換した上でネットワークプロトコルを介して必要なリソースを取得
    • リソース→HTML、css、js、画像など
  • まずはHTMLから読み込み、DOMツリーの構築をする
  • DOMツリーの構築 (DOMツリーとはレンダリングエンジンが解釈できるようしたもの)
  • DOMツリーの構築中にcssやjs、画像の参照があれば読み込む
  • cssをもとにCSSOMツリーの構築
  • jsファイルをもとに字句解析
  • トークン化
  • 抽象構文木
  • コンパイル
    • javascriptエンジンが解釈できるように変換
    • よく使われているのがJIT
  • javascriptの実行
    • CPU上で実行
  • DOMツリーをもとにレイアウトツリー構築構築をする
  • スタイルの計算
    • どのDOMにどのcssプロパティが当たるか計算
    • cssの詳細度の計算
  • レイアウト
  • レイアウト情報の計算をしレイアウトの作成(設計図みたいなもの)
    • レイアウト情報→margin,paddingなどの位置
  • ペインティング
    • 2dグラフィックエンジン向けにRender Treeをもとに命令を作成
  • ラスタライズ
    • レイヤーごとに描画
    • レイヤーはposition ,opacity,z-indexごとに
  • レイヤーの合成
    • できたレイヤーを合成
  • ブラウザに表示される

感想

最初は、

ブラウザを立ち上げてアドレスバーにURLを打ち込んでEnter押してからページが表示されるまでに (裏側で) 何が起こっているかわかる限り説明してみてください。

の問いに対してあまり書けなかったのですが、ブラウザのレンダリングの仕組みの勉強後、3倍くらいの量で書くことができました! ブラウザに関する知識が身についた感触があります。

ブラウザに対して興味を持ったので、今後はネットワークやコンパイル、レイアウト、ラスタライズ等の自分の興味を持った分野に対して深掘りしていき、この問いに対しては定期的に考えてみたいなあと思っています。 (来年も同じ問いに対して考えて、書ける量を増やしていけたらなあ...)

毎日の小さなアウトプット

毎日こつこつアウトプットする習慣を作りたいと思っていたのですが、

小さなアウトプットを100日続けてみた感想

という記事を見かけて、私もTIL(Today I Learned) をやってみようと思ったので TILについて&どのようにやっていくかを考えてみました。

WHY

  • 何かを毎日アウトプットする習慣をつけたい。
  • 毎日の気になったこと、覚えたこと、新しく気付いたこと、学んだことをどんな形でもいいからアウトプットしたかった。

TILとは

Today I Learnedの略。 Github上にTILというリポジトリを作成してそこに今日覚えたことを書いていく。 (githubで検索するとtilというリポジトリがけっこう見つかる)

塵も積もれば山となるみたいな感じ。

ref. https://qiita.com/sitmk/items/239335b4ed0c3c797add ref. https://syossan.hateblo.jp/entry/2016/02/16/144305

実際のリポジトリ

https://github.com/jbranchaud/til

カテゴリごとにディレクトリを作成し、勉強した内容などをmdファイルでまとめている。

f:id:cidermitaina:20190711164035p:plain

f:id:cidermitaina:20190711164057p:plain

HOW

https://aloerina01.github.io/blog/2019-03-22-1

↑を参考に

  • 何か読んだり考えたりしたらそのログをIssueに残す
  • ブログに書くほどじゃないネタを雑にIssueにまとめる
  • ちょっとした実装を日付毎のディレクトリにCommitする

という感じでやっていく。

毎日アウトプットする習慣を作ることが目的なのでブログに書いてある通りかなりハードルを低くして、やっていく。

github.com




5月中旬からはじめて、毎日続いているわけではないのですが...

毎日コツコツ小さなアウトプットをしたいと思っているのでこのブログで意思表明です。。。




ソフトウェアテスト技法ドリルを読みました

最近、担当している機能のリリースしたのですが、リリース後のバグが多く…
テスト設計やテストケースの洗い出しがきちんとできていなかったと実感しました。
会社のテストエンジニアに相談したらソフトウェアテスト技法ドリルをおすすめしてくれたので読んでみました。

個人的に重要だと思ったところ&知らなかったことをまとめてます。

どんな本

  • テスト技法の正しい使い方が実践的に学べる
  • テスト技術者向けに、テスト設計および実施のノウハウを披露し、解説している本。
  • 誰が読んでも理解ができ、すぐに実践できることを目標にソフトウェアテスト技法を一連の流れで説明
    • 一連の流れとは、テストの視点・観点といった「点に注意を向ける」といった話から、テストの目的の一つである品質に関する情報を提供する「多次元の品質」まで

目的

テスト技法の正しい使い方や一連の流れを学ぶことで、実践的にテスト設計できるようになる。

1章 点に注意を向ける

怪しい点に向けるテストについての章

  • 仕様書を読むときは3色ボールペンを使うことをおすすめしてた
  • 仕様書で曖昧なところは具体的なデータを示し、そのデータを見て、「間」「対称」「類推」「外側」を考える癖をつける
  • 思っきり意地悪になってテストデータやテスト手順をつくる
  • 過去の経験を活かすこと

テストの大部分は、仕様書を読んで怪しいところを見つけて確認する

テストの大部分を占める怪しいところをテストする方法の章

2章 線を意識する

連続して変化する数値や文字コードについてテストする方法について

同値分割と境界値分析

同値分割 入力される可能性があるデータをすべてテストするのはたいへんなので入力をグルーピングしてそれぞれのグループから代表となる値を選びそれだけをテスト 同値分割した各々のグループのことを「同値クラス」と呼ぶ

境界値分析 代表となる値を選ぶときにそれぞれのグループの端っこを狙う 境界値に関係するバグは数が多い

  • 境界値、端っこにはバグが隠れている可能性が多い。(図に描いて問題を正しく理解するように)
  • 異常値は他の異常値を隠す
  • 線を意識することで、端っこ以外の点をテストから除外し効率化することができる

3章 面で逃さない

  • 1〜2章は主にデータに焦点を当ててテストを減らす方法について
  • ソフトウェア自体はデータからなるのではなく、ロジック(論理)の塊から構成されている。
  • ロジックとは入力の組み合わせによる特別な動作。ソフトウェアの入力が系統的にロジックを網羅し、正しく動作することをテストするテクニックを身につける必要がある。

ドメイン分析テスト

関係性がある複数の変数を同時にテストする方法

on/off/in/out

on : 着目している境界値のこと

off : onポイントに対して境界値分析をしたときに見つかる隣接したもう一つの境界値のこと

in : ドメインの内側の値

out : 外側の値

多くの変数があった場合は、着目する一つの変数についてon offを変化させ、他の変数についてはすべてinにしておけばその変数のon/offポイントを確実に評価することができる。   Binderのドメイン分析テストマトリクス

方法

  1. まず変数を探す
  2. それぞれのon/off/in/outについて考える
  3. ドメイン分析テストマトリクスを作成する

ドメイン分析テストは、関連性がある(特に数式で結ばれている)複数の変数をテストするときに基本となるテクニック(範囲を扱うとき等)

3.2 デシジョンテーブル

デシジョンテーブルで扱う変数は倫理式で結ばれている

  • AND
  • OR
  • NOT

if文やswitch文はすべてデシジョンテーブルにできる

3.3 原因結果グラフ

条件が多くなると大きなデシジョンテーブルを作成する必要がある。

プールグラフから単純な規則を使ってデシジョンテーブルを作成する ソフトウェアのテストで利用するブールグラフのことを原因結果グラフという

3.4 CFD法

CFD(Cause Flow Diagram)法

複雑な論理関係の仕様から重要なテスト条件を漏らさない技法 「原因の集合」と「原因どうしのつながり」に着目し、流れ線でつなぐことによって仕様を図式化し、そこからデシジョンテーブルを作成する技法

原因を集合で表現することで明示的に補集合についてテストの視点が届く

まとめ

  • ドメイン分析
    • on/off/in/out
  • デシジョンテーブル
    • 論理的な関係をテストする基本となる表
    • 同じロジックをまとめるテクニック(デシジョンテーブルを圧縮)
  • 原因結果グラフ
    • 論理関係を目で見える形で表現したもの
    • CEGTestで具体的な事例を解いてみる
  • CFD法
    • 原因結果グラフの欠点である難しさを改善したテスト技法
    • ロジックを設計するときに使用すれば、ロジックの問題点が見つかる
    • 図式化されているのでレビューがしやすい

4章 立体で捉える

  • 新規機能追加機能によってこれまで表にでてこなかった母体のバグが魔物のように目を覚まし、バグとなって顕在化することがある
  • 関連性を効率的にテストしていく必要がある。
  • ソフトウェア自体は3章と同様に2次元で考えて、そこに組み合わせるべき「要因を選ぶ目線」を追加し立体で考える。
  • 要因を選ぶ目線
    • ソフトウェアの利用者である顧客の視点(6W2H)

4.1 HAYST法

仕様上は機能と機能の間には関連がないことが前提になっいるテスト(直交している) 直交している機能を組み合わせたときに、本当に問題が起こらないことを効率よく確認する方法

4.1.1 HAYST法を使う意義 

一般にソフトウェアは各機能に対して、それぞれを独立してつくろうと努力し開発されるもの。 実際はどこかで意図しない関連性が生まれてしまう。

そこでHAYST法を用いてテストをすることが重要になる

4.1.2 因子と水準の抽出

怪しい因子を見つけて、それをHAYST法、またはペアワイズで表に組み上げてテストすることが重要

  • 因子: テスト対象の項目(判定または条件)
  • 水準: 因子の取り得る値
  • 強さ: 因子の組み合わせ数

どうすれば、有効な因子と水準が見つかる?

6W2Hで考える - When - Where - Who - What - Why - Whom(誰のために) - How - How much(価格、量)

4.1.3 FV表

組み合わせるべき因子水準が見つかり、テスト対象の理解が進んだところで FV表を作成

No. 目的機能(Fr) 検証内容(V) テスト技法(T)

4.2 ペアワイズ

4.2.1 ペアワイズテストとは?

ソフトウェアのバグの多くが1つまたは2つの因子の組み合わせによって発生している という事実に基づいてテストケースを作成する方法。

すべての因子の組み合わせでなく、 2組の因子(強さ2) における水準の組み合わせをすべて網羅することによってテストケースを制限したもの

因子:テスト対象の項目、カテゴリー
水準:因子の取りうる値
強さ:因子の組み合わせ数

例えば、ブラウザにメッセージテンプレートを表示させるときの例

要件は

端末 ブラウザ テンプレート
iPhone Chrome 1
android safari 2
macbook Firefox 3
windows Edge 4

この例では因子が端末、ブラウザ、テンプレート
水準がiPhone,android,macbook,windowsなど
強さは組み合わせ数なので、2の場合は(端末,ブラウザ)、3の場合は(端末,ブラウザ,テンプレート)

4.2.2 PICT

ペアワイズ法によってテストケースを生成するためのオープンソース・ソフトウェア

使い方は以下が詳しそう https://qiita.com/greymd/items/ad18aa44d4159067a627

まとめ

複数の要因に倫理関係がない場合。すなわち要因が直交している場合のテスト技法について。

  • HAYST法
    • テスト対象のテスト条件(HAYST法では「因子」と「水準」と呼ばれる要素を使います)を抽出し、これらの組み合わせを網羅するための直交表という表に割り付け、それをもとにテストを実施する技法
    • 組み合わせるべき因子を抽出する方法について
    • 有効な因子と水準の見つけ方
  • ペアワイズ
    • 因子の組(ペア)に注目して、全ての因子の組み合わせでなく、全てのペアの組み合わせにテストを制限
    • PICT

5章 時間を網羅する

普段まったく問題なく動作しているソフトウェアが何気ないタイミングで動かなくなる問題について、状態遷移の観点と並列処理の観点からテストによる対応を考える。

5.1 状態遷移テスト

浅く全体を確認するテストから深く詳細にテストするものがある。

時間を意識したテスト設計について考える

状態遷移テスト

状態遷移図を書いてみる→状態遷移図から、適用不可のイベントを見つけることは困難。

状態遷移表を書き、適用不可(N/A)を含め、セルの一つひとつの動作をテストすることで基本的な状態遷移のテストを実施することができる。

Nスイッチカバレッジ

壊れた内部的な問題の顕在化方法について考える。 テストを確実に漏れなく実施するテスト技法は?→Nスイッチカバレッジ

Nスイッチカバレッジとは、 最初に遷移前の状態を列方向に、遷移後の状態を行方向にならべた状態遷移表を作成する。

状態遷移テストの実際

技法は上記の通りだが、実際の製品に適用しようとした瞬間に困難にぶつかる。

  • ハードウェアの状態
  • ソフトウェアの状態
  • 外の世界の状態

に分けて考える

組み合わせテストの延長線上として捉えることができる。(HAYST 法やペアワイズでテストする)

テストだけではなく、アーキテクチャや設計、開発段階でのモデルチェッキングなどを総動員して対処する必要がある

6章 多次元の品質

人間の構造は現有のどのようなソフトウェアよりも複雑な構造をもっている。 ソフトウェアより複雑な構造をもつ人間のテストについて考えてみればソフトウェアテストへの糸口が見つかるかもしれない。

人間に対するテストとソフトウェアテスト

人間のテストというと学校で受けたテスト、すなわち、日々のテスト、中間試験、期末試験。身体測定、体力測定、健康診断など

人間に対するテストとソフトウェアテスト

人間に対するテスト ソフトウェアテスト
種類 目的 種類 目的
小テスト・中間テスト・期末テスト 新たに学習した範囲を中心にしたテスト 派生開発テスト テストレベル 追加開発を中心にテスト 段階的テスト
科目ごとのテスト それぞれの分野の能力を確認 テストタイプごとのテスト ソフトウェアの特性を中心のテスト
身体測定 大まかな発育状態の確認 静的テスト コード量や複雑度などを静的にテスト
小テスト・中間テスト・期末テスト 新たに学習した範囲を中心にしたテスト 派生開発テスト テストレベル 追加開発を中心にテスト 段階的テスト
体力測定 運動能力を結果で測定 動的テスト 動かしてみて振る舞いを確認するテスト
健康診断・人間ドック 病気の有無を予測しながら確認 テスト専門者によるテスト バグの検出と品質の確認

テストの効率性

ソフトウェアテストにおいても経済的に実施することはもちろん、ツールを整備し簡単に多くの情報を取得できるようにすべき

ソフトウェアテストとは何か

点にはじまり、線、面、立体、時空とテストの複雑度を増やしてきた。 人間に対するテストと比較することで、適切な時期に適切なテストを行うことが大切。

テスト対象は一般的に複雑なので、さまざまな視点から眺めるということをする。 さまざまな視点から眺めるということは多次元である。

一つの方向から眺めただけでは、決してその姿は想像できない。

さまざまな視点でテスト対象をテストすることが重要

  • シナリオテスト
    • わざとちょっと変わった行動や失敗を犯すシナリオをつくり、そこから回復させながらユーザーのしたいことを継続させるようにする
    • 視点の爆発を狭く深く追うことでカバー
    • When,Where,Whoを明確にする
    • 固定名詞や定数値を使う
    • 例外処理シナリオ
  • 受け入れテスト
    • 受け入れるユーザー側でのテスト
  • サンプリングテスト
    • 品質を保証する
  • 統計的テスト
    • 信頼性を確認するための統計的テスト

最後に(まとめと感想)

テスト技法の奥深さを感じました。

テスト技術者のものの見方とは、「部分的ではなく全体・包括的に複数を捉えること、手段ではなく目的に目を向けること、企業ではなくお客様の目線で考えること、独立ではなく相互関連性を発見すること、構造に加え振る舞いを評価すること」

この一文が印象的でした。

今までテストについて真剣に向き合ったことがなくて、とりあえず書いてみるみたいなことをしていたので、テストを書くときに何を考えるか、とか仕様書の読み方はあまり意識していなかったなあ、と反省しました。
あと、PICTは実際に手を動かして使ってみました。
(テスト工数を半分以下に減らせそう...!)

テスト設計やったことなくて、テストってなんだろう?テスト設計って?な人は読んでみるのをおすすめします。