プログラマーなら単体テスト(UT)も実装しよう

このエントリーをはてなブックマークに追加
1仕様書無しさん
おまえらちゃんとテスト作ってる?

テストメソッドの名前
どういう単位でテスト実装してるか
テストのためにアクセス指定子変える派とリフレクション使う派とどっちが多いのとか
2仕様書無しさん:2013/04/07(日) 14:56:52.55
関連しそうなスレ


テストを軽視する者ども
http://kohada.2ch.net/test/read.cgi/prog/1214650160/
テストデータに「test」とか「てst」とかもうやめろ
http://kohada.2ch.net/test/read.cgi/prog/1127447938/


テストしにくいコードをテストする方法教えて下さい
http://toro.2ch.net/test/read.cgi/tech/1334408391/
テストを書いてからリファクタリングなんてのは幻想
http://toro.2ch.net/test/read.cgi/tech/1349191466/
【TDD】テスト駆動開発【TestFirst】
http://toro.2ch.net/test/read.cgi/tech/1284899172/
3仕様書無しさん:2013/04/07(日) 14:59:45.81
最近糞コードのテスト書いてるから辛い
TDDやれとまでは言わんが、せめてテストできるレベルの実装位できるようになって欲しい
つかnUnitの使い方すら理解できないクズはプログラマー辞めちまえって思う
4仕様書無しさん:2013/04/07(日) 16:36:34.11
>>4
クソスレ立てんな
5仕様書無しさん:2013/04/07(日) 18:30:57.36
>>5
お前の指図は受けない
6仕様書無しさん:2013/04/07(日) 19:58:46.14
>>6
誰に向かって口聞いてんだ
7仕様書無しさん:2013/04/07(日) 20:30:06.31
    _, ,_  パーン
 ( ‘д‘)
  ⊂彡☆))Д´) >>7
8仕様書無しさん:2013/04/07(日) 23:19:05.98
うちの職場にもJUnitとかの使い方が分からないレベルの奴ごろごろいるから悲しいわ
9仕様書無しさん:2013/04/08(月) 11:21:49.79
>>7
自分を叩いてどうする
10仕様書無しさん:2013/04/08(月) 12:23:42.10
>>10
空気読めないのかお前は
11仕様書無しさん:2013/04/08(月) 14:42:11.01
>>11
うるせーハゲ
12仕様書無しさん:2013/04/08(月) 20:05:34.93
>>12
おままえがなー
13仕様書無しさん:2013/04/08(月) 20:21:54.44
僕の魔チンポが暴発しそうです
14仕様書無しさん:2013/04/08(月) 23:40:41.00
>>14
お前だけが希望だ
15仕様書無しさん:2013/04/08(月) 23:55:56.51
なんだよ、このグダグダな流れは....

>>15
きちんと責任とれよ!!
16仕様書無しさん:2013/04/09(火) 01:45:13.14
どうせおまえらUTとか作ってないだろ
17仕様書無しさん:2013/04/09(火) 01:55:35.99
うちの職場のオッサン、JUnitの使い方分からないし単体テストとか実装してすらいないのに
テスト終わったとか嘘言って糞コードコミットしてくるからマジしねばいいのに
18仕様書無しさん:2013/04/09(火) 19:22:32.19
教えてやれ
19仕様書無しさん:2013/04/10(水) 07:26:41.47
リフレクション使ってテスト書くくらいならパッケージプライベートとかアクセスできるようにしておくかなー
20仕様書無しさん:2013/04/10(水) 12:58:26.25
F言語でもできんのかよふざけんな
21仕様書無しさん:2013/04/10(水) 23:41:37.13
メイン言語はJavaだけど、JUnitでテスト書くようになってからprivateメソッドはあんまり書かなくなったな
パッケージプライベートやprotectedを良く使う
メソッド単位でテスト書いたほうが楽だし工数も減るし、リファクタリングとかも捗る気がする

こういうやり方って実際どうなの?publicメソッドのテストケースしか書かないのが普通?
ちゃんとしたテストコードってのを見た事が無くて、どうやるのがいいかいまだによくわからない
22仕様書無しさん:2013/04/11(木) 00:53:21.86
Javaだとどうなんだろうね。
Objective-CもGoも、やろうと思えばプライベートメソッド呼べるしな。
23仕様書無しさん:2013/04/11(木) 13:55:26.00
>>21
ここを参照。

「プライベートメソッドのユニットテストは書かないもの?」
http://qa.atmarkit.co.jp/q/2784

なお、最初の回答のt_wadaが誰なのか知らなければ、和田卓人でググるとテストに関連する記事とか読める。
24仕様書無しさん:2013/04/12(金) 00:47:38.27
プライベートかどうかは関係ない。

テストの目的を考えれば、間違いやすいならば
テストを書くということは明らかにわかるはず。
25仕様書無しさん:2013/04/12(金) 01:20:57.49
関係ないことないでしょ。
privateに対するテストがあると、リファクタリング邪魔になったり、実装詳細を変更したらテストもメンテする必要がでてきたりする。
基本はpublicに対するテストだけでいいと思う。
26仕様書無しさん:2013/04/12(金) 01:29:46.71
それはpublicに対するテストの話だからそうなる。
テストはユニットテストだけではない。

privateのテストがあるとリファクタリングのじゃまになったり
実装詳細を変更した時にメンテをする必要があるが、
それはprivateのテストをしない理由ではない。

privateのテストはリファクタリングのじゃまになったり
実装詳細を変更した時にメンテをする必要があるが、
そのデメリットよりもメリットが上回ればやる勝ちはある。

なお、publicでもリファクタリングじゃまになったり
メンテをする必要があったりする。
なぜならば、インターフェースを変える修正もあるからだ。
27仕様書無しさん:2013/04/12(金) 01:33:25.21
クラスの粒度がやっぱり大きすぎるのかなぁと感じる
プライベートメソッドを別のクラスのパブリックメソッドにしてしまえばこういう悩みはなくなりそう
でもクラス分けすぎると古い脳の人が混乱するからって怒り始めるし、むずかしいなぁ
28仕様書無しさん:2013/04/12(金) 01:37:54.98
ユニットテストは仕様に対するテストのことであって、
リファクタリング(外から見た形は変えずに内部の改善をする)を
行うためためだけに存在するわけじゃない。
29仕様書無しさん:2013/04/12(金) 01:42:28.00
つーか、ハードウェアの自己診断テストみたいに考えればいいんだよ。
あれはハードウェア内部のテスト。つまりprivateテストみたいなもん。

ハードウェアの自己診断テストでどんなテストを行なっているかは知らんが、
外からは(LEDや音などで)テスト結果がわかる。

それと同じでpublicのself_test()メソッドを呼び出して、その中にテストコードを書く。
外部から見れば、self_test()が仕様通り(自己診断テストにtrueを返すか?)を確認するだけだし、
ハードウェア内部の自己診断テストは、自己が仕様通りかテストをすればいい。
30仕様書無しさん:2013/04/12(金) 01:49:21.27
publicのメソッドを実行すればprivateメソッドは内部で呼び出されるんだから
publicメソッドのテストだけをやればいいという考えなら、

それに対して、システムテスト、統合テストを行えば、
publicメソッドは呼び出されるんだから、ユニットテストはいらないんじゃね?
という考えも成り立つよなと言いたくなる。


テストはなるべく小さい粒度でやるべき。それは問題は小さい方で解決したほうが
コストがかからないから。このあたり前の理由がprivateメソッドのテストにも当てはまる。
粒度が大きすぎるなら、当然小さい粒度でやるべき。粒度が問題なのであって
それがクラス内部からしか使わないのであれば、それはテストすべきprivateメソッドということになる。
31仕様書無しさん:2013/04/12(金) 01:52:26.08
privateメソッドのテストはユニットテストじゃねーよというのであれば、
じゃあ「ユニットテスト」とは違う名前を付けないといけないねって話になるだけ。
ユニットテストをしないが、それはテストをしないという意味ではない

ユニットテストと違う名前、つけていいと思う。例えば自己診断テスト。
32仕様書無しさん:2013/04/12(金) 01:55:17.63
Javaマだけどパッケージプライベートにしてテスト書いてる
あと、そういう可視性をあげたフィールドやメソッドには、Guavaの@VisibleForTestingアノテーションとかつけたりしてる
33仕様書無しさん:2013/04/12(金) 01:57:49.54
あとTDDしてないけど、実装とリファクタリング平行しながらテストも書いてるから
パブリックメソッドだけに全ケース網羅できるようなテスト書くのはちょっとしんどいってのもある
クラスが大きすぎるんだろうけど、細かく分け辛い処理(名前が付け辛い処理)って、
業務系クラスだと結構多くて外に持ってくのしんどいのよね
34仕様書無しさん:2013/04/12(金) 02:00:47.05
>>32
それもありだとは思う。思うけど言語の機能に依存する。
privateメソッドを呼び出す機能が存在しないと使えない。

あと、privateのテストを行うモジュールとpublicのテストを行うモジュールは分けたほうがいいかもしれない。
publicのテストを行うモジュールはユニットテストの目的通り「外部から見た仕様をテストする」もの。

それに対してprivateのテストを行うモジュールは、内部で使われている一機能をテストするもの。目的が違う。
あとprivateメソッドのテストはメソッド全てに対して行う必要はない。publicでも結局は一緒なのだけど、
テストを行うメリットとデメリットを考え、テストを行うメリットがある場合だけテストすればいい。
全部やってて時間が足りるのならやってもいいけど。
35仕様書無しさん:2013/04/12(金) 02:10:36.52
網羅するためにPublicメソッドのテストケースを複雑かつ多種用意するくらいなら、
もっと小さい単位のメソッドで網羅して、パブリックメソッドはパスだけテストするほうがコストはかからないね。
リファクタリングには使えないけど、ぶっちゃけちゃんと作れてたら早々大きなリファクタリングは発生しない。
36仕様書無しさん:2013/04/12(金) 02:12:23.54
別にリファクタリングに使えないってこともないんだ。
privateメソッドの仕様が変わらず、
内部だけを修正することもある。

長いprivateメソッドを修正し、そのコードの一部を関数化し、
それを汎用モジュールのpublicメソッドにする。
なんて話だってあるだろう。
37仕様書無しさん:2013/04/12(金) 02:14:38.43
最初からちゃんと作るというのは、実際には不可能な話で、
だって成長するわけで、誰だって昔の自分はだめなもんだろう?

重要なのは最初から正解を出すことではなく、
どうやって間違ったものを正しくするまでの
道順を考えることだろう。
38仕様書無しさん:2013/04/12(金) 15:13:10.34
>>34
> privateメソッドを呼び出す機能が存在しないと使えない。

ん?
そもそもprivateメソッドをテストできるかどうかが、言語依存(あるいは処理系依存)じゃないの?

概念としての「プライベートなクラス」に括り出すのなら、C++でも似たようなことはできるよね。
ライブラリとしてまとめて、exportしなければいい。
39仕様書無しさん:2013/04/12(金) 15:18:25.87
>>30
> それに対して、システムテスト、統合テストを行えば、
> publicメソッドは呼び出されるんだから、ユニットテストはいらないんじゃね?
> という考えも成り立つよなと言いたくなる。

いや、ならないよ。

まず、ユニットテストと結合テストでは行う時期が違う。
バグは早く見つけられれば見つけるほど、修正コストが小さくて済む。

次に、結合テストはたいていの場合ブラックボックステストで行い、要件ベースでテストケースを作成する。
ユニットテストはホワイトボックステストで、コードベース、あるいは、プログラマの意図でテストケースを作成する。
40仕様書無しさん:2013/04/12(金) 23:13:45.88
>>39
だからなに?理由になってないんだが。

時期が違ったからって、統合テストで問題なければ
publicメソッドのテストは不要だろ?

要件ベースでテストした時、
コードにバグがあればテストに通らないだろ?

統合テストやればユニットテスト不要じゃん。
41仕様書無しさん:2013/04/13(土) 00:04:39.06
>>40
何が言いたいかって、単体テストの時にprivateメソッドをやるかどうかという問題と、単体テストを省略して結合テストをやればいいだろという問題は、全く別問題であるという至極普通なことなんだけど。
全く別問題であるがゆえに、仮に単体テスト時にprivateメソッドのテストしなくてもいいと主張したとしても、それが結合テストをするから単体テストは不要ということにはならない。

というか、privateメソッドのテストをすべきどうかは、単体テストの枠組み内で考慮すべき問題なのに、結合テストを持ち出すお前の方が何を言いたいのかさっぱりわからんわ。
42仕様書無しさん:2013/04/13(土) 00:15:33.61
>>41
「結合テストをするからといって、単体テストは不要といういう事にはならない。」って俺が言ってることなんだけど?

それと同じで、

「publicテストをするからといって、privateテストは不要という事にはならない。」も成り立つって言ってんの。
43仕様書無しさん:2013/04/13(土) 00:40:01.17
>>42
話が微妙に変わってる。もう一回>>30を読み直してみろ。
単体テストでpublicのテストをすればprivateが呼び出されるからprivateのテストは不要と言うのであれば、結合テストをすればpublicメソッドが呼び出されるから単体テストは不要とも言える、というのがお前の主張。

で、そうは言えないというのが俺の主張。理由は前述の通り。
44仕様書無しさん:2013/04/13(土) 00:43:49.67
それに、そもそも単体テストではpublicメソッドのみをテストするのが良いという理由は、privateメソッドはテスト中に呼び出されるから不要だからではない。
45仕様書無しさん:2013/04/13(土) 00:58:28.55
>>43
お前の言う理由が理由になってないという話。

例えば行うテストを行う時期が違うことは
privateメソッドをテストしない理由にはならない。
46仕様書無しさん:2013/04/13(土) 01:00:26.41
単体テストでpublicメソッドのみをテストするのはいいが
それはprivateメソッドをテストしない理由にはならない。

privateメソッドをテストするとデメリットが有るが
そのデメリットよりも、テストをするメリットが高ければ
テストをした方がいい。

要するにテストするかしないかは、そのコードはテストをしなければ
バグが出やすいかどうかってだけ。
47仕様書無しさん:2013/04/13(土) 01:11:14.55
ここも妄想癖が強い人の一人相撲
48仕様書無しさん:2013/04/13(土) 01:50:03.00
相撲は一人じゃ出来ません。
相手がいるんだよw
49仕様書無しさん:2013/04/13(土) 01:52:51.47
>>45
テストを行う時期が違うからprivateメソッドのテストをしないとは一言も言ってないが。
privateメソッドのテストをしないというなら、publicメソッドも結合テストでテストされるからしなくていいとも言える、という論理は成り立たないと言ってるんだが。

さらに言えば、俺がすべきでは無いと思ってるのは、privateメソッドをprivateメソッドのままでテストすべきでは無いということ。
更に言うなら、君のprivateメソッドをテストする価値があるならやるべきという立場も否定はしない。俺はやらないが。

俺が否定してるのは、君が俺の立場が間違っているという論拠がおかしいといただそれだけのことだよ。
50仕様書無しさん:2013/04/13(土) 02:03:08.85
> という論理は成り立たないと言ってるんだが。
お前皮肉もわからんの?
publicメソッド経由でテストしてるから不要と抜かしている馬鹿に対して
そんなのは理由にならないと皮肉を言ってるんだが?

> privateメソッドをprivateメソッドのままでテストすべきでは無いということ。

じゃあどうするか?

1.privateメソッドを呼び出すだけのpublicメソッドを作る
2.privateメソッド+別の処理を行うpublicメソッドを作る(または利用する)

1はジョークとしか思えない、2はなぜ複雑にしてテストをしないといけないのか?

テストはシンプルな状態でやるべき。
そしてなるべく早く、privateメソッドが出来た時点でやるべきだ。
51仕様書無しさん:2013/04/13(土) 02:04:40.92
privateメソッドをテストしないの理由を聞いていてわかるのは

privateメソッドは外部から呼び出せないから
テスト出ないだけ。
その言い訳として、あーだーこーだいってる。
52仕様書無しさん:2013/04/13(土) 02:18:20.62
話が通じないわー。
53仕様書無しさん:2013/04/13(土) 02:22:00.56
それは俺のセリフ。

俺がprivateメソッドテストをしない理由はないといって
それに反論してないだろ?
それで話は終わりじゃないか。
54仕様書無しさん:2013/04/13(土) 02:32:19.53
>>53
>>25でしない方がいい理由を書いてるんだが。
君はそれを大した根拠もなく、それは理由にならないとしか言えてないよ。
55仕様書無しさん:2013/04/13(土) 02:52:05.36
>>54
いや、だからテストをメンテする必要があるから何なの?って話。
メンテスレばいいだけでしょ?

それにそもそもの話がある。

Q. 本当にprivateメソッドのテストをメンテする必要があるか?
A. privateメソッドの仕様が変わらないなら、privateメソッドのテストをメンテする必要はない。

Q. publicメソッドのテストはメンテしなくてもいいのか?
A. publicメソッドの仕様が変わるなら、メンテする必要はある。

publicでもprivateでも仕様が変わればテストをメンテする必要があるし、
仕様が変わらないのならメンテの必要はないんだよ。
56仕様書無しさん:2013/04/13(土) 02:56:36.89
ねぇ、private関数を作るときに、private関数単体でテストしないの?

別にユニットテストとか書くとかいう話じゃないよ。
ステップ実行とかでいいからさ、
関数単位でテストしないの?
57仕様書無しさん:2013/04/13(土) 03:05:12.20
>>55
工数が増えるからといってそれが何なの、と言ってるようにしか聞こえません。
工数が増えるのは問題ですね。
58仕様書無しさん:2013/04/13(土) 03:05:54.92
>>56
だから、しないって。
59仕様書無しさん:2013/04/13(土) 03:14:26.11
>>57
テストのための工数を嫌がってるようにしか見えないが?
60仕様書無しさん:2013/04/13(土) 03:19:37.40
>>55のQ & Aに対する反論がないなw
61仕様書無しさん:2013/04/13(土) 08:47:51.60
結論は、t_wadaは馬鹿であるってことでいいのかな。
62仕様書無しさん:2013/04/13(土) 08:48:34.60
結論は、t_wadaは馬鹿であるってことでいいのかな。
63仕様書無しさん:2013/04/13(土) 09:13:14.88
どう見ても馬鹿は>>30
64仕様書無しさん:2013/04/13(土) 09:54:19.63
と罵ることしか出来ないのであった。ああ無能。
65仕様書無しさん:2013/04/13(土) 10:20:01.84
リファクタリング中に、テストが失敗しないことで正しさを担保できるのに、privateメソッドのテストのせいでテストが失敗し、カオスになる。
publicA()の為にprivateA()を作り、privateA()のテストを書いた。publicB()でもprivateA()をつかいたいけど、ちょっと引数を変更しなきゃ。おっと、テストが失敗しまくるぜ。

でも大丈夫。。。俺らには無限の時間があるし。テスト工数をけちっちゃけちっちゃ駄目だよね。
66仕様書無しさん:2013/04/13(土) 10:31:21.90
そもそも論で言うなら、privateメソッドを外部からの呼べる言語の方が少ない訳だから、
privateメソッドをテストすべしというのは最初からおかしいんだが。
67仕様書無しさん:2013/04/13(土) 13:29:59.16
それは理由にならないよ
68仕様書無しさん:2013/04/13(土) 13:35:23.76
なんで理由にならないんだ?
privateメソッドのみならず、クロージャとか無名メソッドとか、普通は外部から呼べないよね。
呼べないんだからそれはそのまま単体ではテスト出来ませんねってなるのが普通。
69仕様書無しさん:2013/04/13(土) 13:42:35.02
privateメソッドは実装詳細なんだから、そのクラスを実装中に引数が変わったり実現内容が変わったりは
よくあること。
publicだって変わることがあるというが、それはprivateと頻度が違う。
そんなにころころpublicのI/Fが変わるとしたら、それは実装のやり方が間違ってるよ。
70仕様書無しさん:2013/04/13(土) 15:03:07.45
>>65
意味不明。

> リファクタリング中に、テストが失敗しないことで正しさを担保できるのに、privateメソッドのテストのせいでテストが失敗し、カオスになる。
それはprivateかどうかではなく、
テストしているメソッドの仕様を変えたからだろ

publicメソッドでも同じ事あるわ。
リファクタリングのうち単純な「メソッド名の変更」と呼ばれるものであっても
テストを修正しないとテストは失敗する。

リファクタリングとはね、システムの挙動を変えない変更であって
クラス単体の内部の修正ではないんだよ。
71仕様書無しさん:2013/04/13(土) 15:10:58.19
>>69
> そんなにころころpublicのI/Fが変わるとしたら、それは実装のやり方が間違ってるよ。

確かにpublicがワールドワイドでpublicならそうだろうね。
世界中で使われているライブラリのpublicメソッドがころころ変わるわけがない。

だがプロジェクトローカルなpublicメソッドだったらどう?
単にひとつの画面をMVCで作ろうととなって、Modelのメソッドは仕方なく
publicにしないといけないが、そのメソッドを読んでいるのは特定の画面のみ。
プロジェクトの開発者が少なければ、ころころ変えても問題無いだろ。
72仕様書無しさん:2013/04/13(土) 15:24:12.44
>>70
それこそ意味不明だわ。
既存のprivateメソッドで、より適切な名称を思いついて変えようとする。
その程度のことでさえ、そのprivateメソッドのテストがあるとテストが失敗してしまう。

リファクタリングのことわかってないんじゃないの?
73仕様書無しさん:2013/04/13(土) 15:26:39.02
>>71
だから変更される頻度が違うって言ってるじゃん。
実装詳細は、公開インターフェイスに比べて変更されやすい。
その都度テストメソッドの修正が必要だとしたら、それこそ改善の足かせになってるよね。
74仕様書無しさん:2013/04/13(土) 17:04:09.02
>>72
既存のpublicメソッドで、より適切な名称を思いついて変えようとする。
その程度のことでさえ、そのpublicメソッドのテストがあるとテストが失敗してしまう。


>>73
publicが変更されにくいってのはわかるが
privateが変更されやすいとは限らないだろ。
特に関数にするようなものは変更されにくい。

ロジックは書き換えるが、
メソッドは変更されにくいんだよ。
75仕様書無しさん:2013/04/13(土) 17:05:16.99
×メソッドは変更されにくいんだよ。
○メソッドのインターフェースは変更されにくいんだよ。

たとえprivateであってもな。
76仕様書無しさん:2013/04/13(土) 17:14:30.97
>>74
クラス内部の構造を改善するリファクタリングしないの?
publicメソッドもprivateメソッド変更されにくいって、それでどうやってリファクタリングするわけ?

publicメソッドの仕様を変えれば、それを使っている所もテストコードも変更するのは当然。
でも、それはprivateメソッドのテストを書くべきかどうかとは関係ないよね。
77仕様書無しさん:2013/04/13(土) 17:15:00.08
なんか言ってることがループしてるな。

privateメソッドは(一般的に)テストをかけない。
→ テストがないから変更しやすい。
→ 変更しやすくするにはテストを書かない。
→ テストがないもの(書けないもの)は変更しやすい。
→ 変更しやすくするにはテストを書かない。
→ テストがないもの(書けないもの)は変更しやすい。
→ 変更しやすくするにはテストを書かない。
→ループ
78仕様書無しさん:2013/04/13(土) 17:19:53.91
>>75
君がそうだからってみんなそうであると決めないでよ。
実装詳細はその時の状況によって、容易に変更されうる。そして、通常は外部との結合は
無いのだから気軽に行える。その変更の正しさを担保するのがpublicメソッドのテスト群。

設計の基本は、高い凝集度と低い結合度だ。
本来必要ないのに、privateメソッドの結合度を高めてどうするんだって話だよ。
79仕様書無しさん:2013/04/13(土) 17:20:03.94
>>76
> クラス内部の構造を改善するリファクタリングしないの?
> publicメソッドもprivateメソッド変更されにくいって、それでどうやってリファクタリングするわけ?

リファクタリング=クラス内部の構造だけの修正じゃないぞ?
クラス構造そのものやメソッドのインターフェースを変えるリファクタリングもある。

インターフェースを変えるリファクタリング方法が存在するのだから
それをprivateメソッドにも同じように適用すればいいだけ。

リファクタリングをちゃんと知ってるのなら、privateメソッドも
リファクタリングできるってわかるはずなんだがな?


> publicメソッドの仕様を変えれば、それを使っている所もテストコードも変更するのは当然。
> でも、それはprivateメソッドのテストを書くべきかどうかとは関係ないよね。

だからそう言ってるだろ。

メソッドのテストを書くべきかどうかは、publicとprivateは関係ない。
メソッドの使用を変えれば、それを使ってるテストコードも変更するのは当然。
80仕様書無しさん:2013/04/13(土) 17:20:46.30
>>78
> 実装詳細はその時の状況によって、容易に変更されうる。

君がそうだからってみんなそうであると決めないでよ。

容易に変更されないメソッドもある
81仕様書無しさん:2013/04/13(土) 17:21:06.13
>>77
ループしてると思ってるのは気のせいだよ。
82仕様書無しさん:2013/04/13(土) 17:22:59.20
>>78
> 本来必要ないのに、privateメソッドの結合度を高めてどうするんだって話だよ。

なら結合度を高めなければいいだけ。

クラスにself_testってメソッドを作って、
テストの実行は、クラス自身にやらせれば、
外部からのインターフェースは変えずに
privateメソッドのテストを行える。
83仕様書無しさん:2013/04/13(土) 17:25:19.59
>>79
話が通じないわー。
84仕様書無しさん:2013/04/13(土) 17:25:40.44
>>83
お前がなw
85仕様書無しさん:2013/04/13(土) 17:26:54.99
結局のところメソッドのインターフェースの変更が
変わらなければテストは変えなくていいが、
インターフェースが変わればテストの変更も必要。

これはpublicやprivateは関係ないのに
結びつけようとしているのが間違いなんだよな。
86仕様書無しさん:2013/04/13(土) 17:27:29.22
>>82
そうしたら、今度はそのself_testの存在が、実装詳細の変更を阻害する要因になるってのが
わからないのかなー。
87仕様書無しさん:2013/04/13(土) 17:29:40.15
>>85
なんでprivateメソッドのテストが存在することが前提になってるんだよ。
俺は、そのテストがなければ自由に実装詳細を変えられるって話をしてるんだが。
88仕様書無しさん:2013/04/13(土) 17:30:09.81
>>86
阻害しないよ?

なぜなら、privateメソッドのインターフェースを
変更しなければ、テストの修正は不要だから。
89仕様書無しさん:2013/04/13(土) 17:30:51.92
テストがなければ、コードを書き換えても
テストに失敗しない!

全てのテストをなくそう!
90仕様書無しさん:2013/04/13(土) 17:32:11.69
>>88
privateメソッドを直接テストするコードの存在が、実装詳細の変更を阻害する要因になるってのが理解できないの?
91仕様書無しさん:2013/04/13(土) 17:32:32.68
なんですべてのprivateメソッドにテストコードを書くって
思い込んでるのさ?(笑)

一部の複雑なコードでいかにもテストが必要だってコードに対して
じゃあ、仕様変えないようにきっちり作ってテストしようか。
でも外部からは呼び出さないからprivateでいいよね。

って話だろうが。
92仕様書無しさん:2013/04/13(土) 17:34:02.18
>>90
> privateメソッドを直接テストするコードの存在が、実装詳細の変更を阻害する要因になるってのが理解できないの?

じゃあ、そのメソッドをpublicに変更しろよ!

そうすれば、テストコードあっても、実装詳細の変更を阻害する要因にならないって
お前の馬鹿な脳でも理解できるだろ?

それpublicメソッドが今回はたまたま外部から呼び出す必要がなかったから
privateだったってだけだ。
93仕様書無しさん:2013/04/13(土) 17:34:11.28
全然かみあってないなw
94仕様書無しさん:2013/04/13(土) 17:35:56.01
>>91
だから、そのprivateメソッドのテストの存在が、実装詳細の変更を阻害する要因になるってのが理解できないの?
その意味で、publicに対するテストとprivate対するテストでは事情が違うと言ってるのに。
95仕様書無しさん:2013/04/13(土) 17:36:33.23
> だから、そのprivateメソッドのテストの存在が、実装詳細の変更を阻害する要因になるってのが理解できないの?

お前が言っていた理由は全て否定されてる。
何度言っても、理由が書いてないものは
誰にも受け入れられない。
96仕様書無しさん:2013/04/13(土) 17:37:37.45
>>92
いきなり何を言い出すんだよ。
俺はprivateメソッドのテストの是非を語ってるんだが。
97仕様書無しさん:2013/04/13(土) 17:38:20.75
>>95
理由は書いただろ。
98仕様書無しさん:2013/04/13(土) 17:39:15.78
>>96
俺はテストが必要かどうかにpublicとprivateは関係ないと
言ってるから、何の問題もないが?
99仕様書無しさん:2013/04/13(土) 17:40:09.84
>>97
それ(>>92等)に対する反論がないじゃないか。

publicにしたらテストするのに、
それをprivateに戻したらテストしないって
おかしい話だろ。
100仕様書無しさん:2013/04/13(土) 17:40:55.53
めんどくせ。
>>98
>>25
101仕様書無しさん:2013/04/13(土) 17:42:09.64
privateに対するテストがあると、リファクタリング邪魔になったり、
実装詳細を変更したらテストもメンテする必要がでてきたりする。

その理由は、ここに書くには狭すぎる。
102仕様書無しさん:2013/04/13(土) 17:43:08.47
>>25は理由を書くように。

先に反論を書いておこう。

privateに対するテストがあっても、
リファクタリングのじゃまにならない場合や
実装詳細を変更してもテストをメンテする必要がない場合もある。
103仕様書無しさん:2013/04/13(土) 17:43:54.35
本人は理由だと思っていたものが
単なる意見だと言われるのは
見てて可哀想だなーw
104仕様書無しさん:2013/04/13(土) 17:44:09.25
>>99
全然おかしくないよ。
話が発散するからあえて書かなかったが、メソッドから意味のある一部分を取り出して
凝集度の高いクラスにするのは、リファクタリングのテクニックの一つで、最初から
そうしましょうと言うことだったら話はこじれなかった。
105仕様書無しさん:2013/04/13(土) 17:45:09.37
> 話が発散するからあえて書かなかったが、メソッドから意味のある一部分を取り出して
> 凝集度の高いクラスにするのは、リファクタリングのテクニックの一つで、最初から

じゃあ、メソッドから意味のある一部分を取り出して、
その部分にテストしてもいいじゃないか?
106仕様書無しさん:2013/04/13(土) 17:46:47.63
>>102
何の理由?
107仕様書無しさん:2013/04/13(土) 17:47:51.59
>>105
だからそれがprivateに対するテストだと、実装詳細の変更を阻害する要因になるってのが理解できないの?
108仕様書無しさん:2013/04/13(土) 17:48:36.79
>>106
リファクタリングの邪魔になる理由
実装詳細を変更したらテストもメンテする必要になる理由。

お前まさか、>>25にその理由が書いてあったと思ったの?

その理由を述べた所で、
それはpublicにも当てはまるねって
言い返されて終わりなんだがw
109仕様書無しさん:2013/04/13(土) 17:49:10.27
>>107
それで、実装詳細の変更を阻害する要因になる理由は?
その理由は、publicだとならないんだよね?
110仕様書無しさん:2013/04/13(土) 17:51:22.77
publicにあてはまることがprivateにもあてはまってしまうことこそが、実装詳細の変更を阻害す
要因になるってのが理解できないの?
111仕様書無しさん:2013/04/13(土) 18:04:44.62
というか、実装詳細が何なのかわかってないんじゃ
112仕様書無しさん:2013/04/13(土) 18:11:15.02
うん。
publicとprivateでは事情が違う。何故ならprivateは実装詳細だから。
これで話が通じない人と話すのは骨が折れる。
113仕様書無しさん:2013/04/13(土) 19:09:21.51
privateメソッドのテストしたところで、それによって品質が上がるわけじゃないし。
無駄な努力っちゃ無駄な努力だよね。
114仕様書無しさん:2013/04/13(土) 21:11:19.20
private テストする派の人は、ホワイトボックステストのテストケースを書くべきだと言ってるの?
しない派の人は多分、ホワイトボックステストを、自動テスト対象としてのテストケースとしては書かないといってるだけでしょ?
例えばアサーションなんかはテストケースではないが、テストと言えばテストだ。
テストケースではないホワイトボックステストで、しない派はこれをすべきでないとは言ってない。
デバッグ用のチェックコードを忍び込ませるなとも言ってない(かも知れない)。

ということ?
115仕様書無しさん:2013/04/13(土) 21:29:31.81
privateメソッドのテストは、テスト対象のクラスのOpen-Closed Principleの原則を破ってしまう。
よってprivateメソッドのテストをしてはならない。
116仕様書無しさん:2013/04/14(日) 02:43:58.18
自分は外部非公開メソッドのテスト書いちゃうほうだけど、
多分そういうメソッドが多くなるのは、クラスが大きすぎるのが原因なんだろうなーって思ってる

でも実務だと、抽象化しまくってかなり細かいクラスにわけちゃったりすると、
レガシー脳の奴がついてこれないどころか重複コード量産始めるから、難しい気もする
大抵はパッケージとか好き勝手に増やしたりも難しいし、あんまり細かい単位でクラス分け辛い
あとクラス外出してDIとかするのは、めんどくさいって言われそうだし

で、パブリックメソッドから分岐のある可能性のテストケース全部実装するくらいなら、
プライベートメソッドをパッケージプライベートにして、
メソッド単位でテストケース実装して動作確認するほうがいいかな、って感じに
テストを行った成果物として残せるし
117仕様書無しさん:2013/04/14(日) 07:59:22.35
Java脳w
118仕様書無しさん:2013/04/14(日) 09:35:59.49
>>116
抽象化しまくってってのがまた設計に失敗してる臭い
119仕様書無しさん:2013/04/14(日) 10:35:35.36
でも実際DIできるのに自前でnewする馬鹿いるんだよなぁ。
1メソッドに全機能詰め込む奴とか。
Java系マはピンキリ激しくて大抵キリ側に寄ってるから、PHPerと戦わせると良い勝負しそうなの多い。
120仕様書無しさん:2013/04/14(日) 10:36:42.69
privateなメソッドの単体テストがどうしても必要な状況って、メソッドの設計がおかしいんじゃね
121仕様書無しさん:2013/04/17(水) 18:12:17.46
だって金玉痒いんだもん
122仕様書無しさん:2013/04/18(木) 01:30:52.74
プライベートメソッドがいっぱいあるようなクラスは多分もうすこし細かい部品に分けたほうが再利用性は上がると思う
まぁプライベートなメソッドテストした方が楽な場合はそっちのテストにすればいいと思うよ
結局のところ、正しく動くかの確認を、いかにして簡単かつ確実に行えるかが、いちばんだいじな部分だし
123仕様書無しさん:2013/04/19(金) 12:50:20.96
リファクタリングでprivateメソッド作ったらテストも作んなきゃいけないのは間違ってる気がする
124仕様書無しさん:2013/04/20(土) 01:26:07.81
今日初めてMockツールを使って、どうやってMockを利用するのが楽になるかって考えてて気付いた。

判定処理、計算処理みたいなのを判定クラスとして外に出してあげると、プライベートメソッドを殆ど作らなくてよくなる。
判定クラスは値を設定して結果をテストするって感じにできるし、
publicメソッドになるから、先に挙がってるようなリファクタリングの影響も受けない。
テストの実装とても捗るし、TDDとかやりやすくなる。

さらに、元のクラスは、別クラスに外だしした判定処理をDIするような作りにする事ができ、
UTでは全部mockに置き替えてテストできるようになる。
正しく分岐するか、繰り返し処理が行えているか、などのテストに専念できるようになってこれまた捗る。

てことで、こういう感じな所にたどり着いた。
1. 判定処理や計算処理を行うロジッククラスを設ける(何のロジックか、でクラスを分ける感じ)
2. 分岐や繰り返して値をつめる、みたいな処理がメインのクラスでは、判定や計算を極力実装せず、全部委託する

テストのしやすい設計って、こういう感じに部品化していく事なんかな。
いままでもっと大きな塊のクラスに処理を纏めようとしてたから、プライベートなメソッドのテストしたくなってたのかも…。
125仕様書無しさん:2013/04/20(土) 01:28:37.82
publicメソッドを変更したらどうするんだ?
privateメソッドだって変更するんだろ?
変更しないのならprivateメソッドだって変更しないだろうし。
126仕様書無しさん:2013/04/20(土) 02:27:56.50
DAOとかentityを使ったクラスのテストってどうしてます?
自動テストするためには、対象テーブルにデータがないといけないので、
テストの時に、データをインサート→テスト→データを削除 とかやってますが、
正直面倒臭いですしどこまでやればいいのかわかりません。

あと、マスタ系はある前提でいいのかとか、
マスタ系もテストデータを挿入する必要があるのかとか、
データがバッティングしてはまずいので、
別スキーマを用意する必要があるのかとか。

また、テーブル変更の際に、エンティティだけの修正で済むのに、
テストデータが古い定義のままなので、
単体テスト動かそうとするとテストデータの修正が必要になったりだとか。

DBが絡んだ途端、JUnitのメリットが半減するような気がします。
127仕様書無しさん:2013/04/20(土) 10:58:21.78
そのテストに意味が無いと言うつもりはないが、
データベース使ったら単体にならないだろ?

それにテストしたい対象は何だ?
データベースなのか?
それとも自分が作った部分なのか?

テストは全ての部分に対してやる必要はない。
極限まで単純な機能にして、
そこに不具合が入り込む可能性が
少なくなったらやらなくてもいいんだよ。
128仕様書無しさん:2013/04/20(土) 11:34:16.05
>>127
データベースを操作するクラスなのに、正しくそれが行われるかどうかをテストしなくて単体テストって呼べるのか?

>>126
俺がやっている方法。
基本的なマスタは存在するのが前提としてテストコードを書く。
テスト用のデータベースは個人ごとに持つ。
テストはsetUpでトランザクションを開始し、tearDownでロールバックする。それで大丈夫なように、直接データベースを操作するクラスではコミットはしないようにする。
テストの前提となるデータの準備はコードでやる。
大量のデータが必要な場合は、CSVで準備しデータベースのロード機能を使う。ただしこの場合は、スキーマの変更があったときにCSVの修正が必要になる。

テスト用データベースを構築するスクリプトはバージョン管理する。
スキーマを変更するのも全てスクリプトで行い、そのコミットにはテストでロードするCSVファイルの変更も含める。

こうすればテスト用データベースはいつでもクリーンな状態なので、普通は誰かが使っているテスト用データベースをダンプして自分用のデータベースを作れば良い。
129仕様書無しさん:2013/04/20(土) 11:38:38.08
>>128
> データベースを操作するクラスなのに、正しくそれが行われるかどうかをテストしなくて単体テストって呼べるのか?

データベースを操作する部分は、実際にはライブラリだろ?
データベース操作ライブラリの作者であれば、
実際にデータベースを使ってテストしないといけないが、
そうではないのであれば、データベースを使わない。

クラス と データベース、2つのものが出てきてるのでこれは”単体”ではない。
つまり単体テストが目的なら、データベースの部分をモックに置き換えろって話。
130仕様書無しさん:2013/04/20(土) 11:45:45.29
>>129
例えば集計を実行するメソッドがあって、そのソースがデータベースだったとき、自分が実装した選択条件等が正しいかどうかはいつテストするんだ?
131仕様書無しさん:2013/04/20(土) 15:53:54.23
MVCで言うと、Mはデータベースと接続してテストする方がいいでしょ。
というか、繋げないと妥当性が検証できない場合が多いと思うんだが。
132仕様書無しさん:2013/04/20(土) 19:37:00.19
>>129
理想はそうだと思うけど、モックを作るのが無理な人の方が多いから、実際にDB操作を行うテストになるんだと思う
渡される値が何か、みたいなのを知る事ができない人は多い
133仕様書無しさん:2013/04/20(土) 20:39:28.30
まあ、DBが単なるデータストレージにしか過ぎない場合はmockでもいいけど、
大抵はビジネスロジックがクエリで表現されることが多い。その場合には、
単体テストでDBに繋げろってことだ。
134仕様書無しさん:2013/04/20(土) 22:55:48.06
ビジネスロジックのメソッド内からDAOのメソッドを呼ぶとするなら、
ビジネスロジックのメソッドの単体テストではDAOのモックを使い、
DAOのメソッドの単体テストではDBにアクセスするではダメ?
135仕様書無しさん:2013/04/20(土) 22:59:52.45
SQLがビジネスロジックなら、
SQLのテストを行えばいいのだよ。
アプリは不要。

RDMBSにつないで、SQL実行して
そのSQLが期待した通りの答えが帰ってくるか
テストすればいい
136仕様書無しさん:2013/04/20(土) 23:02:36.04
どうしてそうすぐに極論にはしるかね
137仕様書無しさん:2013/04/20(土) 23:04:39.15
え? そんだけ? それで?
138仕様書無しさん:2013/04/20(土) 23:05:10.18
俺は極論かどうかには興味が無い。
言っていることが正しいかどうかだけだ。
139仕様書無しさん:2013/04/20(土) 23:39:30.12
>>135
コードで動的にクエリを組み立てたりしないの?
140仕様書無しさん:2013/04/20(土) 23:43:25.30
>>134
だから、クエリそのものがビジネスロジックになる場合の話だよ。
そんなこと無いの?
141仕様書無しさん:2013/04/21(日) 02:36:56.71
>>139
条件を元に動的にクエリが正しく組み立てられるか。
簡単なテストだな。
142仕様書無しさん:2013/04/21(日) 02:37:54.23
>>140
その場合の単体テストは、
クエリのテストだよ。

クエリがビジネスロジックを満たしているか
調べればいいだけじゃない。

SQLとRDBMSがあればテストできる。
143仕様書無しさん:2013/04/21(日) 03:55:02.12
>>142
クエリが正しいかどうかを最も低コストに検証するのは、実際に動かしてみること。
なんでコードを動作させるのを頑なに拒むの?
144仕様書無しさん:2013/04/21(日) 09:21:16.30
結合テストでやればいいじゃん
145仕様書無しさん:2013/04/21(日) 09:28:55.86
>>144
なんでそこまで実行を遅延させるんだよ?
意味がわからん。
146仕様書無しさん:2013/04/21(日) 09:39:13.09
具体例を出してくれないと誰も判断できんわ。
147仕様書無しさん:2013/04/21(日) 10:55:25.86
なんの具体例?
148仕様書無しさん:2013/04/21(日) 11:43:33.15
>>143
だからデータベースに接続して、
そのクエリを流して、
想定通りのデータが帰ってくるか
テストをすればいいじゃん?
アプリ経由でクエリを流す必要はないよ。
149仕様書無しさん:2013/04/21(日) 12:24:16.20
それじゃアプリケーションのテストにならんがな
150仕様書無しさん:2013/04/21(日) 13:19:58.57
そのクエリはアプリケーションで使うんだろうが?
何を言ってるんだ?
151仕様書無しさん:2013/04/21(日) 13:59:59.26
きっちりかっちりやるなら単体テストとしてはそっち(DBはDB、アプリはアプリ)の方がいいとは思う
DBに依存したテストをやるのは単体というより結合だから、自動実行のために用意するのとはちょっと毛色が違う
ローカルで手動実行する結合してみてテストするための補助ツール的な物だと思う
クラスを作成するための支援としての単体テストや、自動テストとしてやるものとはちょっち違う感
まぁどっちが楽かはケースバイケースだと思うから、明確に線引く必要はないと思うけど
152仕様書無しさん:2013/04/21(日) 14:09:49.00
副作用を目的とするメソッドの単体テストは、何をどこまで確認すべきか。
153仕様書無しさん:2013/04/21(日) 14:20:12.41
>>148
例えばあるメソッドにたいして、条件によってクエリが何十パターンにもなる場合、いちいちクエリを出力して、データを投入してデータベースのツールで動作させて、結果を目視で確認したりするの?
何でそんなに手間も時間も間違う可能性もあるようなことするのかさっぱりわからん。
154仕様書無しさん:2013/04/21(日) 14:26:14.29
それに、データベースと接続するのを結合まで伸ばす人って、負荷テストはどこでやるの?
因みに俺の場合は、単体で正しく動くことが確認できたらすぐやるよ。
その結果いかんでは、実装の見直しが入るかもしれないから。
155仕様書無しさん:2013/04/21(日) 14:39:52.51
FWやORMが出力するレベルのModelやDAOしか必要なければ、別にDBに繋げなくても良い
156仕様書無しさん:2013/04/21(日) 14:40:33.86
ttp://d.hatena.ne.jp/cero-t/20111210/1323457069

レベル2から3に進めたあたりで世界が変わった気がする
確かに過剰コードはテストデータの準備に時間かけすぎてこれは効率悪いなって感じることが多かった
プライベートな処理の可視性をあげてテストを書くとかでケースは大幅に減らせるんだけど、それも少し違うかなって感じてた
でも、そもそもクラス設計時点でテストをしづらくしていた事が原因だった
157仕様書無しさん:2013/04/21(日) 14:49:30.96
>>154
むしろ実装に入ってからじゃ遅すぎる感もあるな
設計とかに影響が出るレベルの検証なんかは設計段階で実施してる
確認したい内容を試すだけの使い捨てコードをちゃちゃっと用意して問題としている部分が大丈夫か試す
設計と実装の線引き自体が環境や人によってまちまちで曖昧な表現だから、タイミングとしては同じことかもしれないけどな

んで、そういうのの動作確認のためにユニットテストツールをつかう事はあるけど(実行楽だし)、
それを自動実行するためのコードとしてコミットしたり、今後も保守したりは考えたくないな
検証は検証でそれで終わりで、確認がとれたらちゃんとしたちゃんとした実装を始める感じ
158仕様書無しさん:2013/04/21(日) 14:50:35.63
>>153
えとさあ、だったらのその問題はどうやって解決できるのさ?

クエリにビジネスロジックが入っているって話だよ?
クエリが何十パターンにもなるというなら、ビジネスロジックも
何十パターンもなると君はいってるわけだよ?

君は、条件で何十パターンにもなるようなもののテストを
どうやってるのさ? これはもはやクエリは関係ない話だ。
159仕様書無しさん:2013/04/21(日) 14:50:40.74
データベースに接続するタイミングをどこに持ってくるかはプロジェクトの性格によると思うよ。
俺は自社Webサービスを少数人でやってるけど、スキーマが結構変わるから実際にデータベースと
接続する自動ユニットテストが無いとやってけないからやってる。
160仕様書無しさん:2013/04/21(日) 14:51:48.47
>>154
> それに、データベースと接続するのを結合まで伸ばす人って、負荷テストはどこでやるの?

アプリが出来上がるまで待つのか?

アプリの一部、クエリがわかった時点でやればいいじゃないか。
161仕様書無しさん:2013/04/21(日) 14:54:45.25
>>158
問題って具体的に何?
何十パターンにもなるもののテスト方法なら、クエリが絡まない場合と同じだよ。
問題は、そのクエリが妥当なものかどうかを検証する方法で、それはデータベースと
接続して確認するのがいいってことなんだけど。
162仕様書無しさん:2013/04/21(日) 14:56:04.97
>>160
いやだから俺はそうしてるわけで、データベースと接続するのを結合まで伸ばす人たちは
どうしてるのかなって疑問。
163仕様書無しさん:2013/04/21(日) 15:01:13.33
>>162
データベースだけを使ってやるテストは単体テストだよ?
164仕様書無しさん:2013/04/21(日) 15:03:07.79
かみ合わない話の原因は、DBクエリがラップされてるか自前でSQL書いてるかの違いもあると思う。

個人的には、複雑なビジネスロジックをSQLで実装すること自体をなるだけ避けたい。
業務的な仕様変更に対する修正コストが大きくなるから、引継ぎとか考えると割とダルい。
パフォーマンスへの影響がどれくらいあるか次第だけど、
大きく影響しないと言い切れる部分であれば無理複雑なロジックをSQLで表現しないようにしてる。

単体の話題というよりは設計な気もするけど、まぁTDDなんかは設計の話だし、いいよね。
165仕様書無しさん:2013/04/21(日) 15:04:26.91
>>163
でも、データベースにアクセスするコードをデータベースと接続するのは結合テストなんでしょ?
166仕様書無しさん:2013/04/21(日) 16:25:31.28
>>165
普通の単体テストって

テストコード → テスト対象クラス

だよね?


同じように

テストコード → データベース

これも単体。
167仕様書無しさん:2013/04/21(日) 17:10:43.60
>>166
別にそれは否定しない。
つか、君、俺に何を言いたいの?
168仕様書無しさん:2013/04/21(日) 17:30:38.00
今の流れを纏めると、DBの動きはテスト対象外だからmockに置き換えるよ派と、
クラス内で作ったクエリが正しく動くかも一緒に検証するため、DB操作も含めたUTにするよ派の違い、ってとこかな?

前者は、DBにクエリを投げるクラスの単体なんだから、UTはクエリが想定どおりかをテストするべきだって主張で、
後者は、クエリにビジネスロジック絡んでるから、クエリ生成のあとDBの動作まで含めてUTツールで動作させたいって感じ。

以下私見
クラス単体テストって意味だと、DB部分はMock化すべきで、DBクエリが正しいかを検証するほうが正しいと思う。
なぜなら、DBクエリによるデータ操作結果をテストするのは、DBの動作を検証するDBの単体テストになるから、
言ってしまえばやるべき必要のないケース。テスト工数を嵩ませる要因になってしまうと思う。
内容にもよるけど、そこを頑張ると、テストデータの用意だったり改修に伴う影響だったりで、メンテが辛くなる重たいテストになってしまう。

本来DBに投げるクエリは命令文であって、処理を行うものとは少し違うんだけど、
インラインで別の命令を含めたり、その結果で分岐するようなクエリもかけてしまうせいで、クエリを複雑化しやすい。
なので、クエリを呼び出すクラスでデータベースの動きまで含めてテストにしたいというのは理解できなくもない。

でもあくまでもそれは単体テストではなく、結合テストの自動化だと思う。
他のUTとは別のものとして管理を行ったほうがいいんじゃないかな。

そもそもとして、動的にクエリが変わるうえ、それがビジネスロジックを含むとか大分魔界な感あるw
人間が体感できないほどの実行時間差しか生まなそうな場合は、
複数回クエリを投げてプログラム上で処理したほうが、後々の事を考えるといいケースもあるし、
頻繁にDBを絡めたUTを書かないといけないような事はないと思う。

どうしてもロジックを含むクエリが必要な場合も、1つのクエリに詰め込むよりプロシージャー化するとかしたほうが、
長期的にみるいいんじゃないかな。キッチリやるのはコストかかるから、プロジェクトの規模とかにもよると思うけれど。
169仕様書無しさん:2013/04/21(日) 17:32:17.22
>>154,162
そもそも、あなたの定義した、
> データベースと接続するのを結合まで伸ばす人たち
がどこに居るのかがわからない。
敵を作り出しては居ないかい?
170仕様書無しさん:2013/04/21(日) 18:33:55.14
ちゃんと作るならDBをモックにすべきって思うけど、
ロジックの全パターンテストしようとすると、
結局DBの返り値想定を何パターンも用意しなくちゃいけなくて、
むしろDB使うより効率悪い気がする。
171仕様書無しさん:2013/04/21(日) 18:54:09.50
172仕様書無しさん:2013/04/21(日) 18:57:17.05
>>168
だから、きちんと目的の結果を得ることができるクエリを組み立てられたかどうかを
確認するのが目的だってば。
これを結合テストと言いたがる理由がわからない。
173仕様書無しさん:2013/04/21(日) 19:03:07.21
あと、テストが必要なのは大抵は一覧を取得するクエリ。
一覧を取得するクエリは、一度のクエリで全部終わるのが理想だから、内容が複雑になりがち。
まあ、Oracle SQLパズルに登場するようなクエリをいくつか合わせたようなイメージ。
174仕様書無しさん:2013/04/21(日) 19:30:25.17
>>168
> クラス単体テストって意味だと、DB部分はMock化すべきで、DBクエリが正しいかを検証するほうが正しいと思う。
結局そのクエリの正しさを検証するには、そのシステムで使用しているDBMSを使う必要が
ある訳だが?現実的に、そこをわざわざ別のテストにするメリットはあるの?
175仕様書無しさん:2013/04/21(日) 19:37:50.67
例えば、Redmineのチケット一覧ページ。
あれが実際どう実装してるのかしらないけど、まあ最終的に単一のクエリが生成されると思ってくれ。
ユーザが指定する条件で、そのクエリのwhere句が変わるのはわかると思う。
それに付け加えて例えば「管理ユーザが登録したもの」とか「直近1週間にSCMに
コミットされたもの
176仕様書無しさん:2013/04/21(日) 19:46:19.59
間違えて書き込みしてしまった。

とかの条件が加わると、別テーブルもjoinする必要がでてくる。
あるいは、カラムリストにcaseを使う必要が出てくるかもしれない。

そんなクエリをコードで動的に生成するから、それが妥当なものかどうかを単体で
検証したいということ。
で、それを確認するのが最も簡単なのが、DBを使うこと。
177仕様書無しさん:2013/04/21(日) 22:59:43.44
なんか、単体テストとか結合テストとか頭硬い人多いな
その時点で最もやりたいことを最も低コストでできる手段を使えばいいんだよ
mockがいいならmockでいいし、DBに繋げた方がいい人は繋げればいい
ただそれだけだよ
ステップ実行がいいという人までいるくらいなんだし
178仕様書無しさん:2013/04/21(日) 23:16:18.62
仕様通り動くことが確認できれば手段は何でもいいってことだな
179仕様書無しさん:2013/04/22(月) 08:55:27.79
単体テスト段階で仕様(要件)とマッチしていることも確認できればいいんだが、
大抵はプログラマの意図通りかを確認するテストになり、仕様とのずれが後工程で
発覚したりする。
180仕様書無しさん:2013/04/22(月) 10:43:23.74
条件からクエリを生成する機能をテストするために、SQL文法チェッカ探すよりDBつないだ方が手軽だから、DBを使って単体テストを書く。
というのは別に誰も否定してないだろう。

その機能を実装してる時に、テストケースとは別に DB につないでデバッグしたり、テストコードを紛れ込ませることも、誰も悪いとは言ってない。
自動テスト対象のテストケースとして書く必要はないが、単体テストと並行して普通のデバッグとして DB アクセスしたらいい。
書いてすぐにそこの部分の結合テストしたいなら、前倒しにするなり、実装直後に部分的な結合テストをするようにスケジューリングすればいい。

DB につながないと分からないことが、とかそういうのは単体テストじゃない。
別にこのスレでその話をして悪いとは思わないが、スレタイは単体テストだ。
181仕様書無しさん:2013/04/22(月) 11:13:37.74
>>180
> DB につながないと分からないことが、とかそういうのは単体テストじゃない。

なんでそういうことにしたいの?
DBUnitとかは全否定?
182仕様書無しさん:2013/04/22(月) 11:19:30.00
>>180
> というのは別に誰も否定してないだろう。

というのであれば、そのメソッドをリファクタリングしたり、仕様変更等の理由で修正したり、
クエリそのものをリファクタリング(結果が変わらないよりよいクエリに変更すること)をする
時に、自動テストのテストスィートが存在することのメリットがわかると思うけど。
183仕様書無しさん:2013/04/22(月) 13:48:00.83
>>168
> どうしてもロジックを含むクエリが必要な場合も、1つのクエリに詰め込むよりプロシージャー化するとかしたほうが、
一つのビジネスロジックを実現するために、複数のSELECT/INSERT/UPDATE/DELETEを組み合わせる必要が有る場合、それらをまるごとストアド化するとカバレッジが取れなくなる。
184仕様書無しさん:2013/04/22(月) 14:58:24.96
カバレッジ測定出来ないからストアド禁止ってこと?
それはさすがにアホすぎるかと
185仕様書無しさん:2013/04/22(月) 16:18:53.25
>>183
そうではなくて、ストアドでやってもクライアント言語側でやってもあまりかわらないなら、クライアント言語側で実装すればカバレッジを取れるということ。
また、ストアドで実装すると、バージョン管理が面倒になるというのもデメリット。
それと、これはそれほどたいした話ではないが、一般にストアドよりクライアント言語の方がデータの取り回しが楽。
186仕様書無しさん:2013/04/22(月) 16:19:22.22
× >>183
○ >> 184
187仕様書無しさん:2013/04/22(月) 17:42:05.31
DBにアクセスするメソッドを呼ぶメソッドのテストではmockを使うのが良い。
DBにアクセスするメソッドのテストでは、データベースに接続するのが良い。

ってことでしょ。かみ合ってないわ。
188仕様書無しさん:2013/04/22(月) 17:54:13.02
股間が群れて臭い
189仕様書無しさん:2013/04/22(月) 20:00:42.31
もともと、動作を確認するのにアドホックなテスト書くくらいだったらxUnitでテスト書こうぜって
のりのはずだったのに、DBアクセスだとアドホックなことしたがる理由がわからない。
190仕様書無しさん:2013/05/19(日) 17:08:25.57
画面ポチポチで動作確認するのだるい処理をテストするのには向いてるし
クラス単体のテストを行ったって結果がとても重要だから、UTの実装もできない連中はクズだと思うよ実際
ちょっとツールの使い方を学ぶ、ってことすらできなくなってる
191仕様書無しさん:2013/06/12(水) 01:14:27.48
C++でデストラクタのテストはどうすればいいんですかね?
戻り値返せないし、例外も飛ばせないし。
テスト時だけ検証用のコードを入れてますか?
192仕様書無しさん:2013/06/12(水) 06:57:24.71
メモリーリークのテストって事か?
193仕様書無しさん:2013/06/13(木) 02:24:46.40
テストが必要なほどの処理をデストラクタでやるのが問題な可能性も
カバレッジ100%のため、ってことなのかもしれないけど

C++殆どやってないし、テストとか書いたことないからよく知らないんだけど
他に影響を与える処理ならモックつっこんで、自身の状態を変えてるなら継承(できるんだっけ?)して
期待した処理が呼ばれるかをテストするとか…?
194仕様書無しさん:2013/06/13(木) 04:26:32.30
>>193
何言ってるの?
195191:2013/06/13(木) 05:36:10.79
説明不足ですみません。

良い例では無さそうだけど、こんなクラスでちゃんとfclose()が
成功したか調べる場合どうしたらスマートなのかと思い質問させて頂きました。
class xxx {
 FILE *fp;
public:
 xxx() {fp = fopen("xxx","r");}
 ~xxx() {fclose(fp);}
};

>>193
モックからチェックするのは思いつきませんでした。
ありがとうございました。
196仕様書無しさん:2013/06/13(木) 14:11:50.97
fclose()の戻り値拾って標準エラー出力にでも吐けば?
197仕様書無しさん
デストラクタの中の処理を関数化して
それをテストするとか?