<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>テストテクニック</title><link>http://blogs.wankuma.com/esten/category/1290.aspx</link><description>略してTT（号泣ではない）　片桐的、システム開発でのテストのいろいろについて</description><managingEditor>片桐　継（Tugu Katagiri）</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>Android Studio で Junit を使いたいので、戦い続けて挫折して立ち返って立ち直った話</title><link>http://blogs.wankuma.com/esten/archive/2014/08/21/408431.aspx</link><pubDate>Thu, 21 Aug 2014 16:49:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2014/08/21/408431.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/408431.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2014/08/21/408431.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/408431.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/408431.aspx</trackback:ping><description>&lt;p&gt;最初、EclipseでJunit 4.11+Robolectricを使ってたんだけど、AndroidStudioに移植した時に、全部グリーン状態のソースを移植したのでテストコードは省いてたｗ&lt;/p&gt; &lt;p&gt;なので、機能追加のついでに、テストコードも移植しようと思ったんだけど、意外な展開が。&lt;/p&gt; &lt;div class="insertcode"&gt;&lt;pre&gt;&lt;code&gt;!!! JUnit version 3.8 or later expected:

java.lang.RuntimeException: Stub!&lt;br&gt;&lt;/code&gt;&lt;code&gt;＜中略＞
Process finished with exit code -3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;素直にRobolectricを依存ライブラリに追加して実行して、&lt;font color="#c0504d"&gt;&lt;strong&gt;なにこれ？？？&lt;/strong&gt;&lt;/font&gt;というわけで色々と調査。で、判ったことは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android StudioでRobolectric使うならプラグインいれましょう 
&lt;li&gt;クラスパスはJunit＞SDKの順番でライブラリ参照しましょう&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;あふー、gradleをいじる羽目になりましたですよorz　書き直すのメンドイなー。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://robolectric.blogspot.jp/" target="_blank"&gt;Robolectricスタッフのブログ&lt;/a&gt;や&lt;a href="https://groups.google.com/forum/#!forum/robolectric" target="_blank"&gt;GoogleGroup&lt;/a&gt;を見る限りだと、この辺りの問題はできたら解決したいなー的レベルらしくて、しばらくは手動でごにょごにょの世界のようです。&lt;font color="#c0504d"&gt;&lt;strong&gt;まぁAndroid Studio自身がbetaの立場だもんなー、正式版になってからなんだろうなぁ（遠い目）&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;で、やってみたこと。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;app/build.gradleにrobolectricの依存ライブラリ追加 
&lt;li&gt;ルートのbuild.gradleにrobolectricのプラグインのための依存ライブラリ追加 
&lt;li&gt;app/buid.gradleにrobolectircのプラグイン追加 
&lt;li&gt;ここで、いったんgladleをSync 
&lt;li&gt;ターミナルから、プロジェクトルートでgladle robolectric を実行し、必要なクラスがコンパイルされていることを確認 
&lt;li&gt;テストコードを書いて、ライブラリが追加出来ていることを確認 
&lt;li&gt;テストコードから生成されたクラスの出力先をクラスパスに追加 
&lt;li&gt;プロジェクトルートにある、.imlファイルの中にあるクラスファイルの読み込み順番を変更 
&lt;li&gt;gladlew androidTest を実行&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;さらっと書いたけど、&lt;font color="#9b00d3"&gt;２から５の間はgradleソースの読み込みだったので、簡単じゃなかったよorz &lt;/font&gt;　gradleソースはpom.xmlよりも何をやっているのかソースで追える分、楽と言えば楽だし、親切と言えば親切なんだけどね。やっててよかったgroovy。&lt;/p&gt;
&lt;p&gt;そして、何とかたどり着く9のフェーズ。&lt;strong&gt;&lt;font color="#ff0000"&gt;ここで恐怖のハマりポイント、自クラスをクラスパスにうまく追加できない、をやらかしてしまった。&lt;/font&gt;&lt;/strong&gt;いや、世界には、この方法で解決している人もいるので&lt;font color="#c0504d"&gt;&lt;strong&gt;（成功例がMacOSXだったりするのがとてもとても気になるけれどもｗ）&lt;/strong&gt;&lt;/font&gt;きっと、何かが悪いんだろう。&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff"&gt;&lt;strong&gt;収穫はgradleソースが読めるようになった、ってことで、挫折orz&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;これに丸々二日ハマって、なんか疲れたんで、基本に立ち返ってみたんだ。&lt;/p&gt;
&lt;h1&gt;Android SDK　にテストフレームワークがあるのかな？&lt;/h1&gt;
&lt;p&gt;&lt;font color="#9b00d3"&gt;&lt;strong&gt;結論から言えば、ある、Junitがある。ただし、バージョンは3.8。&lt;/strong&gt;&lt;/font&gt;便利なassertもアノテーションも全滅のオールドタイプさん。まぁ悪いバージョンじゃないんだ、基本機能はガッチリ揃ってるし、実績も高いしさ。まさかとは思うけど、&lt;a href="http://mvnrepository.com/" target="_blank"&gt;Mavenリポジトリサイト&lt;/a&gt;で、Junit3.8のダウンロード数が廃れないのは、こいつのせいだったりしてねｗ　&lt;/p&gt;&lt;a href="http://developer.android.com/tools/testing/testing_android.html"&gt;Testing Fundamentals | Android Developers:&lt;br&gt;http://developer.android.com/tools/testing/testing_android.html&lt;/a&gt;&lt;br&gt;
&lt;p&gt;基本に立ち返って、もう一度、この記事を目皿にして読み直し、抜粋したポイントは&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ディレクトリを作成する 
&lt;li&gt;テストしたいAndroidオブジェクトに対応したTestCaseを継承してテストコードを書く 
&lt;li&gt;Android Test を実行する&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;これだけ。じゃ、やってみようか、もちろん、最初はレッドのテストでね。&lt;/p&gt;
&lt;p&gt;まず、ディレクトリ作成&lt;/p&gt;
&lt;p&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://esten.dip.jp/blogimg/Android-Studio--Junit-_4EA0/image.png" width="216" height="127"&gt;&lt;/p&gt;
&lt;p&gt;デフォルト配色で、androidTest/javaフォルダが緑色になればOK。これは、テストクラスのあるパッケージディレクトリですよ、を指している色で、これが指定されていないと、後の作業がメンドクサイ、フォルダ見難いｗ&lt;/p&gt;
&lt;p&gt;このフォルダの指定は、モジュールの.imlファイルに記述されているので、検索してフォルダ表記が無かったら、それを記述追加してリビルドすれば環境ができているはず。できるだけ、いじらないでいたいなら、テストクラスとして指定されている別のフォルダがすでにあれば、それを新規作成すると後も綺麗に続けられるので楽。テストクラスのパッケージフォルダ記述が無いなら、仕方ないから追加ね。&lt;/p&gt;
&lt;p&gt;そして、テストクラスを新規作成。これはいつもの新規作成の手順でOK。&lt;/p&gt;
&lt;div class="insertcode"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ApplicationTest &lt;span style="color: #0000ff"&gt;extends&lt;/span&gt; ApplicationTestCase&amp;lt;Application&amp;gt; {
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ApplicationTest() {
        &lt;span style="color: #0000ff"&gt;super&lt;/span&gt;(Application.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);
    }

    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; testAssertion(){
        assertEquals(1,3);
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;絶対レッドのテストｗ＜手抜きすぎｗ&lt;/p&gt;
&lt;p&gt;今回はアクティビティやコンテンツのテストではないので、ApplicationTestCaseを継承したけど、テストしたいものによって継承するテストクラスが異なるので、細かい事は前記述のサイトのリンクから参照で。(そのうち、まとめるとは思うけどｗ)&lt;/p&gt;
&lt;p&gt;クラスが書けたら、次は実行設定。私は、モジュール内のｘｘｘｘTestクラスのtestXXXXメソッドを総なめにした。細かくやりたい人はパッケージ事とかに分けると良いと思う。&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://esten.dip.jp/blogimg/Android-Studio--Junit-_4EA0/image_3.png" width="373" height="355"&gt;&lt;/p&gt;
&lt;p&gt;Android SDKのJunitは実行環境を必要とするのでエミュレーターは起動しておき、立ち上がりを確認したら、テストを実行してエミュレーターに環境割り当てをすると、テストモジュールがエミュレーターにアップロードされて……&lt;/p&gt;
&lt;p&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://esten.dip.jp/blogimg/Android-Studio--Junit-_4EA0/image_4.png" width="675" height="159"&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#ff0000" size="5"&gt;&lt;strong&gt;よっしあぁ！レッドすねぇぇくかもぉぉん♪&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;というわけで、立ち返ってからレッドになるまで、２時間だったというオチｗ&lt;/p&gt;
&lt;p&gt;&lt;font color="#c0504d"&gt;&lt;strong&gt;基本って大事だね！　痛感したわ。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/408431.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>JUnitのassertはどうして書くのが良いんだろうか？</title><link>http://blogs.wankuma.com/esten/archive/2014/07/23/343831.aspx</link><pubDate>Wed, 23 Jul 2014 10:20:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2014/07/23/343831.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/343831.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2014/07/23/343831.aspx#Feedback</comments><slash:comments>106</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/343831.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/343831.aspx</trackback:ping><description>&lt;p&gt;&lt;font color="#000000"&gt;ちょっと、迷って困ってた。&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000"&gt;JUnitのテストを書いてて、&lt;/font&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;font color="#000000"&gt;とある整数型リストは、1,2,3,4 の四つの要素を持っているはず。&lt;/font&gt;  &lt;li&gt;&lt;font color="#000000"&gt;リストの要素の順番はどうでもいいが、要素の中身はこうであるはず。&lt;/font&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;font color="#000000"&gt;ってのを、JUnitのassertで検証したい、となった時、書き方としては、&lt;/font&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;em&gt;&lt;font color="#000000"&gt;assertTrue(actItem.getRolled().containsAll(Arrays.asList(1, 2, 3, 4)));&lt;/font&gt;&lt;/em&gt;  &lt;li&gt;&lt;em&gt;&lt;font color="#000000"&gt;assertThat(actItem.getRolled().containsAll(Arrays.asList(1, 2, 3, 4)), is(true));&lt;/font&gt;&lt;/em&gt;  &lt;li&gt;&lt;em&gt;&lt;font color="#000000"&gt;assertThat(actItem.getRolled().toArray(new Integer[0])&lt;br&gt;　　　　　　　　, IsArrayContainingInAnyOrder.arrayContainingInAnyOrder(1, 2, 3, 4));&lt;/font&gt;&lt;/em&gt;&lt;!--EndFragment--&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;font color="#000000"&gt;と、こんな風に、色々とあるんだけど、どれが判りやすいんだろうか、正しいんだろうか。&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#000000"&gt;考えるネタとして、逆に、このassert文はこれをテストしたいんだな、と、assert文から読み下してみたらどうなるのかなぁと思って、やってみたの。&lt;/font&gt;&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;font color="#000000"&gt;１２３４の値で構成されたリストを引数としたContainsAllメソッドの実行結果が、trueであることを確かめたい。&lt;/font&gt;  &lt;li&gt;&lt;font color="#000000"&gt;１２３４の値で構成されたリストを引数としたContainsAllメソッドの実行結果が、戻り値trueであることを確かめたい。&lt;/font&gt;  &lt;li&gt;&lt;font color="#000000"&gt;リストの構成要素を整数配列型にキャストした結果が、並び順関係なく１２３４の要素で構成されていることを確かめたい。&lt;/font&gt;&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;こうなった。&lt;font color="#ff0000"&gt;&lt;strong&gt;なので、この場合、確かめたいことをassertしているのは、３ってことになる。&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;u&gt;&lt;font color="#000000"&gt;だって、&lt;/font&gt;&lt;font color="#000000"&gt;テストしたいのはContailsAllメソッドじゃないし。リストの要素だし。&lt;/font&gt;&lt;/u&gt;&lt;/p&gt; &lt;p&gt;といいつつも、私は個人的な好みでシンプルな１が好き。何をassertしたいのか、コメントしとけば良いもん。&lt;font color="#cccccc"&gt;＜我儘ｗ&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#9b00d3"&gt;でも、個人のお気楽開発ならこんな風に好きにして良いけど、チームでの開発であるなら、こういうの、きっと、どれにしときましょ？とすり合わせた方がいいね。&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;assertの書き方は、チーム内なり、プロジェクト内なりで、ある程度基準を作っておくと、ここで何を確認したかったのか、仕様の要点が何なのかが判りやすくなって、後から来た人にも、作って忘れちゃってる人にも、親切なテストコードになる&lt;/font&gt;と思うの。よくある「好きにしていいよ」が一番よろしくないオチ。後で混乱したり、なんでこうなってるの？、これはなにをテストしてるの？が起きちゃうこと請け合い、つか、経験則ｗ&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/343831.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>私、MVCでTDDやってます。</title><link>http://blogs.wankuma.com/esten/archive/2011/12/21/232961.aspx</link><pubDate>Wed, 21 Dec 2011 06:08:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2011/12/21/232961.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/232961.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2011/12/21/232961.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/232961.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/232961.aspx</trackback:ping><description>&lt;h2&gt;はじめに&lt;/h2&gt; &lt;p&gt;この記事は&lt;a href="http://atnd.org/events/22027" target="_blank"&gt;TDD Advent Calendar jp: 2011 : ATND&lt;/a&gt;の参加記事です。&lt;/p&gt; &lt;p&gt;私で21日目に突入しました。20日目は、haru012さんの&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;a href="http://d.hatena.ne.jp/haru01/20111220/1324341146"&gt;Testing と 私と 苦い出来事&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;でした。体験談かぁー。私も炎（ｒｙ　ごほんごほん。&lt;/p&gt; &lt;p&gt;てな感じで、今までの記事では、TDDの色々がとてもお勉強になるお勧め記事がたくさんでしたが、私のはちょっとだけ業務アプリケーション開発の実作業に近づいた内容かもしれません。まぁ、実際の所、私はこんな風に思ったよ、というのが正しいのですけれども。&lt;/p&gt; &lt;h2&gt;MVCとTDD、それぞれの利点&lt;/h2&gt; &lt;p&gt;MVC（Model-View-Controller）と呼ばれるデザインパターンが流行ってます。実際、私も使ってます。MVCって何？って方は以下など読んでいただいて。&lt;/p&gt; &lt;h5&gt;&lt;a href="http://ja.wikipedia.org/wiki/Model_View_Controller"&gt;&lt;em&gt;Model View Controller&lt;/em&gt; - Wikipedia&lt;/a&gt;&lt;/h5&gt; &lt;h5&gt;&amp;nbsp;&lt;/h5&gt; &lt;h5&gt;&lt;a href="http://www.google.co.jp/url?sa=t&amp;amp;rct=j&amp;amp;q=mvc&amp;amp;source=web&amp;amp;cd=2&amp;amp;ved=0CEQQFjAB&amp;amp;url=http%3A%2F%2Fe-words.jp%2Fw%2FMVC.html&amp;amp;ei=WYbwTuexDM6dmQWehuyoAg&amp;amp;usg=AFQjCNEh_eUYuwxWDZIcGy829f0SAECeww&amp;amp;sig2=Zvh432ojFqNEk9Cq76kZgA"&gt;&lt;em&gt;MVC&lt;/em&gt;とは【&lt;em&gt;Model-View-Controller&lt;/em&gt;】 - 意味/解説/説明/定義 ： IT用語辞典&lt;/a&gt;&lt;/h5&gt; &lt;p&gt;読んで字のごとく、MVCはアプリケーションの構造をModelとViewとControllerという３つの概念に分けるものなのですが、これらの開発過程でTDDを生かして進めていくとかなり有効。というのも、それぞれの利点がうまく重なっているんです。&lt;/p&gt; &lt;p&gt;まず、私が考えているMVCの利点は次のような所。&lt;/p&gt; &lt;ul&gt; &lt;li&gt;MVCそれぞれにクラスが独立していて、作成するコードの単位が明確である。&lt;/li&gt; &lt;li&gt;メソッド単位、アクセサ単位で処理を隠ぺいできるので、既存コードへの影響が少ない修正作業、リファクタリングをすることが出来る。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;そして、TDDの利点は次のような所。&lt;/p&gt; &lt;ul&gt; &lt;li&gt;仕様が理解できているか、抜けが無いか、自己確認が出来る。&lt;/li&gt; &lt;li&gt;リファクタリングや仕様変更によるデグレードを防ぐことが出来る。&lt;/li&gt; &lt;li&gt;メソッド単位、クラス単位の小さなテストコードを積み重ねるので、全体がどれくらいで、今できているのがどれくらいなのか判り易く、進捗を取りやすい。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;つまり、それぞれの利点の共通点は、&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#800080"&gt;プログラムコードにしろテストコードにしろ、実際に作業する単位が小さい。&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;こと。&lt;font color="#ff0000"&gt;ここ、以外と大事。&lt;/font&gt;独りでちまちま作るにしろ、チームで作業を分けあうにしろ、TDDで作り上げていくMVCのアプリケーションは、小さな単位を積み上げていくってことが同じだから作業に無駄がない。&lt;font color="#008000"&gt;実際に、たくさんのテストコードがGreenになるのは楽しいし＜結局そこか（笑）&lt;/font&gt;&lt;/p&gt; &lt;h2&gt;効率良いTDDをするために&lt;/h2&gt; &lt;p&gt;小さな作業単位を積み上げていくのは良いけれど、それらをもっと効率的に確実にできる方法はないのでしょうか？&lt;/p&gt; &lt;p&gt;例えば、チームでMVCそれぞれを担当して並行してすすめる、とか。恐らくは「独立したテストコード」を作成できれば、その理想に近づく事は出来ると思うのですけれど……。&lt;/p&gt; &lt;p&gt;MVCは独立しています、といっても、それぞれのクラス、メソッドで動作するプログラムは動作の前提条件や変数の内容などで密接な関係があることに違いありません。&lt;font color="#808000"&gt;こっちが出来てないと、データこないじゃん、データないじゃん、ということはフツーにあるわけで。&lt;/font&gt;&lt;/p&gt; &lt;p&gt;そこで、テスト用クラス、Mockというクラスの考え方が出てきます。&lt;/p&gt; &lt;p&gt;極論、&lt;strong&gt;Modelのクラスを作成したい時には、Modelクラスだけがテスト出来れば良いわけです。&lt;/strong&gt;その他のViewクラスやControllerクラスが、未実装だったり、まだバグがある状態だだったり、そんな状態で使っていたら、本来のModelクラスのテストはいくら頑張っても効率が上がらない。だから、その対策として、Modelクラスの目的の動作に必要な前提条件、テストデータ、それらを備えたクラス、Mockクラスを用意するのです。それを使う事で、前提条件がそろった状態で実行できますから、自分は必要な最低限のModelクラスの動作だけをテストコードに記述すればよいですね。&lt;/p&gt; &lt;p&gt;具体的に、データベースからレコードを取得して一覧に表示する、を例に考えると、&lt;/p&gt; &lt;ol&gt; &lt;li&gt;データベースからデータを取得する。&lt;/li&gt; &lt;li&gt;一覧表示用のリストデータに加工する。&lt;/li&gt; &lt;li&gt;リストデータから一覧表示を行う。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;とMVCの単位で大まかに分けることができます。実際にはもっと色々とあるかもしれないけど、例なので大雑把（笑）。この時にTDDしよう！と思ってテストコードを書き始めた時、１を作って動作できたら、２を作って、２が動作出来たら３を作る、とやっていかないと、必要な前提条件（データ）がそろわない。&lt;/p&gt; &lt;p&gt;でも、&lt;/p&gt; &lt;ol&gt; &lt;li&gt;データ取得ためのデータを提供するデータベースのMock&lt;/li&gt; &lt;li&gt;リストデータ加工するためのソースデータを持つクラスのMock&lt;/li&gt; &lt;li&gt;リスト用データに加工済みのデータを提供するクラスのMock&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;がそれぞれにあれば、１～３のクラスを並行に作業可能。自身以外の必要なクラスはMockに任せてしまってるから、本当に自分が作りたいクラスとメソッドの動作を検証するだけのテストに特化でき、TDDのサイクルも早くなります。&lt;/p&gt; &lt;p&gt;つまり、Mockクラスを使う事で「独立したテストコード」が可能になるんです。&lt;/p&gt; &lt;p&gt;ちなみに、実際にテスト用Mockを使ったテストを行う時、良い仕事をしてくれるのがInterfaceクラス。Mockに置き換えたいクラスがInterfaceを持つことで、呼び出し側はMockなのかそうでないのか、意識する必要がなくなります。DI（&lt;em&gt;Dependency Injection&lt;/em&gt;）できるフレームワーク上でのTDDなら、なおのこと、必要に応じてMockを注入できるからお勧め。&lt;/p&gt; &lt;h2&gt;TDDの肝&lt;/h2&gt; &lt;p&gt;こうなってくると、Mockを作成する＝Mockの内容に仕様と齟齬があったら、なかなか大変なことになるのでは？と思いませんか？&lt;/p&gt; &lt;p&gt;Mockの作成もさることながら、テストコードの作成にしてもそうです。テストコードの品質＝作成されるアプリケーションの品質、と考えても過言ではないでしょう。あくまでもこれは経験則ですが、&lt;font color="#ff0080"&gt;TDDの肝は、言語やフレームワークに関係なく、まず仕様の理解が必要不可欠であり、それをいかにテストコードに反映できるか、&lt;/font&gt;だと思っています。なんて偉そうに言ってても、まだまだ私も修行中の身、仕様理解できてない、勘違いしてた、がよくあってorz。&lt;/p&gt; &lt;p&gt;TDDは小さな単位でプログラムコードの動作を検証でき、それを積み上げていくことで磨かれていく開発手法です。MVCパターンとも相性がよく、うまく使えば非常に有効な手段でもあります。&lt;/p&gt; &lt;p&gt;というわけで、私の記事は終わりです。最後に、TDDに携わるようになってから覚えた、自戒の意味をこめて、この言葉を。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p align="center"&gt;&lt;strong&gt;&lt;font color="#008000" size="4"&gt;「書いていないテストコードにバグがある」&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/232961.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>WCATのコマンドラインオプション</title><link>http://blogs.wankuma.com/esten/archive/2009/07/09/177290.aspx</link><pubDate>Thu, 09 Jul 2009 17:19:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2009/07/09/177290.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/177290.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2009/07/09/177290.aspx#Feedback</comments><slash:comments>417</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/177290.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/177290.aspx</trackback:ping><description>&lt;p&gt;どうも、ＷＣＡＴってやつは、wsfファイルに色々とコマンドをくっつけて動かすらしい。&lt;/p&gt; &lt;p&gt;一個のファイルでいろんなことができるようになっているようなので、コマンドを整理しないと困りそう。&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="67" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_F343/image.png" width="502" border="0"&gt; &lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="90%" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-clients&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;コントロールしたいWCATクライアントのIPアドレスとか名前とかをカンマ区切りで列挙&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-terminate&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;すべてのWCATクライアントを停止&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-update&lt;/td&gt; &lt;td valign="top" width="10"&gt;：&lt;/td&gt; &lt;td valign="top" width="804"&gt;-clientsで指定したWCATクライアントに、DLLとEXEをコピーしてWCATクライアントとして登録、使用できるようにする。クライアントのコピー先は「￥￥コピー先クライアント￥admin$￥wcat」となるので、アクセス権があるかどうかを確認すること&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-run&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;WCATクライアントを開始&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-setclients&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-clients パラメータと一緒に使用すると、コントロール側では、レジストリ「HKLM￥Software￥WCAT￥clients」に情報を登録更新。パラメータがない場合には、同レジストリを初期化してデフォルト値（localhost）に戻す&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-showclients&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;レジストリ「HKLM￥Software￥WCAT￥clients」に登録されているクライアントを表示&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-stdout&lt;/td&gt; &lt;td valign="top" width="10"&gt;：&lt;/td&gt; &lt;td valign="top" width="804"&gt;ログの標準出力先を指定。ファイル名を使用しない場合には画面に表示される&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-stderr&lt;/td&gt; &lt;td valign="top" width="10"&gt;：&lt;/td&gt; &lt;td valign="top" width="804"&gt;エラーの標準出力先を指定。ファイル名を使用しない場合には画面に表示される&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-help&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;ヘルプを表示&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;ってここまでが、WCAT.wsfで使用するおもなオプション。で、これの大変なところは、&lt;font color="#ff0000"&gt;この後に、WCATコントロール用の専用オプションスイッチもつけられるってところ&lt;/font&gt;。これがまたたくさんあって、どうしたもんだかと、ちょっと考え込んじゃった。&lt;/p&gt; &lt;h3&gt;WCATコントロール（wcctl.exe）のコマンドラインオプション&lt;/h3&gt; &lt;p&gt;いくつかのカテゴリに分かれているらしい。入力系、設定系、シナリオ系、出力系、その他、くらいかな。&lt;/p&gt; &lt;h4&gt;入力系オプション（Input File　Parameters)&lt;/h4&gt; &lt;table cellspacing="0" cellpadding="2" width="914" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-clientfile&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-t に省略可能。必須。テストシナリオファイルを指定&lt;strong&gt;（テストシナリオファイルについてはまた後で）&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-settingfile&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-f に省略可能。必須。設定ファイルを指定&lt;strong&gt;（設定ファイルについてはまた後で）&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h4&gt;設定系オプション（Setting File Override Parameters）&lt;/h4&gt; &lt;p&gt;設定ファイルの中にも書けるんだけど、実行時にスイッチで渡すことで動的に変えることができるらしい。&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="914" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-virtualclients&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-v に省略可能。ファイル内で指定していない場合には必須。１台のWCATクライアント上で、何ユーザー分の仮想コネクションを発生させるかを数字で指定。WCATが５台あって、３を指定していたら、５×３で15コネクションの負荷テストが行える&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-server&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-s に省略可能。ファイル内で指定していない場合には必須。テストを行いたいWEBサーバーをドメインURLもしくはIPアドレスで指定。カンマ区切りで複数指定も可能&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-port&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-p に省略可能。WCATクライアントがテスト開始時に、対象サーバーへ接続テストを行う際にポート番号を変更したい場合には指定。通常はhttpポート（８０）を使用&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-comment&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-k に省略可能。テスト結果に含めておきたいコメントがあれば指定&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h4&gt;シナリオ系オプション（&lt;a name="_Toc164236540"&gt;Scenario File Override Parameters&lt;/a&gt;）&lt;/h4&gt; &lt;p&gt;シナリオファイルの中にも書けるんだけど、実行時にスイッチで渡すことで動的に変えることができるらしい。&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="914" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-warmup&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-w に省略可能。ファイル内で指定していない場合には必須。全てのクライアントのロード開始準備が終了しても、この時間が指定されている場合には、WCATコントローラはテスト開始を待機させることができる&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-duration&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-uに省略可能。ファイル内で指定していない場合には必須。warmup終了後、WCATクライアントがロードテストを開始するまでの待機時間を秒で指定&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-cooldown&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-c に省略可能。ファイル内で指定していない場合には必須。ロードテスト終了後、warmupを行うまでの待機時間を秒で記録。この間にテスト結果を記録される。通常は20秒。&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;って、ようるに、ウォーミングアップして、テスト開始！よーいどん！まで待機して、仕事終わったらクールダウンして、ハイ次！って繰り返す時のそれぞれの時間を指定してるってことだね。&lt;/p&gt; &lt;h4&gt;出力系オプション（&lt;a name="_Toc164236540"&gt;Ooutput File Parameters&lt;/a&gt;）&lt;/h4&gt; &lt;p&gt;出力用の設定。デフォルト値があるので、別に指定はいらないかもしれない&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="914" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-output&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-o に省略可能。デフォルトは　log.xml。WCATインストールディレクトリに存在&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" nowrap width="98"&gt;-report&lt;/td&gt; &lt;td valign="top" width="10"&gt;:&lt;/td&gt; &lt;td valign="top" width="804"&gt;-r に省略可能。デフォルトは　report.xsl。WCATインストールディレクトリに存在&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;その他系はまたどっかで。ふー、列挙だけで疲れたｗ&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/177290.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>WCAT起動の準備</title><link>http://blogs.wankuma.com/esten/archive/2009/07/08/177217.aspx</link><pubDate>Wed, 08 Jul 2009 15:21:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2009/07/08/177217.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/177217.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2009/07/08/177217.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/177217.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/177217.aspx</trackback:ping><description>&lt;p&gt;WCATを使用する前の最初に一回だけのおまじない。これは、WCATコントローラとなるPC（サーバー）で使用。&lt;/p&gt; &lt;ol&gt; &lt;li&gt;Administratorでログイン&lt;/li&gt; &lt;li&gt;コマンドプロンプトを起動&lt;/li&gt; &lt;li&gt;WCATのディレクトリに移動&lt;/li&gt; &lt;li&gt;「cscript //H:Cscript」 と入力&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="402" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_D7A5/image.png" width="559" border="0"&gt; &lt;/p&gt; &lt;p&gt;これで、動作準備OK。次に、このマシンで行うWCATクライアントを登録&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#008000"&gt;wcat.wsf -terminate -update -clients localhost&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;もし、いくつかのPCにWCATが分散する場合には、-clientsのパラメータに localhost,192.168.1.3,hogepc とかいった感じでカンマ区切りで追加してあげれば大丈夫。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000" size="4"&gt;初めてこのコマンドを動かす場合、このあと強制的にサーバーが再起動！！&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;だから、他のアプリケーションとか立ち上げてたら注意してね&lt;/p&gt; &lt;p&gt;コマンドプロンプト画面がないのは、そのせいなのorz&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/177217.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>WCATの３つのテスト手法</title><link>http://blogs.wankuma.com/esten/archive/2009/07/08/177215.aspx</link><pubDate>Wed, 08 Jul 2009 14:58:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2009/07/08/177215.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/177215.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2009/07/08/177215.aspx#Feedback</comments><slash:comments>77</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/177215.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/177215.aspx</trackback:ping><description>&lt;p&gt;さて、まだ実はドキュメントを読んでいるわけなのですが、こちらにメモをためていくことにした＜おい&lt;/p&gt; &lt;p&gt;WCATには３つのテスト手法があって、それぞれにメリットデメリットがあるみたい。で、思ったことをつらつらと。&lt;/p&gt; &lt;h3&gt;１台のマシンで行う（&lt;a name="_Toc164236524"&gt;Single Machine Environment&lt;/a&gt;）&lt;/h3&gt; &lt;p&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="172" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_D210/image.png" width="545" border="0"&gt; &lt;/p&gt; &lt;p&gt;テスト用のすべての要素（WEB、DB、WCATコントローラ、WCATクライアント）を一台に入れてしまう方法。&lt;/p&gt; &lt;p&gt;テストに使用する資源は１台で済むのでお手軽。&lt;/p&gt; &lt;p&gt;ハイスペックマシンだと計測結果と実地結果の差異は小さいだろうけどスペック低いと本来のパフォーマンスが得られない分信頼性が下がりそう。&lt;/p&gt; &lt;h3&gt;２台のマシンで行う（&lt;a name="_Toc164236525"&gt;Dual Machine Environment&lt;/a&gt;）&lt;/h3&gt; &lt;p&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="183" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_D210/image_3.png" width="547" border="0"&gt; &lt;/p&gt; &lt;p&gt;テスト用の要素を（WEB）と（DB、WCATコントローラ、WCATクライアント）に分ける方法。&lt;/p&gt; &lt;p&gt;ネットワークの負荷も視野に入れてテストを行える分、こちらの方がより現実的実地に近いWEBサーバーのパフォーマンス計測が可能。テストに使用する資源が複数になるので、準備が大変だけど。&lt;/p&gt; &lt;p&gt;個人的には、Hyper-V上にWEBサーバーと計測用PCを作るのがお勧め。ヴァーチャルネットではあるけれども疑似的なネットワーク負荷も計測できるし。ただ、負荷テストなだけに、ホストサーバーマシンにそれなりのスペックが必要になっちゃうけど。&lt;/p&gt; &lt;h3&gt;たくさんのマシンで行う（&lt;a name="_Toc164236526"&gt;Multiple Machines Isolated Environment&lt;/a&gt;）&lt;/h3&gt; &lt;p&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="280" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_D210/image_4.png" width="559" border="0"&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;その名の通り、（WEB）、（DB）、（WCATコントローラ）、（WCATクライアント）×いっぱい、の構成で行う方法。&lt;/p&gt; &lt;p&gt;大規模なWEBサービスの負荷テストなら、これくらいのものが必要になるのだろうと思う。個人的には、これも、WCATクライアント全部Hyper-Vしちゃったら実質４台ですむなぁとつらっと思ったりした。&lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;てなかんじの３種類。まぁ今回は、Hyper-V上に１台構成のSimpleで触ってみようと思う。&lt;/p&gt; &lt;p&gt;ゲストマシン（テストサーバー）&lt;/p&gt; &lt;p&gt;Windows2003ServerR2 メモリ３G&lt;/p&gt; &lt;p&gt;SQLServer2005　Enterprise&lt;/p&gt; &lt;p&gt;IIS 7.0&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;ちなみにHyper-Vホストマシン&lt;/p&gt; &lt;p&gt;AMD 5200(DualCore)&lt;/p&gt; &lt;p&gt;メモリ８G&lt;/p&gt; &lt;p&gt;の自作機&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;うん、がんばってみる。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/177215.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>WCAT、起動！</title><link>http://blogs.wankuma.com/esten/archive/2009/07/03/177019.aspx</link><pubDate>Fri, 03 Jul 2009 14:45:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2009/07/03/177019.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/177019.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2009/07/03/177019.aspx#Feedback</comments><slash:comments>492</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/177019.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/177019.aspx</trackback:ping><description>&lt;p&gt;最近のダブルキャットといえば、しゅうたんとみずきちゃん。&lt;/p&gt; &lt;p&gt;さて、そんなこんなで、ひさしぶりにASP.NETで作られたサイトをゴリゴリとストレステスト中&lt;/p&gt; &lt;p&gt;サーバースペック：Hyper-V上のWindows2003 server R2(64Bit)&lt;/p&gt; &lt;p&gt;に対して、WEBアクセス負荷テストをしてみたくて、WCATを使ってみることにした。&lt;/p&gt; &lt;p&gt;WCAT、とは？&lt;/p&gt; &lt;p&gt;Microsoftの開発チームが使っているテストツールらしい&lt;/p&gt; &lt;p&gt;&lt;a href="http://social.technet.microsoft.com/Forums/ja-JP/iis7ja/thread/c49f277a-f9e3-4e96-8634-72259edf2730"&gt;[HOW TO] 無償の簡易 Web 負荷ツール WCATの使い方&lt;/a&gt;&lt;br&gt;&lt;a href="http://social.technet.microsoft.com/Forums/ja-JP/iis7ja/thread/c49f277a-f9e3-4e96-8634-72259edf2730"&gt;http://social.technet.microsoft.com/Forums/ja-JP/iis7ja/thread/c49f277a-f9e3-4e96-8634-72259edf2730&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;でもって、さっそくダウンロードして、msiからセットアップ。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#ff0000"&gt;しても、メニューにも登録されないし、デスクトップにもでません&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;だって、&lt;font color="#008000"&gt;&lt;strong&gt;これ、スクリプトベースで動く、CUIアプリだもん&lt;/strong&gt;&lt;/font&gt;。&lt;/p&gt; &lt;p&gt;まぁCUIでもなんとかなるさ、インストール先は普通なら、「Program Files\WCAT」なので、これを覗く。&lt;/p&gt; &lt;p&gt;&lt;img title="image" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="283" alt="image" src="http://esten.cside.com/wankuma/img/WCAT_CF57/image.png" width="600" border="0"&gt; &lt;/p&gt; &lt;p&gt;という風に、exeファイルが３つにスクリプトファイルひとつ、あとはサンプルに、xslファイル。&lt;/p&gt; &lt;p&gt;まぁxslはSandcastleで見慣れたファイルなのでここはおいといて、と。&lt;/p&gt; &lt;p&gt;とりあえず、DOCファイルを読む、でわかったこと。&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#000080"&gt;wcclient.exe：クライアント側からストレステストする時のプログラム&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#000080"&gt;wcctl.exe：サーバー側からストレステストする時のプログラム&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;font color="#000080"&gt;wcutil.exe:ストレステストで作成したログを整形するっぽい？&lt;/font&gt;&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;くわしくはもちっと、がんばって読んでみることにする&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/177019.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>SQLCLR　ストアドプロシジャをデバッグする</title><link>http://blogs.wankuma.com/esten/archive/2009/03/30/170452.aspx</link><pubDate>Mon, 30 Mar 2009 22:15:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2009/03/30/170452.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/170452.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2009/03/30/170452.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/170452.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/170452.aspx</trackback:ping><description>&lt;p&gt;SQLServer2005でSQLCLRストアドプロシジャを作ってて、何が大変って、デバッグだった。それもステップ実行による、デバッグ。&lt;/p&gt; &lt;p&gt;いろいろと方法があるのだけれど、&lt;font color="#ff0000"&gt;結局、「現場でいちばん有効だった」方法がこれだったので投下&lt;/font&gt;ｗ&lt;/p&gt; &lt;p&gt;まず、思い切ってクラス化構造にしてしまうというのがこのお話のポイント。&lt;/p&gt; &lt;p&gt;こうすると、クラスの単位でデバッグができるので、処理の確認の範囲がぐっとせまくなるんだよね。&lt;/p&gt; &lt;p&gt;&lt;font color="#800000"&gt;&lt;strong&gt;１．クラス化構造でロジックを作る&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#800000"&gt;&lt;strong&gt;２．作ったクラスをコンソールアプリ or UnitTest で動作確認する&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;&lt;font color="#800000"&gt;&lt;strong&gt;３．確認を終えたら、ストアドプロシジャのメイン処理からそのクラス処理を行う&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;って作ると、２．を作った段階で、クラスの処理内部の動きは確認済になるわけだから、動かなくなる、エラーがある、としたら、３．のクラス呼び出し側にかかわる部分、と絞り込めるわけ。&lt;/p&gt; &lt;p&gt;最初は、必死にCLRデバッガで止めてやってたけど、行き着いた先はここだったorz&lt;/p&gt; &lt;p&gt;でも簡単にはこの手順ではいかない。特に、SQLServerCLRのためにあるとも言えるような処理ロジックを含む場合には、それを代替してテストして、ストアドプロシジャ環境に持ってきてから動かしてみる、という手順が必要。そのためにも、ストアドプロシジャ独自で使われるルール（Partialクラスで作るトアドプロシジャクラス、接続文字列）とオブジェクト群（SqlContextクラス処理）の使いどころと処理スコープについて知識を得た上で、自分の作りたい処理にあてはめながら明確に切り分けられるようにしておくといいよ。&lt;/p&gt; &lt;p&gt;くわしくは、MSDNのここかな？&lt;/p&gt; &lt;p&gt;&lt;a href="http://msdn.microsoft.com/ja-jp/library/ms131102(SQL.90).aspx"&gt;データベース エンジンの .NET Framework プログラミング&lt;/a&gt;&lt;/p&gt; &lt;p&gt; &lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:fcce6cdf-cea5-4e2e-8c6d-fc2919b4d8ba" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb:nocontrols"&gt;Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlClient

Partial Public Class StoredProcedures 
    &amp;lt;Microsoft.SqlServer.Server.SqlProcedure&amp;gt; _
    Public Shared Sub GetVersion()
        Using connection As New SqlConnection("context connection=true")
            connection.Open()
            Dim command As New SqlCommand("SELECT @@VERSION", connection)
            SqlContext.Pipe.ExecuteAndSend(command)
        End Using
    End Sub
End Class&lt;/pre&gt;&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;これはMSDNサンプルの、SQLServerのバージョンを返すCLRストアドプロシジャ。この中にはSQLServer用CLRのために使われているオブジェクトや宣言が混じっていているのね。なので、デバッガでステップ実行しようとするといろいろと設定したりして、それでも止まらなかったりでなんかストレスｗ。&lt;/p&gt;
&lt;p&gt;でも実は、この処理はこう書いても動きは同じ。&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:d52ec49f-f72a-4ef5-863e-8a1aeaffdd5b" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb:nocontrols"&gt;Imports System
Imports System.Data
Imports System.Data.Sql
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Data.SqlClient

Partial Public Class StoredProcedures
    &amp;lt;Microsoft.SqlServer.Server.SqlProcedure()&amp;gt; _
    Public Shared Sub GetVersion()

        Dim versionGetter As New GetVersionInfo
        SqlContext.Pipe.Send(versionGetter.GetVersionFromServer)

    End Sub
End Class

Public Class GetVersionInfo
    Private _myConnString As String = "context connection=true"
    Property SQLConnectionString() As String
        Get
            Return _myConnString
        End Get
        Set(ByVal value As String)
            _myConnString = value
        End Set
    End Property
    Public Function GetVersionFromServer() As String

        Dim retStr As String

        Using connection As New SqlConnection(_myConnString)
            connection.Open()
            Using CommandStr = connection.CreateCommand
                CommandStr.CommandText = "SELECT @@VERSION"
                retStr = CommandStr.ExecuteScalar().ToString
            End Using
            connection.Close()
        End Using

        Return retStr

    End Function
End Class&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;で、こうなると、GetVersionInfoクラスとして分離されちゃうわけなので、こういうテストロジックが書けるようになる&lt;/p&gt;
&lt;div class="wlWriterEditableSmartContent" id="scid:812469c5-0cb0-4c63-8c15-c81123a09de7:9cffb8cd-b316-4901-a8e6-1d806d8cdc57" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;pre name="code" class="vb:nocontrols"&gt;Module Module1

    Public Sub main()

        Dim versionGetter As New GetVersionInfo

        versionGetter.SQLConnectionString = "接続文字列"
        versionGetter.GetVersionFromServer()

    End Sub

End Module
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これなら、デバッグできるじゃない？　で、GetVersionInfoクラスの処理の動作を確認できてから、実際のGetVersionストアドプロシジャを動かしてみれば、正常に動作しなかったとき、ストアドプロシジャ関連のところで問題があるのでは、と絞り込みやすくなる。サンプルは小さい処理だからいいけど、大きな処理になればなるほど、小さな単位で動作を保障できるように作っていくのがとっても大事だと思うの。&lt;/p&gt;
&lt;hr&gt;

&lt;p&gt;さて、今の現場も残り１日。いろんなことを勉強して、いろんなことを知って、いろんなことがあった。一つ一つが本当に大切なスキル。&lt;/p&gt;
&lt;p&gt;ありがとうございましたです。心から、感謝。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/170452.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>てすと☆番外</title><link>http://blogs.wankuma.com/esten/archive/2007/07/27/87296.aspx</link><pubDate>Fri, 27 Jul 2007 11:27:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2007/07/27/87296.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/87296.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2007/07/27/87296.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/87296.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/87296.aspx</trackback:ping><description>&lt;P&gt;もってけ！とは言わない（大汗）&lt;/P&gt;
&lt;P&gt;ネタ元は&lt;A href="http://blogs.wankuma.com/hirom/archive/2007/07/26/87200.aspx"&gt;こちら&lt;/A&gt;。片桐、一刀両断されてるし（笑）&lt;BR&gt;というか、なかせんせのおっしゃるとおりで、前提からしてベクトルずれてるやんという話だとおもってみるテスト&lt;BR&gt;なので日記であげてみるデスよ（＾＾；&lt;/P&gt;
&lt;P&gt;プログラミングして、コンパイルして、テストケース作って、仕様書書いて&amp;#8230;&amp;#8230;かくして出来上がってくる単体テストの精度や結果、それを証明する成果物は「動作結果を証明するもの」であって、「品質を証明するもの」とは別だと考えるので、ここでベクトルがすでにズレまくりんぐ。「テストしやすいコード」「テストしづらいコード」のこだわりって、必ずしも必要じゃないね的所がすでに（ｒｙ　開発規模が大きかったり、納期がタイトだったりするとそれよりも「確実に動作が確認できる」ことの方が先決になる場合もあるし（＾＾；&lt;BR&gt;　単体は所詮「単体」で、それがシステムの品質を証明することにはならない。多分ここもベクトルが違ってて&lt;FONT color=#ff0000&gt;私の考える品質は「システム」に対して掛かる修飾子（大汗）&lt;/FONT&gt;そのプログラムがそれこそ「単体」で「全体」の動きであるのなら、確かにその「単体の動作保証」＝「品質の動作保証」だと思うけれど、&lt;STRONG&gt;ぶっちゃけ、車の一部品の品質保証が取れたからって車全体の品質保証にはならない&lt;/STRONG&gt;。&lt;FONT color=#0000ff&gt;確実にいえるのは、その部品自身は発注されたとおりの動きがとれてますよってことが明らかになってます、証拠もありますですよ、ってことだけ。&lt;/FONT&gt;そこが私の中では前提になっちゃってたからベクトルずれズレなんだと思うのです。&lt;FONT color=#800080&gt;むぅ。&lt;/FONT&gt;&lt;BR&gt;　テストしやすいコードで作られたプログラム達が積み重なって寄り集まって、キング「テストしやすいコード」になったとして、それが「品質保証完璧だぜ」コードになるかというとそれは違う。それぞれが正しくても、全部を通したときにやっぱりおかしい、なんてことはザラで、そこには全体を通したときの「仕様バグ」や「方式バグ」が存在するわけだから、単体で品質保証＝システムの品質保証にはならないし、そういう考え方で進めちゃうとハマッチャウから危ないと思うの。&lt;BR&gt;　単体＝プログラムの動作が仕様とあっていることを証明するテスト≠品質保証のテスト　は私の中では変わらないですよ&amp;#8230;&amp;#8230;むぅ。じゃ、品質保証のテストは&amp;#8230;&amp;#8230;？　規模によるけど、総合テストはまさしくそのためのテストだと思ってますです。なので単体では無いのです&amp;#8230;&amp;#8230;。&lt;BR&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/87296.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>片桐　継（Tugu Katagiri）</dc:creator><title>単体テスト　レベル１　その２</title><link>http://blogs.wankuma.com/esten/archive/2007/07/04/83632.aspx</link><pubDate>Wed, 04 Jul 2007 13:37:00 GMT</pubDate><guid>http://blogs.wankuma.com/esten/archive/2007/07/04/83632.aspx</guid><wfw:comment>http://blogs.wankuma.com/esten/comments/83632.aspx</wfw:comment><comments>http://blogs.wankuma.com/esten/archive/2007/07/04/83632.aspx#Feedback</comments><slash:comments>261</slash:comments><wfw:commentRss>http://blogs.wankuma.com/esten/comments/commentRss/83632.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/esten/services/trackbacks/83632.aspx</trackback:ping><description>&lt;P&gt;　レベル０&lt;BR&gt;&lt;A href="http://blogs.wankuma.com/esten/archive/2007/06/18/81072.aspx"&gt;http://blogs.wankuma.com/esten/archive/2007/06/18/81072.aspx&lt;/A&gt;&lt;BR&gt;&lt;A href="http://blogs.wankuma.com/esten/archive/2007/06/19/81308.aspx"&gt;http://blogs.wankuma.com/esten/archive/2007/06/19/81308.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;ちょっと間が開いたのですが、&lt;A href="http://blogs.wankuma.com/esten/archive/2007/06/29/82841.aspx"&gt;前回の続き&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;「単体テストは全てのプログラムコードが処理されたことを証明し、書いていないプログラムコードの処理によって起きうる結果についても検証するテストである」&lt;/STRONG&gt;というお話をしました。つまり、&lt;FONT color=#0000ff&gt;書いていないプログラムコード≒例外処理&lt;/FONT&gt;、ということが言いたかった前述だったのですが、先輩方のプログラムコードから単体テストを任される場合、ほとんどの場合「これら例外処理がプログラムコードに含まれている」ことが多いことに気づくと思います。&lt;U&gt;例外処理を意識したプログラムコードが書けるかどうかも、プログラムスキルの一つといっても過言ではありません。&lt;/U&gt;レベル０でお話したとおり、「全てのプログラムコードの処理を確認する」単体テストを行えば必然的にこれら例外処理のロジックも通らなくてはならないのですから、&lt;FONT color=#ff0000&gt;例外処理を意識したプログラムは、テストを依頼する場合にテストする側が読み取らなくてはならない「書いていないプログラムコードの動作」について考慮する範囲が狭くなり、テストの難易度も下がる&lt;/FONT&gt;、と良い事づくしですね。&lt;/P&gt;
&lt;P&gt;と、ちょっと話はそれましたが（汗）、レベル１の最後として、例外処理のテストについてもう少し突っ込んでみましょう。&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;FONT color=#800080&gt;いかに例外処理を発生させるのか&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;　&lt;FONT color=#ffa500&gt;VisualStadio等のコードデバッグを可能とするツールの場合、イミディエイトを使うと簡単に実現できます&lt;/FONT&gt;。テスト直前のロジックでブレークポイントを設定し、止めた後に、判定の変数の中身を変更してしまうもしくは次の処理ロジックラインを目的の処理まで変更する、ことができるからです。また、UNIX、AIX等で使用される&lt;FONT color=#ffa500&gt;DBXも同じく変数の中身の変更（assign コマンド）を行うことで擬似的に処理例外を起こす事ができます&lt;/FONT&gt;。&lt;BR&gt;　&lt;U&gt;&lt;STRONG&gt;変数の中身の変更は、NULL値を設定、もしくはアドレスをNULL値に設定、とするとほとんどの場合例外処理を発生させることになるはずです&lt;/STRONG&gt;&lt;/U&gt;。&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#800080&gt;&lt;STRONG&gt;例外発生時の処理結果保存&lt;/STRONG&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;　さて、そうやって何とか発生させたエラーです、&lt;U&gt;確実に証拠を取りましょう。&lt;/U&gt;ダイアログが表示される場合にはダイアログをキャプチャーしてしまうのが最も手っ取り早く確実です。&lt;FONT color=#ff0000&gt;&lt;STRONG&gt;「ALT」＋&lt;/STRONG&gt;&lt;STRONG&gt;&lt;FONT color=#ff0000&gt;「PrintScreen」&lt;/FONT&gt;キーを同時押しすると、現在、最前面にあるダイアログだけが画像データとしてクリップボードに送られます。&lt;/STRONG&gt;&lt;/FONT&gt;ペイント等で貼り付けて確実に残しましょう。画面上にエラーが表示される場合のみの場合も同様です。大切なのは「こうなった時にはこういう結果が出る」ということを確実に証拠として残しておく、ということです。習慣づけておくと良いですよ。&lt;/P&gt;
&lt;P&gt;今度、レベル２はその単体テストで作成しておくべき「テスト仕様書」と「テスト結果」について、ちょこっと話&amp;#8230;&amp;#8230;してもいいかな？＜おい&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/esten/aggbug/83632.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>