テストしにくいコードをテストする方法 その2 [無断転載禁止]©2ch.net

0001デフォルトの名無しさん2017/01/03(火) 14:50:44.83 ID:f6cee8Pv
ここで言うテストっていうのは
ユニットテストみたいなものね。

人間がぽちぽち操作してやるテストじゃありません。


前スレ テストしにくいコードをテストする方法教えて下さい
http://echo.2ch.net/test/read.cgi/tech/1334408391/
0002デフォルトの名無しさん2017/01/03(火) 18:00:08.97 ID:f6cee8Pv
例で考えよう。
private function numberOfFeet(動物) returns 脚の数
{
 if (動物 == 人) { return 2 }
 if (動物 == 犬) { return 4 }
 if (動物 == 猫) { return 4 }
 raise exception 知らない動物
}
っていう関数が既にあるとする。
0003デフォルトの名無しさん2017/01/03(火) 18:00:28.68 ID:f6cee8Pv
その関数で対応する動物がもっと増えたとしよう。

private function numberOfFeet(動物) returns 脚の数
{
 if (動物 == 人) { return 2 }
 if (動物 == 犬) { return 4 }
 if (動物 == 猿) { return 4 }
 if (動物 == キジ) { return 2 }
 if (動物 == 猫) { return 4 }
  :
  :
 raise exception 知らない動物
}

いよいよ複雑になってきた。privateなnumberOfFeetをテストしたい。
となってきたら、設計が悪いって話なんだよ。

そもそもこの関数のテストはどうするか? ↓このようにやるか?
assert( numberOfFeet(人) == 2 )
assert( numberOfFeet(犬) == 4 )
assert( numberOfFeet(猿) == 4 )
 :

あほらしい。これは実行コードの内容を単純に変換してテストコードに転記したにすぎん。
新たに対応する動物が増えたら、それに対応するコードを追加するだけの単純作業
いったいなんの意味があるというのか。
そこ(実行コード)にそう書いてあるんだから関数の実行結果はあきらかではないか。

カバレッジを100%にするためには必要?
それは "設計が悪いから" こうするしかなくなってしまってるんだよ
0004デフォルトの名無しさん2017/01/03(火) 18:00:58.15 ID:f6cee8Pv
private関数がテストしたいと思ってきたら設計が悪いという話だったね。
この場合は、このprivate function numberOfFeetを
publicにしてテストするのではなくて設計を変えるってことだよ。

もちろんやり方はいくつもある。もっともシンプルな解決方法ではないが
今回はヘルパークラスを作る方法で解決してみようか。

LookupTableクラスというものを作る。
このクラスは特定のキーを元に特定の値を返すクラスだ。
newの引数で対応するキーと値の組み合わせを渡すことができる。

lookup_table = new LookupTable({a: 1, b: 2, c: 3})

さて、このLookupTable・・・のテストを書くとき、
動物が増えたら?などということを考える必要はない。
LookupTableは汎用的なクラスなのだからそこに動物は出てこないからだ。
では使う側はどうなるか?

data = {人: 2, 犬: 4, 猿: 4, キジ: 2, 猫: 4}
numberOfFeet = new LookupTable(data)

こういうコードを書くだろう。
テストはどうする? ・・・答えは "不要" だ。

なぜならばLookupTableのテストはすでに書いているからだ。
おそらくこのコードは別のテストコード時に最低1回は通るだろう。
それでカバレッジは100%になる。いくら動物が増えたとしても
そのdataというデータ定義の行は通るのでカバレッジは100%のままだ。
0005デフォルトの名無しさん2017/01/03(火) 18:01:14.98 ID:f6cee8Pv
これを手抜きやずるいやり方だと思うか?

元の設計のテストというのはデータが増えれば対応するテストを
増やすだけという単純作業だっただろう?

こんなのそもそもやる意味がない
データが変われば、それに応じて答えは変わる。
それだけのことだろう。

こういうのは、そもそもやらなくていいんだよ。

変数aに1を入れました。これ対応する変数aは1であるか?という
テストコードを書く意味はない。
テストすべき対象は実行するコードであってデータ定義はテストしない。

LookupTableという汎用的なクラスを作ることで実行するコードの中から
データ定義を分離させることで、少ないテストパターンでカバレッジ100%にしながら
テストコードを書くことができる。それが可能な設計に変更したからだ。

ということで、 テストしたくなってしまった
private function numberOfFeetは
悪い設計を正すことで存在が消えました。

ということでおしまい。
0006デフォルトの名無しさん2017/01/03(火) 18:01:31.58 ID:f6cee8Pv
プログラム設計の善し悪しとテスト技法は密接に関係している。

というかprivate関数をテストする言語特有の裏技的テクニックは
テスト技法ではないんだがな。

プログラム設計が悪いと、テストが難しくなったりできなくなったりする。
private関数のテストもその一つで、private関数がテストしたいほど
複雑になったら、それは設計が悪いということだよ。

こういうのはprivateのまま頑張ってテストするんじゃなくて、
単純にpublicに変えるのでもなくて、
汎用的な処理をヘルパークラスや親クラスとして抽出する

テストしづらい → 設計が悪い → 設計を直す → テストを書く
こういう流れでなくてはいけない。



話は少し変わるが、設計を直すその途中で作成するリファクタリングを
するためだけに用いる一時的なテストコードに名前をつけたいね。

本来であればテストしづらいコードであってもテストコードは
あってしかるべきなんだが、多くの場合悪い設計のコードにテストコードはない。
だから新たにテストコードを追加する。しかしこのテストコードは
リファクタリング後にすぐにメンテナンスして、違う形になる。

だから一時的なテストコードになるんだよね。
0007デフォルトの名無しさん2017/01/03(火) 18:01:50.63 ID:f6cee8Pv
あ、そうそう

リファクタリングを行うための一時的なテストコードであれば
単純にprivateをpublicに変えたり
private関数のテストコードを書くのもありだから。

このprivate関数へのテストはリファクタリングをしたあとの
テストコードのメンテナンスでなくなるという前提であれば
一時的にprivate関数へのテストコードを書くのはあり。
0008デフォルトの名無しさん2017/01/03(火) 18:02:53.02 ID:f6cee8Pv
https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#testing-private-code

Testing Private Code

If you change your software's internal implementation,
your tests should not break as long as the change is not observable by users.
Therefore, per the black-box testing principle, most of the time you should test your code through its public interfaces.

If you still find yourself needing to test internal implementation code, consider
if there's a better design that wouldn't require you to do so. If you absolutely
have to test non-public interface code though, you can.

プライベートコードのテスト

あなたのソフトウェアの内部実装を変更した場合、変更がユーザによって観察されない限り、
テストは中断されるべきではありません。 したがって、ブラックボックスのテストの原則に従って、
ほとんどの場合、パブリックインターフェイスを使用してコードをテストする必要があります。

依然として内部実装コードをテストする必要がある場合は、そうする必要のない
優れた設計があるかどうかを検討してください。 しかし、非公開のインターフェイスコードを
絶対にテストしなければならない場合は、できます。
0009デフォルトの名無しさん2017/01/03(火) 18:03:14.28 ID:f6cee8Pv
「privateだからテストしてはいけない」という意見はそもそも的外れで
テストすべきものがprivateという状態ができたら
それは設計がおかしいと気づかないといけない。

「privateだからテストしてはいけない」は単なる思考停止で
privateをテストしたいのは設計がまずいからだね、設計をなおそう。
という流れにならなければいけない。
0010デフォルトの名無しさん2017/01/03(火) 18:03:37.53 ID:f6cee8Pv
http://higelog.brassworks.jp/1941

テストコードにもリファクタリングが必要

・昔はテストコードがメンテ対象であるという意識が薄かった
・見てすぐ分かるテストコードがよいという考えからコピペコードが非常に多かった
・テストコードがたくさんあることによって動きが取りづらくなり、変更コストも上がる
・素早く動きたいがためにTDDしているのにそんな皮肉な結果になってしまう
・たくさん書くのではなく必要十分書くことが大切
・書き散らすと「テストケース爆発」を起こす
・テストコードもメンテし続けるためにリファクタリングして行く必要がある
0011デフォルトの名無しさん2017/01/03(火) 18:04:15.86 ID:f6cee8Pv
http://dev.classmethod.jp/testing/10_errors_about_unit_testing/
> 3.テスト対象が完璧な設計であるという勘違い
>
> ユニットテストを実践することによりプロダクションコードが
> 適切に修正されていく状態でなければなりません。
>
> ユニットテストの重要な目的のひとつに「テスト対象クラスやメソッドの
> 使用感を把握する」ことがあります。机上の設計やフィーリングだけで
> 書いたコードは、使ってみての違和感や使いにくさに気付き難いものです。
> それらの使用感は、実際に利用してみてはじめて気付きます。
> だから、テストコードを書くことで実際に利用してみます。これはサンプルコードを書く事に他なりません。
>
> サンプルコードを書くと、「これは使いにくい」と感じたり、
> 「これはこうした方が使いやすい」と感じたりします。それはユニットテストの
> 大きな効果です。もし、使いにくいと感じたならば、すぐにテスト対象を修正します。
> テスト対象が完璧な設計で変更する余地が全く無い、または変更し
0012デフォルトの名無しさん2017/01/03(火) 18:04:36.15 ID:f6cee8Pv
これも関連する話。まずリファクタリング後にテストを変更するのは当然

まず対象のクラスに対してテストを書く。そしてリファクタリングをする。
この時、汎用的な処理をヘルパークラスや親クラスとして抽出する。

ここまででテストを変更することはないが、
次に対象のクラスにあったテストのうち、ヘルパークラスや親クラスに分離したものは、
対象のクラスのテストではなくて、ヘルパークラスや親クラスのテストとして移動する

ヘルパークラスや親クラスでテストしている内容を、
それを使用している対象クラスでもやる必要はない。

具体的に言うと、あるモデル、例えばUserモデルクラスにsaveメソッドを作ったのであれば
そのsaveメソッドのテストを書くのは当然だが、そのsaveメソッドが親クラス
(例えばRailsで言えばActiveRecord::Baseクラス)にあるものならば、
Userモデルクラスでsaveメソッドのテストをする必要はない。


こうやってヘルパークラスや親クラスに処理を移動して、それに対するテストを書くことで
それを使用している部分ではテストが不要という状態を作り上げることが重要
0013デフォルトの名無しさん2017/01/03(火) 18:05:03.70 ID:f6cee8Pv
privateメソッドに対してテストをしたくなっったら
それはクラスが肥大化してる証拠だよ。

まず前提としてprivateメソッドなんてものは
ほとんど必要ありません。

長い処理があったとして、その中で汎用的な処理を
抜き出していったら、コードは短くなります。
短いのだからprivateな関数にするまでもありません。

それでもprivateメソッドが残ったとしたら
それはヘルパーメソッドとして別クラスに分離する。
別クラスの関数を呼ぶのだから、必然的にそのメソッドはpublicになる
そうすりゃそのメソッドだけでテストかけるだろう?

privateメソッドをテストしたいっていうのは、作り方が悪いんだよ。
0014デフォルトの名無しさん2017/01/03(火) 18:06:10.26 ID:f6cee8Pv
ある程度埋めないと落ちるといわれたので、
前スレのハイライト(笑)をコピペ
0015デフォルトの名無しさん2017/01/03(火) 18:45:05.85 ID:mYtDE+67
なめてんの?
0016デフォルトの名無しさん2017/01/03(火) 19:23:41.90 ID:Oj8nbLhF
>>13
>privateメソッドをテストしたいっていうのは、作り方が悪いんだよ。

バカ丸出し。
privateメソッドだからといって十分にunit testingしない奴は頭が悪いんだよw
privateメソッドがあるからといって設計のせいにするのは性格が歪んでんだよw
privateメソッドをテストする技術を持たないからといって
出鱈目な ”あるべき論” を捏造する奴は技術者としての道徳が欠如してるんだよw
0017デフォルトの名無しさん2017/01/03(火) 22:27:14.69 ID:f6cee8Pv
>>16
お前日本語がわかってないなw
0018デフォルトの名無しさん2017/01/04(水) 09:28:49.04 ID:cRY9oGv2
privateメソッドとテストに相関はありません
リファクタリングのスレに移動してください
0019デフォルトの名無しさん2017/01/04(水) 14:06:42.84 ID:mEkZwZd0
>>13
馬鹿丸出し
頭固すぎ
0020デフォルトの名無しさん2017/01/04(水) 14:10:32.56 ID:mEkZwZd0
>>9
> テストすべきものがprivateという状態ができたら
> それは設計がおかしいと気づかないといけない。
という思考停止にきづかない馬鹿pgr
0021デフォルトの名無しさん2017/01/05(木) 04:41:00.85 ID:4wDE4Xcp
当のKentは ID:f6cee8Pv みたいな教条主義とは対極にいるんだがな。
0022デフォルトの名無しさん2017/01/05(木) 07:46:32.69 ID:SvuiXrcs
>>21
どこが?
https://twitter.com/kentbeck/status/3579860805

2chのレスだけで知ったかぶってる、まさに半可通
この手のクズは他分野でも同様なのだろうが、
本も読まず、手も動かせない人間なんて、
職人気質なTDD実行側の人間が、一番嫌うタイプだぞ
0023デフォルトの名無しさん2017/01/05(木) 07:59:15.46 ID:SvuiXrcs
むしろつまみ食いしかしてないくせに、拡大解釈して腐ったコード撒き散らすな
ケントベックはXPは熟練者が必要とは言ってるだけで、手法は何でも良いなんて言ってない
テストコードも、trivialな物は不要、複雑なprivateメソッドは設計が悪いと一蹴してる
これを教条主義だと言うなら、レッテル張る事しかできない屑だな
0024デフォルトの名無しさん2017/01/05(木) 08:26:33.27 ID:rS/TqFdr
前スレでprivateメンバーしか見ずにそれをテストしようとしたり、考え方がおかしい。

あと、Kent Beckはテストは不要だと思ったらやらない、と言うぐらい柔軟な思考の持ち主だぞ
0025デフォルトの名無しさん2017/01/05(木) 09:16:09.02 ID:qUpJhZLr
前スレ埋めてからやってくれ。
0026デフォルトの名無しさん2017/01/06(金) 14:09:56.36 ID:jUueQ44/
>>23
> 複雑なprivateメソッドは設計が悪いと一蹴してる
ソースは?

>>22のtweetがそれだとしたら、その会話の流れが設計の善し悪しであることを示す他のtweetも示せ
0027デフォルトの名無しさん2017/01/06(金) 14:31:04.58 ID:jUueQ44/
Kent BeckはImplementation Patternsの中でこう言ってる

* Inner Class
* Bundle locally useful code in a private class.

* Method Visibility
* Make methods as private as possible.

* Helper Method
* Create small,private methods to express the main computation more succinctly.

別に、private classやprivate methodを否定しているわけではない
0028デフォルトの名無しさん2017/01/06(金) 15:00:59.05 ID:ueXke68e
公開する必要のないprivateメンバーをpublicにしてまでテストするなんて真逆の発想なんだよなぁ
0029デフォルトの名無しさん2017/01/06(金) 15:23:30.30 ID:jUueQ44/
>>28
まあ、そのprivateメソッドが、所属するクラスと直交していて再利用可能な内容だった場合は
別クラスにpublicメソッドとして切りだすのもいいけど、いつでもそうとは限らないからな
0030デフォルトの名無しさん2017/01/06(金) 16:24:11.26 ID:bv2F1pCR
0031デフォルトの名無しさん2017/01/06(金) 19:55:59.99 ID:SxMvRiz3
飽きてきたので以降privateの話題禁止
0032デフォルトの名無しさん2017/01/06(金) 21:44:03.66 ID:IT5nhYwQ
>>27
レスをよく読め文盲め
言ってもいない事を言ったかのように叩くやつがあるか
0033デフォルトの名無しさん2017/01/06(金) 21:44:44.23 ID:IT5nhYwQ
>>26
勝手に追えばいいだろ
くだらない人種だな
0034デフォルトの名無しさん2017/01/07(土) 01:43:02.53 ID:jcRWOLCk
結局世界的有名人であるKent Beckが言ってることは
>>1がまとめたとおり。

privateメソッドをテストしようと思った時点で、
そのprivateメソッドは設計が悪いということ。

悪い設計を直す過程でpublicになる。
設計を直さなないで単にpublicに変更するのは間違い。
0035デフォルトの名無しさん2017/01/07(土) 07:12:47.19 ID:0cNXAmIk
>>34
まだそんなこと言ってんの?ばかだなあw
0036デフォルトの名無しさん2017/01/07(土) 07:22:58.29 ID:55rirhTJ
そこで#define private publicですよ。え?
0037デフォルトの名無しさん2017/01/07(土) 08:54:35.16 ID:bP0cwlRr
publicメソッドしかテストできない道具を使ってprivateメソッドをテストすることはできない。
一種のトートロジーだな。
0038デフォルトの名無しさん2017/01/07(土) 12:20:08.80 ID:HNCUhS1Q
前スレ埋めてからやれ
こういう奴らが糞コードを放りっぱなしにしていってこっちが掃除しなくちゃならなくなるんだよ
バグ解析依頼されて見てみたら、意識だけ高いけどそのまま放置されたゾンビコードに当たったときの腹立たしさって
まあお前らのおかげでちょっといい飯が食えるんだから感謝しないといけないな
0039デフォルトの名無しさん2017/01/07(土) 13:20:41.90 ID:jcRWOLCk
>>35
悔しいなら反論しろよw
0040デフォルトの名無しさん2017/01/07(土) 19:21:41.83 ID:adAq7wbq
今現在を占う 2017/1/7 19:21

おみくじ 大吉 →  ♌ 獅子座
.      吉   →  ♈ 牡羊座 ♋ 蟹座   ♓ 魚座 
.      中吉 →  ♏ 蠍座 
.      小吉 →  ♉ 牡牛座 ♍ 乙女座 ♎ 天秤座 ♒ 水瓶座
.      末吉 →  ♊ 双子座
.      凶   →  ♐ 射手座
.      大凶 →  ♑ 山羊座
0041デフォルトの名無しさん2017/01/08(日) 09:54:40.93 ID:qkk6ZrX+
吉だぜ、いやっほーい
0042デフォルトの名無しさん2017/01/08(日) 09:54:57.91 ID:qkk6ZrX+
あ、昨日か.....
0043デフォルトの名無しさん2017/01/09(月) 20:16:25.89 ID:pl8AdjB2
今現在を占う  2017/1/9 20:16  (不定期テスト)

おみくじ 大吉 →  ♍ 乙女座 ♑ 山羊座
.      吉   →  ♉ 牡牛座 ♎ 天秤座 ♒ 水瓶座
.      中吉 →  ♋ 蟹座 
.      小吉 →  ♈ 牡羊座 ♏ 蠍座 
.      末吉 →  ♌ 獅子座
.      凶   →  ♊ 双子座 ♐ 射手座
.      大凶 →  ♓ 魚座 
0044デフォルトの名無しさん2017/01/11(水) 00:09:48.89 ID:ha9kcMkV
あんまり可視性でグダグダ言っても揉め事しか起こらん印象は有る。
だからあんまりカプセル化周りの議論は好きではない。
重要なのはテストするコードの粒度じゃないかね。
3 のレベルのコードをテストするのは粒度が細かすぎる。
3のコードを呼んで何かしてるコードのテストコードを書くべきなんだろう。
0045デフォルトの名無しさん2017/01/11(水) 23:15:37.40 ID:1SbN3a75
端折って網羅性が確保できなくなるのであればそもそもこのテスト自体イラネーってのあるよ
だからやるなら機械的に全部やるかそもそもやらないかのどっちかになると思う
0046デフォルトの名無しさん2017/01/11(水) 23:16:53.94 ID:1SbN3a75
あ、Visual Studioのユニットテスト的な話ね
0047デフォルトの名無しさん2017/01/12(木) 00:02:44.60 ID:qhQd7W/g
>>46
2017のlive unit testのことを言ってる?
0048デフォルトの名無しさん2017/01/13(金) 06:48:56.80 ID:tNTQooLV
>>44
しょうがないよ、ID:f6cee8Pvの能力ではそこが限界・・・
0049デフォルトの名無しさん2017/01/13(金) 23:07:22.63 ID:9L2JHio8
>>48
呼んだか?

何か言いたいことがあるなら言ってみな。

今のところ俺の書き込みに論理的に反論している
文章は存在していない。
0050デフォルトの名無しさん2017/01/13(金) 23:40:30.59 ID:2oF12qKz
テスト
○○○●○○○○○○○○●○○○○○○○○●
○○○●○○○○○○○○●○○○○○●●●●●●●
○○○●○○○○○●●●●●●●○○●○○○○○●
○●○●○●○○○○●○○○●○○○○●●●●●○
○●○●○●○○○○●○○○●○○○○○○○●○○
○●○●○○●○○○○●○●○○○○○○○●○○○
○●○●○○●○○○○●○●○○○○●●●●●●●
●○○●○○●○○○○○●○○○○○○○○●
○○○●○○○○○○○●○●○○○○○○○●
○○○●○○○○○○●○○○●○○○○○○●
○○●●○○○○○●○○○○○●○○○○●●

○○○○○○○●○○○○○○○○○○○○○○○○●○○○○○○○○○○○○○○○○●
○○○○○○○●○○○○○○○○○○○○○○○○●○○○○○○○○○○●●●●●●●●●●●●●●
○○○○○○○●○○○○○○○○○●●●●●●●●●●●●●●●●○○●○○○○○○○○○○○○●
○○○○○○○●○○○○○○○○○○○○○●○○○○○○●○○○○○○●○○○○○○○○○○○○●
●●●●●●●●●●●●●●●●○○○○○●○○○○○○●○○○○○○○○●●●●●●●●●●
○○○○○○○●○○○○○○○○○○○○○●●○○○○●●○○○○○○○○○○○○○○○●●
○○○○○○●●●○○○○○○○○○○○○○●○○○○●○○○○○○○○○○○○○○○●●
○○○○○○●○●○○○○○○○○○○○○○●●○○●●○○○○○○○○○○○○○●●
○○○○○○●○●●○○○○○○○○○○○○○●○●●○○○○○○○●●●●●●●●●●●●●●●●
○○○○○●●○○●○○○○○○○○○○○○○○●●○○○○○○○○○○○○○○○●
○○○○○●○○○●●○○○○○○○○○○○○●●●●○○○○○○○○○○○○○○●
○○○○●●○○○○●●○○○○○○○○○○●●○○●●○○○○○○○○○○○○○●
○○○●●○○○○○○●●○○○○○○○○●●○○○○●●○○○○○○○○○○○○●
○○●●○○○○○○○○●●○○○○○●●●○○○○○○●●●○○○○○○○○○○●
●●●○○○○○○○○○○●●●○●●●○○○○○○○○○○●●●○○○○○○●●●
0051デフォルトの名無しさん2017/01/16(月) 23:19:44.60 ID:9FmOEppL
>>48
お前ってプログラムに限らずいつも的はずれな難癖しかつけないよな
0052デフォルトの名無しさん2017/01/21(土) 00:48:16.31 ID:EhyrNbEj
>>49
>>27に論理的な反証があるだろw
ほんとに頭悪いのな
Kentの書いてる英語のとこだけ読み直してお前自身の矛盾に気がつけないの?
0053デフォルトの名無しさん2017/01/21(土) 06:46:40.76 ID:gnjAlXGF
>>52
前スレでもそうだったけど、彼は都合の悪いレスは目に入らない人だから何言っても無駄
0054デフォルトの名無しさん2017/01/21(土) 13:01:41.54 ID:sMDuy5hJ
>>52
それのどこが論理的な反証?

今の話はprivateメソッドのテストの話で、
privateメソッドが良いかダメかの話はしてない

Kent Beckのどこにprivateメソッドの話が書いてあるんだ?
0055デフォルトの名無しさん2017/01/21(土) 13:28:19.57 ID:zMOHiEOd
くすくす…
0056デフォルトの名無しさん2017/01/21(土) 13:47:45.70 ID:EhyrNbEj
残念な頭だな
0057デフォルトの名無しさん2017/01/21(土) 13:58:00.26 ID:sMDuy5hJ
反論お待ちしてまーすw
0058デフォルトの名無しさん2017/01/21(土) 14:03:40.46 ID:EhyrNbEj
Kentの引用読んでも矛盾に気づけない残念さ
ひとりだけ斜め上
0059デフォルトの名無しさん2017/01/21(土) 14:04:25.54 ID:sMDuy5hJ
時間が相手勘違いされかねんから俺の意見を書いておくか

まずprivateメソッドはpublicメソッドを通してテストするもの
(この時点でprivateメソッドの存在は否定してない)

もしprivateメソッド単体でテストしたいと思ったら
それは設計がまずいということ、設計を見直したら自然にpublicになる。
(privateをpublicに変えるだけではない。それは設計変わっていない)

そうすればpublicメソッドをテストすれば良くなる。
0060デフォルトの名無しさん2017/01/21(土) 14:04:58.86 ID:sMDuy5hJ
>>58
俺の意見とどう矛盾するのか言ってみな
0061デフォルトの名無しさん2017/01/21(土) 14:05:54.01 ID:EhyrNbEj
脳が単純だから単純な考え方に縋っちゃうんだろうね
それがたたって物事を複雑にする
0062デフォルトの名無しさん2017/01/21(土) 14:07:22.70 ID:sMDuy5hJ
脳が単純だとprivateメソッドのテストコードの話をしていたのに
privateメソッドを作っていいかどうかの話に
単純化(笑)されるんだろうね。
0063デフォルトの名無しさん2017/01/21(土) 17:46:46.32 ID:O/GZ8TN6
クラス自体がウンコ

最近そう思うようになった
0064デフォルトの名無しさん2017/01/21(土) 19:28:01.03 ID:ij3ZsOnR
xUnitが定番になる以前はビルトインテストも珍しくなかったわな。
つか、他人の作ったテストフレームワークを使うのが当たり前になる前はビルトインテストの方が多かったくらい。

ID:sMDuy5hJ は「製品コードにテストコードが混在するのは良くない設計だ」とでも言うだろうか。
0065デフォルトの名無しさん2017/01/21(土) 20:08:55.14 ID:sMDuy5hJ
>>64
なんか罠張ってますぜって臭いがプンプンするなw
俺からなんて言葉を引き出したいのさ?

> 「製品コードにテストコードが
まず前提として「製品コード」という物の話をしてからだよな。
世の中にはソフトウェアに限らず、不具合がたくさんある不良製品もたくさんある。
テストコードが混在するか否かに関係なく
「(不良)製品コードは良くない設計だ」と言うよ。当然だろう?

それから昔のハードディスクはよく壊れたものだが、今壊れにくくなってるのは
製品を改良したからだ。より良い設計に変えた、逆に言えば昔のやり方は設計が今より悪かった。
これも言うまでもない話だよな。

それとテストコードとはなんぞやの話もしないといけない。
今話しをしてるテストコードとうのは製品で必要ないものであって
故障の場合に障害を調べる調査用端子や自己チェック機能はテストコードではない。
そういう機能をもたせるという仕様があって、その仕様を満たすためにテストコードが存在するだろう。

で、ここまでがお前の罠に引っかからないようにするための話な。

> 「(優れた)製品コードにテストコードが混在するのは良くない設計だ」とでも言うだろうか。
あぁ、そのとおりだ。何か言いたいことがあるならどうぞ
0066デフォルトの名無しさん2017/01/21(土) 21:01:47.67 ID:gnjAlXGF
sqliteみたいな例外はあるけど一般的にはそこまで書かない、全てのコードに対してsqlite並みにテストコード書いてたらプロジェクト終わらんよな
0067デフォルトの名無しさん2017/01/21(土) 21:22:40.22 ID:ij3ZsOnR
>> 「(優れた)製品コードにテストコードが混在するのは良くない設計だ」とでも言うだろうか。
>あぁ、そのとおりだ。何か言いたいことがあるならどうぞ

俺は、テストコードが混在するかどうかが設計の良し悪しに関係するとは思わんが、
問題はこんな単純なことですら「良い設計」の定義が一致しないということ。

そのへん曖昧なまま「privateメソッドをテストしようとするのは設計が悪い」と主張しても、
証明になってないという突っ込みする奴はいるかもしれないが、それ以上反論は
しようがないわな。
0068デフォルトの名無しさん2017/01/21(土) 22:36:34.80 ID:sMDuy5hJ
>>66
> sqliteみたいな例外はあるけど一般的にはそこまで書かない、全てのコードに対してsqlite並みにテストコード書いてたらプロジェクト終わらんよな

だから十分にテストされているライブラリやフレームワークを使い。
なるべくコードを書かないようにするのが良いぞ

自分のプロジェクト専用の処理は、自分でテストするしか無い。
しかし、その中で汎用の処理を見つけ出して、そこを外出することで
自分がテストする量を減らすことができる。

そうやってきたら、俺はpublic関数で10行前後、
private関数なんか更に短くなってしまって。

だから言うんだprivate関数をテストしたいと思ったら
設計が悪いだけだってこと。
0069デフォルトの名無しさん2017/01/21(土) 22:37:51.39 ID:gnjAlXGF
>>68
それは汎用ライブラリーを作らない人の立場での話だな。
0070デフォルトの名無しさん2017/01/21(土) 22:40:50.50 ID:sMDuy5hJ
>>67
> 問題はこんな単純なことですら「良い設計」の定義が一致しないということ。

俺は良い設計の定義の話なんかしてないんだが?

お前が思い込んでるんじゃないか。
「世の中に出ている製品」=「良い設計」だと
お前はそう言いたいんだろう?

俺が言ったのは「製品コードだからって良い設計ということにはならない」と
言うこととと「悪い設計」の話だけなんだがちゃんと理解できてないのか?
そういやprivate関数をテストしたくなったらそれは「悪い設計」とも言ったな。
0071デフォルトの名無しさん2017/01/21(土) 22:41:52.89 ID:sMDuy5hJ
>>69
> それは汎用ライブラリーを作らない人の立場での話だな。

汎用ライブラリを作る人の立場の君に聞きたい。
世の中でよく使われている汎用ライブラリで
sqlite並みにテストコードを書いてないライブラリはどれだ?
0072デフォルトの名無しさん2017/01/21(土) 22:55:22.41 ID:gnjAlXGF
>>71
一杯あるとおもうけど、それを聞いてどうすんだ?
0073デフォルトの名無しさん2017/01/21(土) 23:08:11.88 ID:sMDuy5hJ
>>72
どうするんだと言われてもね。

よくテストされてる汎用ライブラリを使いましょうという
当たり前のことしか言わないよ。
0074デフォルトの名無しさん2017/01/21(土) 23:12:54.46 ID:gnjAlXGF
えっ、話を逸らしただけ?
0075デフォルトの名無しさん2017/01/21(土) 23:16:13.67 ID:sMDuy5hJ
>>74
話をそらしたのはお前じゃね?
俺は>>68でちゃんと会話をしている。

それに対するお前のレスは中身が何もない。
中身が何もないお前にこれ以上何をいえと?

俺は話を>>68に戻しただけ。
わからないならここに>>68の内容を
コピペしてやっても良いんだぜ?
0076デフォルトの名無しさん2017/01/21(土) 23:21:02.28 ID:gnjAlXGF
>>75
ああ、そういうことか、sqliteがどんなテストコード書いてるか見たらprivateをpublicにするとか言えないと思うんだけど、すまんねその前提で言ってたわ
0077デフォルトの名無しさん2017/01/21(土) 23:23:43.91 ID:sMDuy5hJ
みんなsqliteのテストコード見なくていいぞw
どうせこいつが言ってるだけのことだから。
0078デフォルトの名無しさん2017/01/21(土) 23:36:56.46 ID:gnjAlXGF
まあ見なくて良いよ。普通のプロジェクトにとっては間違いなく過剰だから。
本体のソースコードの行数が122.9Kのところテストのコードとスクリプト含めて91596.1Kらしいから。
ちなみに内部でassertも大量に書いてる。
0079デフォルトの名無しさん2017/01/21(土) 23:41:58.25 ID:sMDuy5hJ
それが今までの話、
privateメソッドをテストしたくなったら
設計が悪いって話と何の関係があるのかな?
0080デフォルトの名無しさん2017/01/21(土) 23:43:42.51 ID:ij3ZsOnR
>>70

だから、定義してないから真偽定まらんと言ってるのだが。

>>59の主張を要約するとこうだな。

1. privateメソッドをテストしようと思ったら設計が良くない
2. テストできるようにするには2種類の方法がある
 a. 設計を見直してpublicにする
 b. 設計を見直さずにpublicにする
3. bではなくaにすべき

1.や3.に反論しようと思ったら設計が良い/まずいの定義に踏み込まざるを得ない。
0081デフォルトの名無しさん2017/01/21(土) 23:59:42.25 ID:gnjAlXGF
他人に使われるものを作ってるんだったら必要ないものまでpublicにする(外部に公開する)のは良くないよ。
なのでaもbもどっちもダメ
0082デフォルトの名無しさん2017/01/22(日) 01:41:32.45 ID:etjPL+qg
>>81
他人ってどういう意味?
その文脈で何故他人が出てくるの?

もしかしてpublicメソッドの話をしているのに、
一般用語のパブリック(大衆の、公共の、公衆の)と間違えちゃった?
だとしたら恥ずかしいね。
0083デフォルトの名無しさん2017/01/22(日) 04:45:25.75 ID:77/TNfJH
>>82
何故他人が出てきたらいけないの?
あなたは自分しか使わないものしか作らないの?
0084デフォルトの名無しさん2017/01/22(日) 05:34:13.73 ID:etjPL+qg
>>83
もしかして図星だった?
質問にちゃんと答えようね

もしかしてpublicメソッドの話をしているのに、
人間に対して使う用語ののパブリック(大衆の、公共の、公衆の)と間違えちゃった?
0085デフォルトの名無しさん2017/01/22(日) 05:37:05.25 ID:bK3k81d3
>>80
publicにしなくてもテストできるやろ
0086デフォルトの名無しさん2017/01/22(日) 07:00:17.67 ID:gigvK4EO
>>84
いや、間違えてないけど?
0087デフォルトの名無しさん2017/01/22(日) 07:12:24.26 ID:gigvK4EO
逆に聞きたいんだが、使う人を考えてクラス設計するのがそんなに不自然か?
意味不明な解釈してると決め付けるぐらいに
0088デフォルトの名無しさん2017/01/22(日) 07:13:16.92 ID:etjPL+qg
じゃあ自分しか使わないものは
全部privateにするわけね。

自分っていうのは人間の話ね。
0089デフォルトの名無しさん2017/01/22(日) 07:17:40.52 ID:gigvK4EO
>>88
自分しかつかわないなら好きにすればいいんじゃない?それこそ全部publicでも誰も文句言わない
0090デフォルトの名無しさん2017/01/24(火) 12:54:18.38 ID:QA0ZcG3O
自分しか使わないからprivateって、なんてクソな設計なんだろうw
0091デフォルトの名無しさん2017/01/24(火) 20:35:15.30 ID:dMWZcDP0
むかしオブジェクト指向システムの設計ってスレで
将棋の例を出して暴れてたやつにそっくりだなw
0092デフォルトの名無しさん2017/01/24(火) 21:30:19.03 ID:8U3NWpZ6
むしろ自分しか使わないならpublicでええやん
0093デフォルトの名無しさん2017/02/06(月) 23:15:46.42 ID:Z4T16Vvy
設計的な公開/非公開はpublic/privateで分ける
人に対しての公開/非公開はスコープで分ける
0094デフォルトの名無しさん2017/02/07(火) 08:52:53.46 ID:SRenyBWg
>>93
それって逆でもいいんじゃね?
0095デフォルトの名無しさん2017/02/07(火) 08:59:32.21 ID:ppv+uzEt
開発者が俺とお前の2人ならそれでも良いかもな
0096デフォルトの名無しさん2017/02/08(水) 01:47:58.35 ID:oZ8qLhDf
>>4

どれ、宿題を出しといてやるよ

動物が「バカ」だったときには「4」を返す
という仕様を実装漏れしていました。
なぜ漏れていることに気づけなかったんでしょうか?

あなたの実装漏れを知った顧客は、あなたの報告するカバレッジが100%であることに何の意味もないことを知り、あなたの報告に疑いを持つようになりました(ちゃんちゃん)
0097デフォルトの名無しさん2017/02/08(水) 03:00:48.24 ID:nBuIwUQ3
>>4じゃないけどさ
カバレッジ100%にしても実装漏れは検出できないって当たり前でしょ…
0098デフォルトの名無しさん2017/02/08(水) 03:33:50.20 ID:EqksEKaR
>>96
じゃあお前への宿題な

他の自動車に後ろから追突されたときはエアバッグは意味が無いことを知りました。
エアバッグによる安全性に意味が無いことを知り、あなたは安全装置をすべて外しました
そしてあなたはエアバッグで助かる事故で死にました(ちゃんちゃん)
0099デフォルトの名無しさん2017/02/08(水) 03:38:50.66 ID:EqksEKaR
馬鹿・・・カバレッジが100%ということはバグがないということだ
普通・・・カバレッジが100%ということはすべての行を実行する程度のテストはしているということだ。


馬鹿は銀の弾丸があると思っている。
馬鹿はカバレッジを完璧じゃないと言おうとしているつもりが
実は馬鹿のほうこそが過大評価している。

自分の間違った考え(カバレッジ100%は完璧)を自分でそれは間違いだって
ツッコミを入れているだけである。マッチポンプ
0100デフォルトの名無しさん2017/02/08(水) 03:39:18.59 ID:nBuIwUQ3
出題しろよ
0101デフォルトの名無しさん2017/02/08(水) 04:48:48.06 ID:q7Bk+Pyw
たかがC0のカバレッジ100%を特別なことだと思ってるバカって、>>4のことだよな?
0102デフォルトの名無しさん2017/02/08(水) 07:54:35.87 ID:oZ8qLhDf
>>98
>>99

なんだ。答えられないのか。おまえクビなw
0103デフォルトの名無しさん2017/02/08(水) 08:23:37.62 ID:J/owSyuZ
>>4の話でLookupTableクラスを分離するというのが「良い設計変更」だとして、じゃあそれを
使用するクラスの内部クラスにしたらその設計は良いままなのか、あるいは悪くなった
ことになるのか、って疑問はあるな。
0104デフォルトの名無しさん2017/02/08(水) 09:34:33.51 ID:3ajnzt+4
>>97
動物が増えてもテスト不要と言っちゃってる >>4 に言えよ
0105デフォルトの名無しさん2017/02/08(水) 10:58:26.85 ID:WP/XTf2I
>>4
> 動物が増えたら?などということを考える必要はない。
はたして、そうだろうか

> data = {人: 2, 犬: 4, 猿: 4, キジ: 2, 猫: 4}
"馬: 3"の追加が必要なのに、それを忘れていた場合にどうするんでしょうね

> テストはどうする? ・・・答えは "不要" だ。
残念、追加し忘れを見逃しましたね

> 元の設計のテストというのはデータが増えれば対応するテストを
> 増やすだけという単純作業
をやってれば、バグを検出できたのに

> なぜならばLookupTableのテストはすでに書いているからだ。
LootupTableのテストは書いていても、data定義(初期化)行はテストできてないね
0106デフォルトの名無しさん2017/02/08(水) 22:49:03.07 ID:EqksEKaR
>>105

> をやってれば、バグを検出できたのに
残念。それを忘れたらバグは検出できませんね
0107デフォルトの名無しさん2017/02/08(水) 23:29:11.39 ID:b6dR+iVQ
くだらないこと言ってないでコード書けってよく言われてるんだろうな。
0108デフォルトの名無しさん2017/02/09(木) 00:22:21.28 ID:lnTHGhne
>>106
この場合は忘れてもカバレッジが教えてくれるだけマシだったんじゃない?コードの見やすさは知らんけど
0109デフォルトの名無しさん2017/02/09(木) 06:51:39.40 ID:IOSaScxB
>>106
テスト設計しないんですか?
0110デフォルトの名無しさん2017/02/09(木) 13:02:15.28 ID:dfCX7ZDm
>>106
テストが不要だということの反論に対して、テストを忘れたらバグを検出できないとか言われても困惑するのみ
0111デフォルトの名無しさん2017/02/09(木) 17:06:47.27 ID:EPpoXydB
> data = {人: 2, 犬: 4, 猿: 4, キジ: 2, 猫: 4}
こんな増えてくと予想できるリストなんかは外部ファイルにしとけよ
後は必要なら勝手にファイルに追加してねって責任を誰かに丸投げできれば重畳
テストもそいつに丸投げできる
0112デフォルトの名無しさん2017/02/09(木) 21:32:56.16 ID:l61bzEJu
テストしにくいコードを書くのがおかしい。
0113デフォルトの名無しさん2017/02/09(木) 21:39:55.38 ID:UTxumv29
残念ながら世間ではおかしいことがまかり通っててそれを修正する必要がある。
0114デフォルトの名無しさん2017/02/09(木) 22:37:41.43 ID:V+qaSj6I
テストし易い部分のコードなんて誰でも書ける
0115デフォルトの名無しさん2017/02/10(金) 00:43:43.40 ID:/WxwB06L
>>114
矛盾
0116デフォルトの名無しさん2017/02/10(金) 14:03:12.42 ID:0nwBBEN6
コードを選ぶようなテストフレームワークが悪い
0117デフォルトの名無しさん2017/02/10(金) 19:11:46.63 ID:+HewTgrG
じゃあ作ろっか
0118デフォルトの名無しさん2017/02/15(水) 20:12:18.71 ID:rWNVJqHz
>>115
矛盾というかジレンマですな。
0119デフォルトの名無しさん2017/02/17(金) 01:13:32.33 ID:ZnfoQYBi
要件や設計に書いてあることをただ満たせばいいのに、
何だテストしにくいコードって。
0120デフォルトの名無しさん2017/02/17(金) 01:34:44.39 ID:EzDq9nSn
>>119
自動テストができないコード
自動テストをやろうとしたら組合せ爆発を起こして
時間がかかりすぎるコードだよ
0121デフォルトの名無しさん2017/02/17(金) 04:11:34.18 ID:cVLy1vhF
>>119
ばーか
0122デフォルトの名無しさん2017/02/17(金) 08:05:23.30 ID:LsFaYFdt
>>119みたいなマがいるから困る

後々の工程や運用段階でバグが見つかっても
困るのはオレじゃないから、とか考えてるんだろうな
0123デフォルトの名無しさん2017/02/17(金) 10:14:12.44 ID:rxbbpEDv
>>119 はいきなりシステムテストレベルを行う人間なんだろうね。

それだと小さいバグ、作り上の問題に気づかない。
0124デフォルトの名無しさん2017/02/22(水) 13:30:52.81 ID:nFPUHBlJ
>>120
組み合わせ爆発は、自動テストが原因じゃないよね。
逆に組み合わせ多数でマニュアルだと時間がかかりすぎて繰り返し実行できないなら、
自動テスト化を考えたほうが良い。
0125デフォルトの名無しさん2017/02/22(水) 20:23:22.44 ID:Ameqiwj8
自動テスト使って開発したこと無いだろお前
組み合わせが多過ぎるなら組み合わせが減るようにバラすのが先だわ
0126デフォルトの名無しさん2017/02/23(木) 10:38:26.31 ID:5OVH7aZj
>>125
全組み合わせだと1億通りなのを、オールペア法や直交表で100通りくらいまでに減らすのは基本
さらにその100通りをマニュアルで実行すると時間がかかるのなら、自動化すべき
ということだよ

組み合わせ爆発は、自動テストが原因じゃない

とか、こんな説明書くの疲れるわー
0127デフォルトの名無しさん2017/02/23(木) 14:42:20.90 ID:iUfvCfTM
やっぱり分かってねえ…
テスト技法の前に設計を何とかしろ
0128デフォルトの名無しさん2017/02/23(木) 14:59:39.53 ID:5OVH7aZj
>>127
あのねぇ・・・
俺は>>120の内容が間違ってると言いたいのだよ・・・
糞設計が原因のテスト困難性の話なんかしてないわ・・・
0129デフォルトの名無しさん2017/02/23(木) 15:11:55.49 ID:sZtROie8
>>128
ほっとけよ、どうせprivateをpublicにするとか言ってた奴だろ
相手を解ってない事にして見下したいだけのやつだよ
0130デフォルトの名無しさん2017/02/23(木) 18:15:47.32 ID:eyTAmQSH
今時、1億通りぐらいで自動化できないとか、どれだけヘッポコなんだろw
0131デフォルトの名無しさん2017/02/23(木) 20:44:47.41 ID:4lIYYkyp
ぼこぼこにされた>>119が噛み付いて回るスレをお楽しみください
0132デフォルトの名無しさん2017/02/25(土) 11:41:05.47 ID:7KoBIFTE
どうした?力技でテストすればいいんじゃないのか?w
0133デフォルトの名無しさん2017/04/01(土) 03:45:16.63 ID:I0+wrTCp
お前らGUIは自動テストしてんの?
0134デフォルトの名無しさん2017/04/01(土) 11:09:14.09 ID:tny4BO7D
>>133
最低限
0135デフォルトの名無しさん2017/04/01(土) 16:27:50.44 ID:Hg380gii
>>133
現状人の見た目でしか判断できないのは仕方ないとして、(表示されている写真の人物が最盛期の西条秀樹に間違いないとか)
GUI の状態取得関数やプロパティなんかで得られる情報ならその情報を確認できたらそれが表示できているとしてテストを組んでる。
例えばあるテキストボックスの文字色が赤というテストなら文字色プロパティが赤になっているのを確認するとか。

GUI ライブラリ自体はテストされているという前提なのでそのバグに遭遇しない限りは問題ないはず。
(稀によく遭遇するけどテスト過程で原因は判りやすいから GUI ライブラリ側に報告もできるしこちらも回避はできる)

GUI の表示ライブラリそのものを作ってるとしたらまた話は別だけど。頑張って死んでくれ。

ところで、テストコードを自動で書いてくれる便利ツール、おまえらなら何か知ってるんだろ? 教えてくれ。言語や手段は問わない。ヒントになればいい。
0136デフォルトの名無しさん2017/04/09(日) 02:20:28.91 ID:BJMv2zza
>>108
テスト不要だ(キリッ 君はこれに答えろよカス
0137デフォルトの名無しさん2017/04/09(日) 08:57:33.00 ID:Jztab8MH
実装コードの複雑度の客観的判定のお供に
SonarQube

設計のおすすめ書
組み込みソフトウェア開発のためのオブジェクト志向モデリング

あなたの書いたメソッドはテスト以前に単一機能の原則にマッチしていますか?テストが困難という事は設計が(ry
0138デフォルトの名無しさん2017/04/17(月) 08:55:18.58 ID:R62eo4r3
>>136
なんか人違いしてる気がするがテスト不要といってる奴と別人だよ。

>data = {人: 2, 犬: 4, 猿: 4, キジ: 2, 猫: 4}
とする設計より一つずつifで書いた方がテスト忘れてもカバレッジが教えてくれるから(コードの見やすさは別として)マシだったんじゃない?って意味だよ
0139デフォルトの名無しさん2017/04/22(土) 15:10:55.24 ID:+6/27O61
自分の管理下にない外部サービスへのログインなどの処理を行うライブラリのテストを行いたいんだけれども, ログインパスワードとかの情報ってどうやって被テスト対象に渡すべき?
0140デフォルトの名無しさん2017/04/22(土) 15:11:12.35 ID:+6/27O61
age忘れ
0141デフォルトの名無しさん2017/04/22(土) 15:22:45.81 ID:fNu+0xzW
>>138
どちらもカバレッジで教えてくれる。

1つのコード、1つのテストで、カバレッジを100%にするのも
同じ処理を複雑に書いて
100のコード、100のテストでカバレッジを100%にするのも
カバレッジ自体は同じだ。何も違いはない。


ただ、後者は面倒ってだけ。
書くものが増えれば増えるほど、ミスも増えるし
読むものも増える
0142デフォルトの名無しさん2017/04/22(土) 15:27:46.13 ID:fNu+0xzW
>>139
外部サービスがログイン機能を正しく実装しているかっていうのは
外部サービスがテストをするべき所で、あんたがテストするところじゃない。

あんたがテストするならば、その外部サービスに対して
想定通りのパラメータを正しく送ったかどうかをテストする。

この時、実際には外部サービスは使わない。外部サービスのふりした
何か(モック)を代わりに使う。
0143デフォルトの名無しさん2017/04/22(土) 16:01:54.72 ID:+6/27O61
>>142
やっぱりモックか・・・・・・
ありがとう
0144デフォルトの名無しさん2017/04/22(土) 18:03:53.80 ID:NysYFg8M
>>141
だから
>data = {人: 2, 犬: 4, 猿: 4, キジ: 2, 猫: 4}
という設計だと猪:4というのを追加したあとテスト忘れてもカバレッジ変わらないでしょ
ifだったらカバレッジ下がる。それだけの話だよ。
0145デフォルトの名無しさん2017/04/22(土) 18:12:37.60 ID:fNu+0xzW
>>144
なんでカバレッジが変わる必要があるのかわからんのだが?

あんたは猪4が追加されたらカバレッジが減ってほしいと思ってるわけだよね?
それは追加した猪4に対するテストコードを書くべきだって考えてるからだよね?

では、このコードの時、追加した猪4に対するテストはどうなるわけさ?
それ以外のテストはすでに書いてあるという前提なので、
追加した猪4だけのテストはどうなるのかを答えて。

そのあとそのテストをやる意味はどれくらいあるかって話をするからさ
テストを書く時間(将来的にはメンテする時間)にだってコストは掛かるんだぜ?
0146デフォルトの名無しさん2017/04/22(土) 18:14:57.22 ID:NysYFg8M
>>141
そもそも、一つのテストでカバレッジ100%になったとしても、入力による結果が100種類あるなら100個テスト書かなければテストの意味がないというのは理解してる?
0147デフォルトの名無しさん2017/04/22(土) 18:17:51.06 ID:fNu+0xzW
>>146
例えば、atoiの場合、結果は32bitCPUの場合で
4294967296種類(半分だっけ?)あるけど、
その場合のテストの数は?
0148デフォルトの名無しさん2017/04/22(土) 18:38:08.34 ID:NysYFg8M
>>147
そういう場合俺なら仕様を読んで、正数、負数、返す値の最小値、最大値付近とオーバーした場合、数字以外を含む、空文字、空白を付けた場合などのパターンを書くね。

心配ならintの最小値から最大値までを変換後、文字列に逆変換して文字列に戻したものが一致するかどうかのテストも書くかもね
0149デフォルトの名無しさん2017/04/22(土) 18:38:24.70 ID:+5rvIbLJ
>>147
横からだけど、atoi の場合は基本はそうだよ
でもそんなのやりきれないから境界値とか工夫するのが普通。

猪の件はどういう主張なの?

assert( numberOfFeet(人) == 2 )
assert( numberOfFeet(猿) == 4 )
assert( numberOfFeet(猫) == 4 )
assert( numberOfFeet(猪) == 4 )

みたいに増やす以外に良い方法があるってこと?
0150デフォルトの名無しさん2017/04/22(土) 18:44:04.84 ID:fNu+0xzW
>>149
やりきれないとやりきれるの境目はどこ?
100個? 1000個? 1万個?
やれるなら、やれるところまでやるべきだって話なんだよね?


俺はテストする価値が無いなら、テストしない。
テストを減らすために、猪を増やした所で
テストする価値がないコードになるようにする
0151デフォルトの名無しさん2017/04/22(土) 18:45:03.59 ID:NysYFg8M
カバレッジ100%を目的にテスト書くんじゃなくて仕様を満たしているかを確認するためにテスト書くんだよ。
そんな考えだからintの数値の範囲のみテストするような発想になるんだ。
0152デフォルトの名無しさん2017/04/22(土) 18:45:14.22 ID:fNu+0xzW
>>149
> みたいに増やす以外に良い方法があるってこと?
ある。ずっと上の方に書いたはずだがね
0153デフォルトの名無しさん2017/04/22(土) 18:46:19.44 ID:fNu+0xzW
>>151
そんな当たり前のことを言われても・・・

仕様を満たしているかを確認する時の
テストの数を減らせるように
コードを工夫するって話をしてるのに

一歩前にもどるなよw
0154デフォルトの名無しさん2017/04/22(土) 18:48:30.81 ID:NysYFg8M
>>153
猪渡したら4を返すという仕様が追加されてもテスト不要って言ってるんじゃ無かったの
0155デフォルトの名無しさん2017/04/22(土) 18:51:23.30 ID:IUEn1/Ee
>>153
横からだけどそれはおかしいなぁ
テストって設計書から作成するもんでその数がコードの書き方で増減するのは基本的にはおかしい
0156デフォルトの名無しさん2017/04/22(土) 18:53:59.52 ID:fNu+0xzW
>>154
境界値はテストするが、その間は
テストする価値がないからテストを書かないんだろ?

猪渡したら4を返すという仕様であっても、

工夫(仕様や処理を互換性がある別の形に変更)することで
テストを書く価値がないコード(猪を追加する前のテストコードだけで十分)に
することができる。

境界値のような特異なデータである猪を
境界値の間のような無害なデータにすることで
テストする価値がなくなり、テストが不要になる。
0157デフォルトの名無しさん2017/04/22(土) 18:58:04.29 ID:fNu+0xzW
>>155
全然おかしくない。

設計書にコードに記述されていることに全てが書かれていれば
その理屈は正しいかもしれないが、実際には設計書には
コードに書かれていることの一部分しか書かれていないから。

つまり設計書に書かれていない部分に対するテストの数は増減する
0158デフォルトの名無しさん2017/04/22(土) 18:58:29.29 ID:NysYFg8M
>>156
仕様は猪を渡したら4を返す筈が実装を間違えて1と返ってくるバグ仕込んだ場合テストコードの追加無しに検出出来るの?
0159デフォルトの名無しさん2017/04/22(土) 19:09:08.07 ID:fNu+0xzW
>>158
できる。

あとはテストする価値があるかどうかって話になって
俺はテストする価値が無いと思うだろうからテストは書かない。

あんたは境界値の間の値のような、
17を入れたら289が返ってくるはずが実装を間違えて
300と返ってくるバグを仕込んだ場合のテストコードを書くといいさ。
0160デフォルトの名無しさん2017/04/22(土) 19:18:21.00 ID:NysYFg8M
>>159
じゃあどうやるんだよってのが皆の疑問だと思うんだが。

猪が境界値の間の値という主張もどうかと思うが、
場合によっては間のテストも書くと >>148 に書いたよ
0161デフォルトの名無しさん2017/04/22(土) 19:39:48.14 ID:NysYFg8M
例えば仕様が動物の名前を与えたら足の数を返す
という曖昧なものであれば猪のテストは追加しないかもしれない。
しかし実際にそんな仕様のコードを書くのは不可能なので、仕様が粗雑ならテストコードも粗雑になるのは必然

仕様がとある動物データ内で定義されている足の数が返る
というのであればその動物データを読み込んでデータと関数の返す値が一致するかをテストするだろう。

同様に仕様に猪を与えたら4を返すとあればそういうテストを書くのが当たり前
0162デフォルトの名無しさん2017/04/22(土) 19:55:16.77 ID:M051jVFH
>>155
テストの目的によってちげーよばか
0163デフォルトの名無しさん2017/04/22(土) 20:09:40.40 ID:fNu+0xzW
>>161
> 同様に仕様に猪を与えたら4を返すとあればそういうテストを書くのが当たり前

お前の提唱するシステム開発では、
仕様書を作る人は、全ての動物の足の数を仕様書として書く間抜けで
その仕様書に則って開発する人は、何の疑いもなく書かれている通りにテストを書くのだろう?
素人が仕様書を書いて、考える頭がないやつが開発する。
コストがかかるのはそのためだ。


境界値の間のテストを書きたいなら書けばいいさ?

var data = {"人": 2, "猿":2, "猫": 4, "猪": 4}
assert(data["猪"] == 4) というテストに価値があると思うならな
0164デフォルトの名無しさん2017/04/22(土) 20:11:19.43 ID:fNu+0xzW
訂正w

var data = {"人": 2, "猿":4, "猫": 4, "猪": 4}
0165デフォルトの名無しさん2017/04/22(土) 20:19:28.83 ID:NysYFg8M
>>163
全ての動物の足の数が必要とは誰も言ってないんだけど?
0166デフォルトの名無しさん2017/04/22(土) 20:30:59.51 ID:2QNaIclJ
さすがにこの粒度でテストするのは意味ないだろw
二重メンテになるだけだわw
0167デフォルトの名無しさん2017/04/22(土) 20:33:10.67 ID:MfkHEDxl
君たち何のためにテストしてるの?何を保証したいの?
0168デフォルトの名無しさん2017/04/22(土) 20:47:55.86 ID:IUEn1/Ee
>>167
要求仕様書だよね
0169デフォルトの名無しさん2017/04/22(土) 21:05:33.81 ID:MfkHEDxl
>>168
君は覚えたての言葉を垂れ流すのをやめなさい
0170デフォルトの名無しさん2017/04/22(土) 22:37:37.83 ID:x8LqAlRP
{"人": 2} これを、{"入": 2} 書いてもエラーにならないから、確かめる必要がある。
特にハイフンなどは、何種類もあるから危険。
全角空白・半角空白も

テストせずに、こういうので、ずっと出来ないって言ってる、香具師が多い
0171デフォルトの名無しさん2017/04/23(日) 00:17:24.66 ID:CU9TQkMq
カバレッジ100%にする事しか頭にない実装してからテストコード書くようなやつなんだろうね。
0172デフォルトの名無しさん2017/04/23(日) 00:34:16.87 ID:CU9TQkMq
>>167
自分が決めたもしくは他人に決められた仕様を満たしている事の確認のためにテストを書いてる。
けっして全てのコードパスを通すためではないよ。
ID:fNu+0xzW がテストでどんなバリデーション書くのか興味あるね。
0173デフォルトの名無しさん2017/04/23(日) 05:12:33.31 ID:vNB+3Vut
>>166
そう思う人は産業用ロボットなど高信頼性が求められるソフトウェア開発には参加しないでくださいね。
そういう手抜きで人が死ぬから。
0174デフォルトの名無しさん2017/04/23(日) 12:27:10.81 ID:T4INally
>>166
そういうことだよねw

こういうコードがあって
var data = {"人": 2, "猿":2, "猫": 4, "猪": 4}

テストで
var expected = {"人": 2, "猿":2, "猫": 4, "猪": 4}
assertDeep(data, expected)
こういうテストを書くことに、どれだけの意味があるかって話だよ


今までそういう話じゃなかったって?
そうだね。今まではnumberOfFeetの話だった。
しかし、numberOfFeetの部分は他のdataですでにテスト済みとする。

そうすれば残り部分は、dataだけになる。だからdataが変わったのであれば
そのdataの変化分だけをテストすれば良い。それがこのテスト

>>172
> 自分が決めたもしくは他人に決められた仕様を満たしている事の確認のためにテストを書いてる。
他人もしくは自分が、境界値以外のどうでもいい値の仕様を書いたとしたらその値をテストすんの?
「(全ての)数値が二乗される関数であることと」と書いてあったら、
すべての数値をテストすんの?
0175デフォルトの名無しさん2017/04/23(日) 12:41:28.59 ID:vNB+3Vut
>>174
コード上の境界値だけテストすれば十分だと思ってるの?
こわいなあ
0176デフォルトの名無しさん2017/04/23(日) 12:49:38.51 ID:dTVl8E15
どれだけテストすれば良いかは決まっているものでも、個人の感覚によるものでもありません
ターゲットとするソフトの目的や性質を踏まえて設計するものです
これをテスト仕様設計と言います
0177デフォルトの名無しさん2017/04/23(日) 13:00:51.62 ID:HqNmAyPa
でもやっぱり仕様書で猪4が追加されてる以上テストはやりたいね
0178デフォルトの名無しさん2017/04/23(日) 13:01:58.16 ID:T4INally
>>177

> こういうコードがあって
> var data = {"人": 2, "猿":2, "猫": 4, "猪": 4}
>
> テストで
> var expected = {"人": 2, "猿":2, "猫": 4, "猪": 4}
> assertDeep(data, expected)
> こういうテストを書くことに、どれだけの意味があるかって話だよ
0179デフォルトの名無しさん2017/04/23(日) 13:06:57.77 ID:zjYzndui
テストするならせめてもう一つ外側とかかな。
例えば履物が合計何個必要かとかを計算する関数のテストとかね。

get_sum_feet( animal_list )
のテストとか。
0180デフォルトの名無しさん2017/04/23(日) 13:07:29.19 ID:T4INally
>>176
> これをテスト仕様設計と言います

そのテスト仕様設計書に、
「(全ての)数値が二乗される関数であることと」と書いてあったり、
いかにも境界値でも、その前後でも、なんでもない普通の値が書いてあったら
どうするの?って話。

書いた本人は実装がわからない(この時点では実装が存在しない)から、
それが重要な値だって思ってテスト仕様書に書いたかもしれないが、
実装によっては重要でも何でもない値にできるかもしれないだろう?

実装を考えずに無駄のないテスト仕様書を書くのは不可能なんだよ。
0181デフォルトの名無しさん2017/04/23(日) 13:10:00.47 ID:HqNmAyPa
単体はともかく結合あたりじゃ
仕様書を満たすテストが主でしょ?
0182デフォルトの名無しさん2017/04/23(日) 13:13:22.57 ID:T4INally
>>179
なかなか興味深い例をだすねw

では

numberOfFeet(animal)
get_sum_feet( animal_list )

の2つがあって,numberOfFeetのテストが猪の対応も含めてちゃんと書かれているとする。
この時、get_sum_feetのanimal_listに猪が含まれている場合のテストは必要ですか?不要ですか?
ただし実装の内容は決めません。



(俺がこの例で本当に言いたいことは、これは実装を決めなければ
 テストが必要かどうかがわからない例であるという事ねw)
0183デフォルトの名無しさん2017/04/23(日) 13:22:31.14 ID:HqNmAyPa
>>182
だから単体はともかく結合じゃいるよ
0184デフォルトの名無しさん2017/04/23(日) 13:25:47.82 ID:T4INally
>>181
つまり仕様書から作るテストは正しく動くためのテストではなく、
単に仕様書から思いついたテスト(足りない物はあるし、意味のないものもある)
って話だよね?

では残りのテストはどこで作成するのか?
そして意味のないテストを、これからもやり続けたいのか?
という話が残る。
0185デフォルトの名無しさん2017/04/23(日) 13:26:23.30 ID:T4INally
>>183
それでは、単体で行えるテストを
結合でもやる理由は何?
0186デフォルトの名無しさん2017/04/23(日) 13:36:28.74 ID:zjYzndui
なるほど、そもそもテストの目的が違うわけだ。
品質を上げたいというよりかは
SIer から文句を言われないためのテストが必要だと。
それなら言われた通りに頭使わずに、
くだらないコードでもなんでもテストするのが正しいと思うよ。
0187デフォルトの名無しさん2017/04/23(日) 14:06:33.31 ID:vNB+3Vut
>>180
せめてブラックボックステストとホワイトボックステストぐらい理解してから出直してきな
0188デフォルトの名無しさん2017/04/23(日) 14:09:16.82 ID:HqNmAyPa
>>185
結合はお客さんが出してきた仕様書通りに動いてますよっていう保証だから
(会社によってはシステムテストだったり粒度は異なるが)
猪4って仕様があったならそれがPGにとってくだらんテストであるかどうかなんて関係ない
0189デフォルトの名無しさん2017/04/23(日) 14:51:57.18 ID:T4INally
>>187
ブラックボックステストはコストがかかる割に
正確なテストが出来ないという話でOK?
0190デフォルトの名無しさん2017/04/23(日) 15:11:21.31 ID:T4INally
ここまでのまとめ

numberOfFeet(animal)
get_sum_feet( animal_list )

は仕様書で決めることで、仕様書も、テスト仕様書もお客さんが決めることである。
当然ながらテスト仕様書の量に応じてお客さんがテスト作業費を支払う義務がある。

ということらしい
0191デフォルトの名無しさん2017/04/23(日) 15:12:20.42 ID:T4INally
ちょっと訂正

は仕様書で決めることで、仕様書も、テスト仕様書もお客さんが作成するものである。
0192デフォルトの名無しさん2017/04/23(日) 16:02:32.57 ID:CU9TQkMq
>>174
全ての数値が二乗される関数であること の意味が解らんが
リストで渡した数値全てが2乗されて返る関数ってことかな?
テストしない理由がないな
0193デフォルトの名無しさん2017/04/23(日) 16:12:02.25 ID:T4INally
うむ、なるほど理解した。

1. 仕様書を満たすテストコード
2. テスト仕様書を満たすテストコード
この2つは別のものなのだ

例えば、仕様書には「すべての数値を二乗する処理」と書くだろう。
2を4に、3を9に、4を16に、・・・・にする処理。と全ての値を書くバカはいない。

そしてテスト仕様書には「2を4にする」などと特定の値のテストを書くだろう
2を4に、3を9に、4を16に、・・・・になることを確認する。と全ての値を書くバカはいないし
すべての値のテストを行うことと書くバカもいない(テストの量に応じてコストが大きく変わるため)

つまり、仕様書の内容とテスト仕様書の内容は一致しないということだ。
仕様を決めたからと言って、それがそのままテスト仕様書に書く内容になるわけではないのだ。
そこが勘違いしている点の一つだな。

テスト仕様書は別途書き起こさないといけない。そのテスト仕様書を書くのは客の仕事だ。
そしてテスト仕様書を満たすテストを行う(テストコードを書く場合もある)のは開発会社だが、
その費用はテスト仕様書の量に応じて客に請求するものとなる。
(俺の会社ではテスト仕様書の量が膨大でも固定の金額でテストするというのならどうぞ勝手にしてくれw)

テスト仕様書に書かれているテストは作業量をもらっている以上やるべきことだが、
テスト仕様書に書いてあるテストをパスしていたとしても、
仕様書の内容を満たしていなければ客は怒るだろう。それが仕様なのだから。

問題はここだな。テスト仕様書を満たすテストコードではなく仕様書を満たすテストコード。
仕様書には書かれているが、テスト仕様書には書かれていない値 に対するテストだ。

テスト仕様書には書かれていないのだから、その部分の仕様を満たすためのテストはどう書いてもよかろう?
話を戻すとこの仕様書のみに書かれている内容に対するテストの量は実装によって変わってくるという話だったわけだ。
0194デフォルトの名無しさん2017/04/23(日) 16:14:39.12 ID:T4INally
>>192
「引数で渡した数値が二乗されて帰ってくる関数」って意味だよ。

あとは>>193で書いたとおり。
仕様書の内容が、そのままテスト仕様書になるわけではない。
0195デフォルトの名無しさん2017/04/23(日) 16:16:02.47 ID:CU9TQkMq
>>174
あと、せっかく他人が >>149
assert( numberOfFeet(人) == 2 )
assert( numberOfFeet(猿) == 4 )
assert( numberOfFeet(猫) == 4 )
assert( numberOfFeet(猪) == 4 )
とnumberOfFeetの実装方法に依らないテストコードを書いてくれてるのに、
なぜ馬鹿みたいなテストコードを自分で書いて自分で批判してんの?
0196デフォルトの名無しさん2017/04/23(日) 16:17:28.41 ID:T4INally
補足

「引数で渡した数値が二乗されて帰ってくる関数」って意味だよ。
だから、テストするしないは別として引数として取りうる数値の数(32bitで2^32乗個)
だけテストケースは存在しうる。
その全てをテストしないでしょ?

だから仕様書に書かれた内容が、テスト仕様書の内容になるわけじゃない。

どっかの誰かは仕様書に猪が追加されたら、
テスト仕様書にも追加すべきだって言っているようだがね。
0197デフォルトの名無しさん2017/04/23(日) 16:19:01.35 ID:T4INally
>>195
それは実装方法には依らないが
テストする価値が殆ど無いコストがかかるだけの
テストコードだって話をしてる
0198デフォルトの名無しさん2017/04/23(日) 16:29:27.79 ID:CU9TQkMq
>>196
つまりお前は仕様として明示的に追加された”猪”が数値に置き換えると明示的に指定もされていない一つの数と重要度は同等であるという主張なわけな。
まぁ、それはそれでめんどくさいので置いておくとして、
numberOfFeet(猪)
が仕様からはずれた4を返す以外の結果が発生する場合に正しくテストがエラーとなるテストコードはどう書くんだい?仕様が追加されたときにテスト追加しなくても検出出来るって言ったよね?
0199デフォルトの名無しさん2017/04/23(日) 16:43:56.84 ID:T4INally
>>198
人の話をちゃんと聞け

まずテストする価値が殆どないコストがかかるだけのテストコードを
書く意味があるのか?って話をしている。

> numberOfFeet(猪)が仕様からはずれた4を返す以外の結果が発生する場合に
> 正しくテストがエラーとなるテストコードはどう書くんだい?

こう書けばいい

 実装コード(の一部)
 var data = {"人": 2, "猿":2, "猫": 4, "猪": 6}

 テストコード
 var expected = {"人": 2, "猿":2, "猫": 4, "猪": 4}
 assertDeep(data, expected)

実装コードが間違ってる場合に正しくエラーになるぞ。

これはdataの内容だけしかテストしてないと言いたくなるかもしれないが、
それ以外の部分はダミーのdataを使って正しくテストしている(という前提)
変わるのはdataの内容だけなのだから、テストコードを書くとしたらdataの内容のみのテストだけでいい。

そして、こんなテストコードを書くのにどれだけの価値があるのか?って話
だってdataのデータを修正して、テストコードのexpectedにそれをコピペするだけだろ?
追加するたびに、二箇所にある同じデータを同じようにメンテするだけの作業

俺はそんなのをやる意味がないと思っているから、dataの内容以外のテストだけで十分
だからdataの内容が変わるだけならば、新たにテストを追加する必要はないと言っている。
0200デフォルトの名無しさん2017/04/23(日) 16:55:48.18 ID:CU9TQkMq
>>199
え?テスト追加してるじゃん?追加なしに検出出来るんじゃなかったの?

仕様から導き出される実装がとても簡単だったから仕様を満たしているか確認するテストは面倒なので勝手に省きます! って事か。
お前は何の為にテスト書いてんの?
0201デフォルトの名無しさん2017/04/24(月) 03:20:47.13 ID:m96WuHeG
>>199

> テストコード
> var expected = {"人": 2, "猿":2, "猫": 4, "猪": 4}
> assertDeep(data, expected)

テストコード書く能力ひくすぎだろこれ
0202デフォルトの名無しさん2017/04/24(月) 03:30:19.46 ID:wWNCwbd3
>>201
しかもそれ、numberOfFeetが仕様を満たしているかかくに
0203デフォルトの名無しさん2017/04/24(月) 03:34:16.30 ID:wWNCwbd3
ミスで途中送信

numberOfFeetが仕様通りか確認するテストでは無いんだよなぁ。自分で無意味なテストを書いて無意味だからやらない!とか何のギャグなんだかね。
0204デフォルトの名無しさん2017/04/24(月) 10:54:24.52 ID:yA6lKxwP
>> var data = {"人": 2, "猿":2, "猫": 4, "猪": 4}
みたいなハードコーディングするということは、要求される場合の数が非常に限定されている場合で、
その場合は全てテストする必要がある。

要求される場合の数が多い場合は、ハードコーディングなんかはしないわけで、上の議論は不毛な議論と言える。
新着レスの表示
レスを投稿する