昨日発生していたサイトログインできない不具合は修正されております(詳細はこちら)

動的型言語は静的型言語に比べてテストが増えるのか?

自分も合っているかどうか分からない話で、それなりに重要だと思うので編集自由でまとめてみます。 とりあえずは、自分とmakotokuwataさんのTLをRT含めてまとめてみました。 時間順なので多少会話が前後します。 他の人の意見が聞いてみたいので、含めるべきツイートがある場合は自由に追加してください。
17
早すぎる最適化オジサン @makotokuwata

@tail_y 説明いただきありがとうございます。しかしこの説明ではどのようなものか想像しがたく…。def f(x,y){return x-y}があったとして、f()を呼び出す側でintを渡していることを確かめるテストを書くということでしょうか。

2014-09-01 09:35:22
早すぎる最適化オジサン @makotokuwata

@tail_y 『単体機能毎のテストの粒度を荒くしても』これはテストの数を減らしたりカバーする範囲を減らすということでしょうか(テストを書かない・書けないときに静的言語のほうが安心できるという主張ならわかりますが、今はテストの数についての話なので)。何度もすみません

2014-09-01 09:39:28
早すぎる最適化オジサン @makotokuwata

@tail_y あーそういう感想なんですね。なるほど。いちおう「今まで質問はすべてスルーされた」って書いてあるんですけどね。今回だけの話ではないのに、そういうふうに広めますか。

2014-09-01 09:43:57
早すぎる最適化オジサン @makotokuwata

@tail_y そんな都合いいことがあったんですねw きっと15時間たっても30時間たっても結果は変わらなかったでしょうに、「15時間くらい」というのはまわりに強調されるんですね。賢いお方だ。

2014-09-01 09:48:46
尾野(しっぽ) @tail_y

@makotokuwata どれくらいテストを書くのかは、その時々の必要な安全性によると思いますが、つまり「同じ安全性で、同じテスト数か?」あるいは「同じテスト数で、同じ安全性か?」ということになると思います。そのため、今回で言えば同じ安全性を確保するのであればテストが増えるかと

2014-09-01 11:29:21
尾野(しっぽ) @tail_y

@makotokuwata ランタイムエラーに関してのテストということで言えば、def f(x,y){return x.a - y.b} といった関数の場合(つまり、xとyが構造体)、typoによって実はx.aが存在しなかった、という状態を防ぐものです。

2014-09-01 11:33:33
尾野(しっぽ) @tail_y

@makotokuwata (続き)単体テストは基本的には、x.aの存在を能動的にテストしたりはしません。しかし、メソッドごとに単体テストを書くことで、このエラーはランタイム時に発覚します。しかし、

2014-09-01 11:35:07
尾野(しっぽ) @tail_y

@makotokuwata (続き)静的型であればこのランタイムテストは不必要になります。これは内部(private)関数のテストを必要とするかどうかに影響を与えます。内部関数はテストを省略可能ですが、ランタイム時にその関数を通らない状況がありうると、バグの取りこぼしとなります

2014-09-01 11:37:11
尾野(しっぽ) @tail_y

@makotokuwata こちらの質問は先のツイートでカバーできたと思います。また、「テストを書かない・書けないときに静的言語のほうが安心できる」と「同一の安全性でテストの数に差が出る」というのは同じことを指すと思われます。まさか、違う安全性での比較ではないですよね?

2014-09-01 11:38:34
尾野(しっぽ) @tail_y

@makotokuwata 有名人の話は今回だけの僕を標的にした話なのでは?違ったら申し訳ないです。

2014-09-01 11:39:06
尾野(しっぽ) @tail_y

@makotokuwata 15時間に対して大した意味は無いと重いますが・・・。「有名人がリツイートしたとたん、慌てたように返事が何通もやってきてびっくり」と周囲にアピールするのは良いんですかね…。

2014-09-01 11:41:32
早すぎる最適化オジサン @makotokuwata

@tail_y だから『typoによって実はx.aが存在しなかった、という状態を防ぐ』ためのテストってどんなのなんですか?通常のassertEqual(expected, f(x1, y1)) というテストでそのtypoは充分防げますよね。それとは違う、typoを防ぐテストって何

2014-09-01 21:35:42
早すぎる最適化オジサン @makotokuwata

@tail_y 念のために聞きますが、まさか静的言語なら f(x,y){return x.a-x.b} のような簡単なコードのテストは書かない、というわけじゃないですよね?もしそうなら議論の前提が大きく違うため、行き違いをなくすために聞いておきます。

2014-09-01 21:44:04
早すぎる最適化オジサン @makotokuwata

@tail_y 両者は違うと思いますが…。こりゃ前提が大きく違いますね。前者は同意しますが、後者は違うでしょ。十分なテストを書けば動的でも静的でも同じような安全性なんだから。それともまったく同一の安全性じゃないと納得しない人?

2014-09-01 21:54:13
尾野(しっぽ) @tail_y

@makotokuwata typoは単体テストの副産物として防がれますし、逆にランタイムエラーしか無い言語の場合はこれによって防がれなければならない、という認識です。

2014-09-01 21:56:17
尾野(しっぽ) @tail_y

@makotokuwata 内部のprivateフィールドの場合書かない場合があるという認識です。ここらへんの議論に関しては調べると幾つか出てきますが。 google.co.jp/search?sourcei…

2014-09-01 21:57:38
尾野(しっぽ) @tail_y

@makotokuwata 「同一」の範囲がどうかというのは認識の差なので水掛け論になります。自分としては動的テストの「十分なテスト」というのは、テスト時にランタイムチェックがされない場所が無いことのことで、静的言語はそうでなくとも同程度の安全性が保たれるという認識です。

2014-09-01 22:00:22
早すぎる最適化オジサン @makotokuwata

@tail_y 『有名人の話は今回だけの僕を標的にした話』ちょっともう何を言ってるのかわからない日本語ですねー。 最初のは「このように〜と主張している人は多いけど」って書いてるんだから、多くいる中での一例にすぎないことはわかるでしょうに。国語苦手なのかもしれんけど。

2014-09-01 22:00:56
尾野(しっぽ) @tail_y

@makotokuwata 最初のはそうかもしれませんが、「有名人がRTしたら慌てて返事してきた」人は、僕以外にいらっしゃったんですか?

2014-09-01 22:02:14
早すぎる最適化オジサン @makotokuwata

“「テストを書かない・書けないときに静的言語のほうが安心できる」と「同一の安全性でテストの数に差が出る」というのは同じことを指すと思われます。” twitter.com/tail_y/status/… 予想外の衝撃的な結末!こりゃ話が噛み合ないはずやで…

2014-09-01 22:05:30
尾野(しっぽ) @tail_y

動的型と静的型の話はちゃんと話をすればそこそこおもしろい話になると思うのだけど、結局は人格批判の話に落ち着いちゃうというか、なんとも残念な感じではある…。

2014-09-01 22:07:42
尾野(しっぽ) @tail_y

静的型と動的型というのは、テストを書かなかった時、つまり底の高さにまず差が出る。まあ、ここは当たり前だけども。それで、テストを書いていくと2つの安全性は高まっていく。この時に動的型のほうが速度が早いということは無いため、2つの安全性は少なくとも平行して上がっていくことになる。

2014-09-01 22:10:00
尾野(しっぽ) @tail_y

ちょっと訂正、静的が既に潰しているテストが動的型のほうでローコストで潰せるので、動的型のほうが最終的な速度に関しては早くなる可能性はあるな。

2014-09-01 22:11:56
尾野(しっぽ) @tail_y

それで、理想的なテスト量を書くことで、動的型だとうろ静的型だろうと、まったく同じ、つまり完全な安全性を得ることが出来る。問題は、この理想的なテスト量とはどこにあるのか?そして、そのテストを用意した場合に変更に対するコストはどうなるか?という話になる。

2014-09-01 22:13:39
尾野(しっぽ) @tail_y

完全なコードが無いように、完全なテストは無いが、仕様が予め決まっているサービスなら、おそらく全ての関数に、全ての行を通るテストを書くことで達成しうるだろう。ところが、そうではなく、容易に仕様や設計そのものがごっそり入れ替わるコンテンツがある。例えばゲームがそれだ。

2014-09-01 22:16:49