ストーリーポイントを効率よく見積もる為に

ストーリーポイントはどのように見積もっていますか?PO がユーザーストーリーを紹介した上、各自が手元のプランニングポーカーから一枚を引き(もしかしたらアプリかもしれません)、「せーの」と唱えった後おもての数字を見せ合います。もし違いが存在していたら、互いに説明をし、最終的に同じ数字に揃えるようにします。とても定番的なやり方ですよね。しかし、そのやり方を貫くだけで、上手く行くとは限りません。例えば、A さんが 1 を出しているものの、B さんがその数字をはるかに上回った 5 とかを出しているケースが頻出していたら、回し方に問題が潜んでいるはずです。自分の経験上、以下の 3 点に関する問題が起因となった可能性が高いです。

バックログアイテムがうまく作成されていない

正確なストーリーポイントが出せていないというのはあくまで事象で、そもそも土台に当たるバックログアイテムが見積もりにくい状態になっていることはよくあります。バックログアイテムの完成度を判断するのによく使用されているのは「I.N.V.E.S.T」という基準です。要するに、取り扱いやすいアイテムは以下の基準を満たさなければいけません。

  • Independant (独立している)
  • Negotiable (交渉できる)
  • Valuable (価値がある)
  • Estimatable (見積れる)
  • Small (サイズが小さい)
  • Testable (検証できる)

ネット上「I.N.V.E.S.T」を説明する良い記事がたくさん存在している為、細かい説明は割愛しますが、ここで Independant と Estimatable に注目したいです。例えば、「上のアイテムを完成しないと、下のアイテムが見積もれないよ」という言い方はよく聞きます。それは恐らく独立性の不足を表している証拠です。上手く切ったユーザーストーリーなら、お互いに干渉しないし、不確実性の急増がしません。

また、Estimatable も大事です。ストーリーポイントを出す前、開発チームが見積もる対象のスコープと情報を理解していなければ、正しい見積もりが出せません。もしバックログアイテムが見積もりにくいと感じたら、リファインメントもしくはプランニング 1 のタイミングで開発チームと PO が擦り合わせを行うべきです。

Read More

JavaScript のプリミティブ型

JavaScript 言語において、データ型は恐らく基礎中の基礎だと言われてもおかしくありません。しかし、JavaScript をよく使用している方でも、データ型に関する知識が曖昧もしくは間違っているかもしれません。スコープが広がり過ぎないように、プリミティブ型に焦点を当て、JavaScript のプリミティブ型にまつわる落とし穴について解説してみたいと思います。

JavaScript の型

プリミティブ型

執筆時の最新パージョンである ECMAScript 2019(略称:ES2019/ES10)の中に、データ型は全部で 7 種類です。そのうちプリミティブ型は下記の 6 つです。

  • Number
  • String
  • Boolean
  • Null
  • Undefined
  • Symbol

C 言語のように、integer や double を区別することがなく、数字系なら Number 型一択です。ただ、Number 型に特殊な値が 3 つ存在します:+Infinity(無限大)、-Infinity(無限小)およびNaN(Not a number/数字ではない)です。
Java でしたら、String はオブジェクトになりますが、JavaScript に String というプリミティブ型が存在します。意味は同じく文字列を表現する型です。
Boolean、Null と Undefined の値は限られています。Boolean の値は true と false 二つのみです。Null の値はnullだけで、Undefined の値はundefinedのみです。
Symbol は ES2015(通称:ES6)にて新しく追加されたデータ型です。MDN を含む、Symbol は ES2016 で追加されたとの記述が散見されますが、それは間違い(タイポ?)です。
また、2019 年 6 月に開催された TC39 ミーティングにて、BigInt という新しいプリミティブ型はStage 4 へ進むことが許可されました。よって、ES2020 の言語仕様へ組まれることがほぼ決定になっています。BigIntは文字通り、今までの Number 型だと取り扱えない大きな数字を処理する為に導入される型です。一部の資料では ES2019 の新機能だと説明されていますが、残念ながらそれは間違いです。確かに一時期 ES2019 へ入れられるんじゃないかと見られていましたが、まだ仕様へ入っていません。ただ、ChromeFirefoxNodejs10.8+ではすでに実装されていますので、JavaScript のプリミティブ型としてカウントされていることもあります。

Read More

JestでDateのコンストラクタをモックする

下記の関数があるとしましょう。

1
2
3
function calcDuration(date: string) {
return Math.abs(new Date().getFullYear() - new Date(date).getFullYear());
}

この関数のテストを書くのに、注意しなければいけないことが1点あります。もう気づいたと思いますが、new Date()の結果を固定値にしないと、テストの結果が実行時の日付に依存してしまいますので、環境依存が発生し許容できないでしょう。Jestにはモジュールモックを含め、いくつのやり方がありますが、標準ビルトインオブジェクトかつコンストラクタの場合、どうモックするか、ドキュメントには詳しく書かれませんでした。ウェブで検索してみた結果jest.spyOn(global, 'Date')という感じで書くのは一番直感的で柔軟性が高いと感じました。よって、テストのコードはこうなるかと思います。

1
2
3
4
5
6
test("mock", () => {
const dateToUse = new Date("2015-01-01");
jest.spyOn(global, "Date").mockImplementation(() => dateToUse);
const duration = calcDuration("2011-01-01");
expect(duration).toBe(4);
})

しかし、上記のコードの実行結果は[Jest] Expected value to be (using Object.is): 4, Received: 0というエラーになるでしょう。理由は簡単です。calcDuration関数内でDateコンストラクタは二回も呼ばれ、そして常にdateToUseが返ってきます。よって、差分が0になるのは正しい振る舞いです。そこを修正する為に、mockImplementationにて条件分岐を作ればシンプルに解決できます。引数が空の場合dateToUseを返し、それ以外は元々のビルドインオブジェクトを使わせます。結果は下記の感じです。

1
2
3
4
5
6
7
8
9
10
test("mock", () => {
const OriginalDate = Date;
const dateToUse = new Date("2015-01-01");
const mocked = jest.spyOn(global, "Date").mockImplementation((arg) => {
return arg ? new OriginalDate(arg) : dateToUse;
});
const duration = calcDuration("2011-01-01");
expect(mocked).toHaveBeenCalledTimes(2);
expect(duration).toBe(4);
});

Read More

List of Whatever Cases

NameExample
flat casesamplenamingconvention
pascal case / capital camel caseSampleNamingConvention
camel casesampleNamingConvention
kebab case / chain case / spinal case / lisp case / caterpillar casesample-naming-convention
train caseSample-Naming-Convention
snake casesample_naming_convention
screaming snake case / macro caseSAMPLE_NAMING_CONVENTION

References

なんちゃらケース系の用語が多すぎるからまとめてみました。以上

Read More

「Kotlin Fest 2018」参加レポート

Kotlinは趣味でちょろっとしか書いていませんが、Kotlinの哲学である実用主義・簡潔・安全・相互運用性に魅了され、理想と現実のバランスをうまくとっているなと感心しましたので、Kotlin Fest 2018へ参加してきました。とても楽しかったし、勉強にもなった為、レポートとしてまとめたいと思いました。

Kotlinもう一歩

最初に参加したセッションはヤフーの森さんによる「Kotlinもう一歩」でした。Kotlinのタイプシステムを用いてGenericsとType Projectionを紹介していました。プレゼンの内容をよくまとめたのは下記の一枚です。

タイプシステムの観点で不変・共変・反変を説明してくれてとても印象的だと感じました。タイプシステムを一言で説明すれば、「タイプAが期待される全ての箇所で、タイプBが使用可能であれば、タイプBはサブタイプだと言える。逆に、タイプAはスーパータイプである。」になります。この一言さえ分かれば、「タイプAは自分自身のサブタイプであり、スーパータイプでもある」ということは理解できるでしょう(ちなみに、これはisSubtypeOfisSupertypeOfで検証できる)。また、「StringString?のサブタイプ」というのもわかるはずです。

How to Test Server-side Kotlin

実例を交えた説明でわかりやすかったです。特に技術選定時に考えたこととハマったポイントの紹介はとても参考になりました。テストコードを書きやすくする為に作られたFactlinkotlin-fill-classは確かに使いやすそうだなと感じました。

Read More

Vuex Plugin 101

Vue.js Tokyo v-meetup #7」にて発表させて頂きました。
スライドはこちらです。

発表したこと

  • Vuexのプラグインは簡単に作れますよ。
  • VuexのプラグインはよくsubscribeというストアインスタンスのAPIを使ってます。
  • ただし、subscribeのコールバックはmutate後呼ばれますので、もっと早い段階で処理を加えたければ、2.5.0から導入されたAPI(subscribeAction)を使いましょう。
  • Vuexのプラグインを探したければ、awesome-vueリポジトリはいいところです。

尺の関係で話せなかったこと(スライドに入れました)

  • 名前通りあくまでsubscribeなんで、いわゆるAOPのような使い方は期待しないでください。
  • vuex-shared-mutationsというタブ間の状態を同期してくれる素晴らしいVuexプラグインがあるが、実は考え方はとてもシンプルです。
  • 他にも色んな有用なプラグインがありますよ。

Read More

ある条件を満たすDOM要素を抽出するコード

週末にデモプログラムを作成する時、ある要素の中から、指定された条件を満たすDOM要素を抽出する機能が必要だった為、下記のようなコードを作りました。

1
2
3
4
5
const selectAll = el => condition => [el,
...Array.from(el.children)
.map(child => selectAll(child)(condition))
.reduce((arr, i) => arr.concat(i), [])
].filter(condition)

考え方

実は、主な作業は2つだけです。

  1. 全ての要素を羅列します。
  2. 条件に満たしている要素をフィルターリングで抽出します。

コードを書けばこうなります。(allElements=全ての要素、condition=条件)

Read More