アプローチ1:プライベートメソッドをテストしない

JUnitとSuiteRunnerでプライベートメソッドをテストする
By Bill Venners
May24, 2004
概要

この記事では、Javaクラスでプライベートメソッドをテストするための四つの異なるアプローチを比較します。 JUnitの最初の使用は、ServiceUI APIの適合性テストキットを構築することでした。 適合性テストキットの目的は、同じAPIの代替実装がAPIの仕様と互換性があることを確認することです。 API仕様はAPIの実装ではなくAPIのパブリックインターフェイスのみを定義するため、適合性テストはパブリックインターフェイスのみを実行します。 言い換えれば、適合性テストは”ブラックボックス”テストです。 テスト対象のAPIは、外部インターフェイスは表示できますが、内部実装は表示できないブラックボックスとして扱います。 したがって、Java APIの適合性テストでは、テスト対象のパッケージとクラスのパブリックメンバーにのみアクセスする必要があります。 パッケージレベルのメンバー、protectedメンバー、またはprivateメンバーにアクセスする必要はありません。

後にJUnitを実際の単体テストを書くタスクに適用したとき、適合性テストとは対照的に、私はホワイトボックステストを書きたいと思っていました。 私は準拠テストでパブリックメソッドをテストしたかったのに対し、パッケージアクセスのための単体テストを書きたいと思っていました。

Daniel Steinbergは、並列ソースコードツリーを使用する一般的なJUnit技術を示しました。 これにより、テストコードと本番コードが明確に分離されました。 両方のソースツリーをクラスパスに配置することで、私のテストクラスはテスト対象のパッケージ内のパッケージレベルのメソッドとクラスにアクセ しかし、これはまだ私にプライベートメソッドをテストする問題を残しました。

私がDanielにプライベートメソッドのテストについて尋ねたとき、彼は優しく、プライベートメソッドを呼び出すpackage-accessとpublicメソッドをテストすることによ この答えは私を満足させるものではありませんでした、なぜなら、私は本当に私的な方法を直接テストする衝動を感じたからです。 私の最初の解決策は、このようなプライベートメソッドパッケージアクセスを作成することでした。 これは正常に動作しましたが、私は何とか少し汚れを感じさせました。 一般的に、簡単に単体テストできるようにインターフェイスを設計する方法を考えることは、より良いインターフェイスを設計するのに役立ちましたが、この場合、テスト可能にするためにデザインを少し悪化させていると感じました。

後にFrank Sommers、Matt Gerrans、そして私が最終的にArtima SuiteRunnerとしてリリースしたものの作成に参加することになったとき、私はJunitよりもsuiterunnerでプライベートメソッドのテス しかし、プライベートメソッドをテストするための様々なアプローチを調査した後、私はプライベートメソッドのテストをサポートするためにSuiteRunner したがって、JUnitまたはSuiteRunnerを使用しているかどうかにかかわらず、プライベートメソッドをテストするための同じ四つの基本的なア:

  • プライベートメソッドをテストしないでください。
  • メソッドパッケージにアクセス権を与えます。
  • ネストされたテストクラスを使用します。
  • 反射を使用します。

この記事では、Javaでプライベートメソッドをテストするためのこれらの四つのアプローチについて説明します。 私はそれぞれの長所と短所を見て、それぞれのアプローチを使用することが理にかなっているときにいくつかの光を当てるようにしようとします。

序文で言及したように、私は最初にDaniel Steinbergから私的な方法をテストするという私の時折の衝動を抑えるための助言を聞いた。 しかし、ダニエルは私が遭遇したこのアドバイスの源だけではありません。 これは、Javaコミュニティでは一般的な態度のようです。 たとえば、JUnit FAQには、

プライベートメソッドのテストは、再利用性を促進するためにそれらのメソッドを別のクラスに移動する必要があることを示して

Charles Millerは彼のウェブログで同様の視点を表明しました:

クラスの公開された(プライベートではない)インターフェイスの徹底的なテストスイートがある場合、それらのテストは、その性質上、クラス内のプライベートメソッドも動作することを確認する必要があります。 これが当てはまらない場合、またはパブリック呼び出し元のコンテキストからテストする必要があるほど複雑なプライベートメソッドがある場合は、

とDave ThomasとAndy Huntは、彼らの本Pragmatic Unit Testingで、次のように書いています:

一般的に、あなたはテストのためにカプセル化を壊したくありません(または、お母さんが言っていたように、”あなたの秘密を公開しないでください!”). ほとんどの場合、クラスのpublicメソッドを実行することでクラスをテストできるはずです。 プライベートまたは保護されたアクセスの背後に隠されている重要な機能がある場合、それはそこに別のクラスが出て行くのに苦労しているという

私はこのすべてのアドバイスを信じています。 ほとんどの場合、プライベートメソッドは、それらを呼び出すパッケージレベル、protected、およびpublicメソッドをテストすることによって間接的に、アプローチ1を介して最も効果的にテストすることができます。 しかし、必然的に、いくつかの状況では、プライベートメソッドを直接テストすることが正しいことだと感じる人もいます。

私の場合、私は多くの民間のユーティリティメソッドを作成する傾向があります。 これらのユーティリティメソッドは、多くの場合、インスタンスデータでは何もせず、渡されたパラメータを操作して結果を返すだけです。 私はそのようなメソッドを作成して、呼び出しメソッドを理解しやすくします。 これは、クラスの実装の複雑さを管理する方法です。 さて、すでに動作し、優れた単体テストのカバレッジを持つメソッドからプライベートメソッドを抽出すると、既存の単体テストで十分でしょう。 私はプライベートメソッドのためだけに単体テストを書く必要はありません。 しかし、呼び出しメソッドの前にprivateメソッドを記述したい場合、privateメソッドを記述する前に単体テストを記述したい場合は、privateメソッドを直接テス プライベートユーティリティメソッドの場合、JUnit FAQが言っているように、メソッドを直接テストする衝動は、”再利用性を促進するためにこれらのメソッドを別のクラスに移動する必要があることを示している”と感じていません。「これらのメソッドは、実際にはそれらが存在するクラスでのみ必要であり、実際には他のメソッドによってのみ呼び出されることがよくあります。

プライベートメソッドを直接テストしたいという衝動を感じることがあるもう一つの理由は、ユニットテストは、堅牢な部分からそのシステムを構築することによって、堅牢なシステムを達成するのに役立つと考える傾向があるということです。 各部分は、私が”単体テスト”を書くことができる”単位”です。”単体テストは、各ユニットが正しく機能していることを確認するのに役立ち、全体として正しく機能するシステムを構築するのに役立ちます。 私がJavaでプログラミングするときの観点から考える主な単位はクラスです。 私はクラスからシステムを構築し、単体テストは私のクラスが堅牢であるという自信を与えます。 しかし、ある程度私はpackage-access、protected、publicメソッドを構成するprivateメソッドについても同じように感じています。 これらの私用方法はそれぞれテストすることができる単位である。 このような単体テストは、privateメソッドが正しく動作しているという自信を与え、堅牢なpackage-access、protected、およびpublicメソッドを構築するのに役立ちます。

はじめに述べたように、methodsパッケージへのアクセス権を与えることは、JUnitでプライベートメソッドをテストするための最初のアプロー このアプローチは実際には正常に動作しますが、わずかなコストがかかります。 メソッドにプライベートアクセス指定子が表示されると、私が知りたいことがわかります—これはクラスの実装の一部です。 パッケージ内の別のクラスのクラスを使用しようとしているだけの場合、メソッドを無視できることを知っています。 メソッドの名前、ドキュメント、コードをより詳しく見ることで、パッケージアクセスメソッドについてこれを理解することができますが、privateという言葉はこれをはるかに効率的に伝達します。 さらに、私がこのアプローチで抱えている主な問題は哲学的です。 DaveとAndyが言っているように、私は「テストのためにカプセル化を破る」ことは気にしませんが、パッケージレベルのAPIを変更する方法でカプセル化を破 言い換えれば、私はクラスの非公開メソッドをテストすること、すなわち”ホワイトボックス”の単体テストを作成することに非常に熱心ですが、パッケー

アプローチ3:ネストされたテストクラスを使用する

プライベートメソッドをテストする第三のアプローチは、テストされている本番クラス内に静的テス ネストされたクラスが、それを囲むクラスのプライベートメンバーにアクセスできるとすれば、プライベートメソッドを直接呼び出すことができます。 静的クラス自体はパッケージアクセスであり、ホワイトボックステストの一部としてロードすることができます。

このアプローチの欠点は、ネストされたテストクラスにデプロイメントJARファイルでアクセスできないようにするには、それを抽出するために少し余分な作業を行う必要があることです。 また、テストコードを本番コードと同じファイルに混在させることを好まない人もいますが、他の人はそのアプローチを好むかもしれません。

アプローチ4:リフレクションを使う

プライベートメソッドをテストするための第四のアプローチは、Junitアドオンを書いたVladimir R.Bossicardによって提案されました。 昼食のある日、Vladimirはjava.lang.reflectAPIには、クライアントコードがJava仮想マシンのアクセス保護メカニズムを回避できるメソッドが含まれていることを啓発しました。 彼はまた、彼のJUnit Addonsプロジェクトには、この目的のためにreflection APIを使用するのを助けるためのクラスjunitx.util.PrivateAccessorが含まれていると私に言いました。 JUnit FAQは、Charlie HubbardとPrashant Dhotkeによって書かれたPrivilegedAccessorと呼ばれる同様のクラスを指しています。

プライベートメソッドのテストにリフレクション手法を使用する利点の一つは、テストコードと本番コードをきれいに分離できることです。 アプローチ3のように、テスト対象のクラス内にテストをネストする必要はありません。 むしろ、クラスのパッケージレベルのメソッドやパブリックメソッドを実行する他のテストと一緒に配置することができます。 また、テスト対象のクラスのAPIを変更する必要はありません。 アプローチ2とは異なり、プライベートメソッドはプライベートのままです。 アプローチ3とは異なり、パッケージアクセスレベルでネストされたクラスを追加する必要はありません。 このアプローチの主な欠点は、reflection APIを使用するため、テストコードがはるかに冗長であることです。 さらに、EclipseやIntelliJなどのリファクタリングIdeは、通常、reflection APIのメソッドに渡されるStringと呼ばれるメソッドの名前を変更するのに熟達していません。 したがって、リファクタリングIDEでプライベートメソッドの名前を変更した場合でも、テストコードで手動で変更する必要がある場合があります。

私の意見では、直接単体テストに値するプライベートメソッドの一例を与えるために、私はクラスmainメソッドからいくつかの機能を抽出しましたorg.suiterunner.RunnerRunner.mainコマンドライン引数を解析し、一連のテストを実行し、必要に応じてGUIを起動します。 私が抽出したメソッドparseArgsIntoListsは、SuiteRunnerアプリケーションへのコマンドライン引数の解析の作業の一部を行います。 ここで、このprivateメソッドを呼び出すpublicメソッドをテストするには、mainをテストする必要があります。 もちろん、メインはアプリケーション全体であり、この方法はテストするのがむしろ困難です。 実際、私はmainの既存のテストを持っていません。

この時点で、私がテスト駆動開発のスタイルで最初にテストを書いていたのであれば、単体テストを持たない解析コードを書くことになったのはど 主な理由は、私のテスト感染が段階的になったことです。 私はJUnitのことを聞いたり、テストを読んだりするずっと前に、実際に単体テストインフルエンザを捕まえました。 たとえば、C++でWindowsアプリケーションを構築していたときは、新しく実装されたメソッドをテストするためのコードを少し書いてから、そのコードを実行し、 この種の単体テストは堅牢性を達成するのに役立ちましたが、テスト自体は適切な動作をチェックしませんでした。 私はデバッガを介して観察することによって、自分自身で適切な動作を確認しました。 テストは自動化されていないため、後で再度実行できるように保存しませんでした。 私がTest Infectedを読んだとき、私はすぐにテストを自動化し、リファクタリング後に一種の回帰テストとしてそれらを維持する価値を見ましたが、長い間、最初にテストを書くことは私には意味がありませんでした。 私はデバッガでテストを実行したときだったので、機能を実装した後にテストを書きたかったのです。 SuiteRunnerの多くを開発している間、私が最初にテストを書かなかった第二の理由は、私自身のドッグフードを食べるために、SuiteRunner自身でSuiteRunnerのテストを書きたかった SuiteRunnerの基本的なAPIが解決するまで、私はテストを書くために使用したいテストツールキットを持っていませんでした。

その時以来、しかし、テストウイルスは私に強いホールドを取っている、と私は今、ほとんどの時間の最初の単体テストを書くことを好みます。 私はテスト駆動開発の主な利点として通常促進されるクリーンな設計で終わることがわかっているので、最初にテストを書くことをあまり好まない。 むしろ、私は最初にテストを書くことを好むのは、後でテストを書くという意図で、圧力の下でコードに飛び込むと、テストが実際には書かれないことが SuiteRunner自体は、その理由のために、この時点では非常に少数の単体テストを持っています。 ここにparseArgsIntoListsメソッドがあります:

 private static void parseArgsIntoLists(String args, List runpathList, List reportersList, List suitesList) { if (args == null || runpathList == null || reportersList == null || suitesList == null) { throw new NullPointerException(); } for (int i = 0; i < args.length; i++) { if (args.startsWith("-p")) { runpathList.add(args); runpathList.add(args); ++i; } else if (args.startsWith("-g")) { reportersList.add(args); } else if (args.startsWith("-o")) { reportersList.add(args); } else if (args.startsWith("-e")) { reportersList.add(args); } else if (args.startsWith("-f")) { reportersList.add(args); reportersList.add(args); ++i; } else if (args.startsWith("-r")) { reportersList.add(args); reportersList.add(args); ++i; } else if (args.startsWith("-s")) { suitesList.add(args); do { ++i; suitesList.add(args); } while (i + 1 < args.length); } else { throw new IllegalArgumentException("Unrecognized argument: " + args); } } }

SuiteRunnerのコマンドラインには、suiterunnerがテストを実行するために使用する三つのタイプの情報が含まれています。runpath、reporters、およびsuites。 parseArgsIntoListsメソッドは、単にStringの配列として渡された引数を通過し、各引数をrunpathListreportersList、およびsuitesListのいずれかのリストに配置します。

このプライベートメソッドのテストを書く前に、Charles Millerが彼のウェブログに書いたように、この単体テストを書く衝動がコードの匂いを表しているかどうか JUnit FAQが示唆しているように、再利用性を促進するためにparseArgsIntoListsを別のクラスに移動する必要があることを示していますか? DaveとAndyは、そこに別のクラスが出て行くのに苦労しているという警告サインを言うでしょうか? まあ、多分。 解析作業を実行するいくつかの静的メソッドのみを保持するArgumentsParserクラスを納得して作成することができます。 ArgumentsParserクラスとそれに含まれるメソッドの両方がパッケージアクセスである可能性があり、テストが容易になります。 しかし、それはちょうど私には右に感じていません。 これらのメソッドはRunner.mainによってのみ呼び出されます。 彼らは明らかに私にとって私的な方法のように感じます。 私がそれらをArgumentsParserクラスに移動する唯一の理由は、それらをテストできるようにすることです。 私は実際にアプローチ番号2を使用しています:private methods package accessを作成します。

代わりに、この例では、アプローチ番号4を取り、反射を使用することにしました。 私はVladimir Bossicardのjunitx.utils.PrivateAccessorとCharlie HubbardとPrashant DhotkeのPrivilegedAccessorの両方を見ましたが、どちらも私が望んでいたように私を助けてくれなかったと判断しました。 一つには、これらのクラスは両方とも、フィールドが正しく設定されていることを確認するためにフィールドをテストする機能を持っています。 まだ私は単体テストからプライベートフィールドに直接アクセスする衝動を感じたことはありません。 私はプライベートユーティリティの方法をテストできるようにしたいだけです。 しかし、私がこれらの2つのクラスで抱えていた主な問題は、リフレクションを介してプライベートメソッドを呼び出そうとしたときにスローされる 各クラスには、リフレクションを使用してメソッドを呼び出すジョブを持つ1つ以上のメソッドがあります。 PrivilegedAccessorの2つのinvokeMethodメソッドは、throws句で宣言された3つのチェック例外NoSuchMethodExceptionIllegalAccessException、およびInvocationTargetExceptionを含む、例外を呼び出し元に返します。 対照的に、PrivateAccessorの2つのinvokeメソッドはInvocationTargetExceptionをキャッチし、呼び出されたメソッドによってスローされる実際の例外であるターゲット例外を抽出してスローします。 その後、他の例外をキャッチし、NoSuchMethodExceptionをスローします。 私は、例外を処理する一般的な方法はテストを失敗させることだと思ったので、PrivilegedAccessor.invokeMethodの呼び出し元が常に3つのチェックされた例外を処理する必要があ 私はまた、PrivateAccessor.invokeが例外処理ポリシーで潜在的に有用なスタックトレース情報を捨てていることを懸念していました。 私が本当に望んでいたのは、リフレクションでプライベートメソッドを呼び出そうとしたメソッドでした。InvocationTargetException以外のスローされた例外を未チェックのTestFailedExceptionにラップしました。 ほとんどの場合、この例外はテストを失敗させます。 例外がスローされることを期待していたテストでは、InvocationTargetExceptionに含まれる例外を抽出し、正確性をテストすることができます。

ということで、invokeStaticMethodと書きました。 setAccessible(true)呼び出しは、プライベートメソッドをクラスの外部から呼び出すことを可能にするものです。 JUnitで使用する対応するinvokeStaticMethod実装では、TestFailedExceptionではなくAssertionFailedErrorがスローされます。 ここにコードがあります:

 private static void invokeStaticMethod(Class targetClass, String methodName, Class argClasses, Object argObjects) throws InvocationTargetException { try { Method method = targetClass.getDeclaredMethod(methodName, argClasses); method.setAccessible(true); method.invoke(null, argObjects); } catch (NoSuchMethodException e) { // Should happen only rarely, because most times the // specified method should exist. If it does happen, just let // the test fail so the programmer can fix the problem. throw new TestFailedException(e); } catch (SecurityException e) { // Should happen only rarely, because the setAccessible(true) // should be allowed in when running unit tests. If it does // happen, just let the test fail so the programmer can fix // the problem. throw new TestFailedException(e); } catch (IllegalAccessException e) { // Should never happen, because setting accessible flag to // true. If setting accessible fails, should throw a security // exception at that point and never get to the invoke. But // just in case, wrap it in a TestFailedException and let a // human figure it out. throw new TestFailedException(e); } catch (IllegalArgumentException e) { // Should happen only rarely, because usually the right // number and types of arguments will be passed. If it does // happen, just let the test fail so the programmer can fix // the problem. throw new TestFailedException(e); } }

次に、テストしたい特定のプライベートメソッドを呼び出す便利なメソッドを作成しました:

 private static void invokeParseArgsIntoLists(String args, List runpathList, List reportersList, List suitesList) throws InvocationTargetException { // Purposely pass null values to the method, to make sure it throws // NullPointerException Class argClasses = {String.class, List.class, List.class, List.class }; Object argObjects = {args, runpathList, reportersList, suitesList }; invokeStaticMethod(Runner.class, "parseArgsIntoLists", argClasses, argObjects); }

最後に、私はこのように、あまりにも多くの余分な混乱なしにプライベートメソッドに対するテストを書くことができました:

 public void testParseArgsIntoLists() throws InvocationTargetException { String args = new String; List runpathList = new ArrayList(); List reportersList = new ArrayList(); List suitesList = new ArrayList(); try { invokeParseArgsIntoLists(null, runpathList, reportersList, suitesList); fail(); } catch (InvocationTargetException e) { // throw the InvocationTargetException unless the target // exception is NullPointerException, which is expected Throwable targetException = e.getTargetException(); if (!(targetException instanceof NullPointerException)) { throw e; } } try { invokeParseArgsIntoLists(args, null, reportersList, suitesList); fail(); } catch (InvocationTargetException e) { // throw the InvocationTargetException unless the target // exception is NullPointerException, which is expected Throwable targetException = e.getTargetException(); if (!(targetException instanceof NullPointerException)) { throw e; } } try { invokeParseArgsIntoLists(args, runpathList, null, suitesList); fail(); } catch (InvocationTargetException e) { // throw the InvocationTargetException unless the target // exception is NullPointerException, which is expected Throwable targetException = e.getTargetException(); if (!(targetException instanceof NullPointerException)) { throw e; } } try { invokeParseArgsIntoLists(args, runpathList, reportersList, null); fail(); } catch (InvocationTargetException e) { // throw the InvocationTargetException unless the target // exception is NullPointerException, which is expected Throwable targetException = e.getTargetException(); if (!(targetException instanceof NullPointerException)) { throw e; } } args = new String; args = "-p"; args = "\"mydir\""; args = "-g"; args = "-f"; args = "test.out"; args = "-s"; args = "MySuite"; runpathList.clear(); reportersList.clear(); suitesList.clear(); invokeParseArgsIntoLists(args, runpathList, reportersList, suitesList); verify(runpathList.size() == 2); verify(runpathList.get(0).equals(args)); verify(runpathList.get(1).equals(args)); verify(reportersList.size() == 3); verify(reportersList.get(0).equals(args)); verify(reportersList.get(1).equals(args)); verify(reportersList.get(2).equals(args)); verify(suitesList.size() == 2); verify(suitesList.get(0).equals(args)); verify(suitesList.get(1).equals(args)); args = new String; args = "-p"; args = "\"mydir\""; args = "-e"; args = "-o"; args = "-r"; args = "MyCustomReporter"; args = "-s"; args = "MySuite"; args = "MyOtherSuite"; runpathList.clear(); reportersList.clear(); suitesList.clear(); invokeParseArgsIntoLists(args, runpathList, reportersList, suitesList); verify(runpathList.size() == 2); verify(runpathList.get(0).equals(args)); verify(runpathList.get(1).equals(args)); verify(reportersList.size() == 4); verify(reportersList.get(0).equals(args)); verify(reportersList.get(1).equals(args)); verify(reportersList.get(2).equals(args)); verify(reportersList.get(3).equals(args)); verify(suitesList.size() == 3); verify(suitesList.get(0).equals(args)); verify(suitesList.get(1).equals(args)); verify(suitesList.get(2).equals(args)); args = new String; args = "-p"; args = "\"serviceuitest-1.1beta4.jar myjini http://myhost:9998/myfile.jar\""; args = "-g"; args = "-s"; args = "MySuite"; args = "MySecondSuite"; args = "MyThirdSuite"; args = "MyFourthSuite"; args = "MyFifthSuite"; args = "MySixthSuite"; runpathList.clear(); reportersList.clear(); suitesList.clear(); invokeParseArgsIntoLists(args, runpathList, reportersList, suitesList); verify(runpathList.size() == 2); verify(runpathList.get(0).equals(args)); verify(runpathList.get(1).equals(args)); verify(reportersList.size() == 1); verify(reportersList.get(0).equals(args)); verify(suitesList.size() == 7); verify(suitesList.get(0).equals(args)); verify(suitesList.get(1).equals(args)); verify(suitesList.get(2).equals(args)); verify(suitesList.get(3).equals(args)); verify(suitesList.get(4).equals(args)); verify(suitesList.get(5).equals(args)); verify(suitesList.get(6).equals(args)); }

結論

アプローチ1、プライベートメソッドを間接的にテストするには、それらを呼び出すパッケージレベル、protected、publicメソッドをテストすることが最善のアプロー プライベートメソッドを直接テストしたい場合は、リフレクションを使用してプライベートメソッドをテストしますが、面倒ですが、テストコードと実 ただし、パッケージアクセスをテストしたい特定のプライベートメソッドを作成しても構わない場合は、アプローチ2を使用できます。 または、テスト中の本番クラス内にネストされたテストクラスを配置しても構いませんが、アプローチ3では、少なくともプライベートメソッドをプ

完璧な答えはありません。 しかし、アプローチ4を採用すると、最終的には再利用できるinvokeStaticMethodような少数のメソッドになります。 プライベートメソッドに対してinvokeParseArgsIntoListsのような便利なメソッドを記述すると、プライベートメソッドに対するテストを簡単に書くことができます。

1. ServiceUI APIは、ユーザー-インターフェースをJiniサービスに接続する標準的な方法を定義しています:
http://www.artima.com/jini/serviceui/index.html

2. ダニエル*スタインバーグは、現在の編集長ですJava.NET:
http://www.java.net/

3. Artima SuiteRunnerは、無料のオープンソーステストツールキットとJUnitランナーです:
http://www.artima.com/suiterunner/index.html

4.JUnit faqプライベートメソッドのテストに関する質問:
http://junit.sourceforge.net/doc/faq/faq.htm#tests_10

5. プライベートメソッドのテスト(それをしないでください)、Charles Millerによるウェブログ投稿:
http://fishbowl.pastiche.org/2003/03/28/testing_private_methods_dont_do_it

6. Andy HuntとDave ThomasはPragmatic Unit Testingの著者であり、Pragmatic Storeで入手できます。

7. JUnit Addonsは、Vladimar R.Bossicardによって作成されたJUnitのヘルパークラスのコレクションです:
http://sourceforge.net/projects/junit-addons

PrivateAccessor プライベートメンバーのテストを容易にするJUnitアドオンのクラスです:
http://junit-addons.sourceforge.net/junitx/util/PrivateAccessor.html

9.プライベートメンバーにアクセスするために使用できるPrivilegedAccessorクラス:
http://groups.yahoo.com/group/junit/files/src/PrivilegedAccessor.java

10. テスト駆動型開発の例は、Kent Beck氏がテストファースト手法について説明しています:
http://www.amazon.com/exec/obidos/ASIN/0321146530/

11. テスト感染、ケント*ベックとエーリッヒ*ガンマによって、世界にJUnitを導入しました:
http://junit.sourceforge.net/doc/testinfected/testing.htm

Unit Testing Private Methods,Ted GrahamによるnUnitに関するウェブログ投稿:
http://weblogs.asp.net/tgraham/archive/2003/12/31/46984.aspx

単体テストのためのJavaのアクセス保護を破壊する、O’Reilly OnJava.com ロス-バートンの記事:
http://www.onjava.com/pub/a/onjava/2003/11/12/reflection.html

この記事のコードスニペットが使用されたクラスRunnerSuiteは、その全体がここに表示されます:
http://www.artima.com/suiterunner/privateExample.html

JUnitをリファクタリングした理由
http://www.artima.com/suiterunner/why.html

Artima SuiteRunnerチュートリアル,Artima SuiteRunnerを使用した適合性と単体テストの構築:
http://www.artima.com/suiterunner/tutorial.html

Artima SuiteRunnerの概要,ディストリビューションに含まれる簡単な例を実行する方法:
http://www.artima.com/suiterunner/start.html

Artima SuiteRunnerでJUnitテストを実行する方法,Artima SuiteRunnerをJUnitランナーとして使用して既存のJUnitテストスイートを実行する方法:
http://www.artima.com/suiterunner/junit.html

アルティマスイーターランナーホームページ:
http://www.artima.com/suiterunner/index.html

Artima SuiteRunnerダウンロードページ(ログオンする必要がありますArtima.com リリースをダウンロードするには):
http://www.artima.com/suiterunner/download.jsp

SuiteRunnerフォーラム:
http://www.artima.com/forums/forum.jsp?forum=61

話を戻せ!

意見はありますか? 読者はすでにこの記事について26のコメントを投稿しています。 なぜあなたを追加しないのですか?

著者について

Bill VennersはArtima Software,Inc.の社長です。 と編集長のArtima.com彼は、Javaプラットフォームのアーキテクチャと内部のプログラマ指向の調査である”Inside The Java Virtual Machine”という本の著者です。 JavaWorld誌での彼の人気のあるコラムは、Javaの内部、オブジェクト指向デザイン、Jiniをカバーしていました。 ビルは創業以来、Jiniコミュニティで活発に活動しています。 彼は、ServiceUI APIを生成したJiniコミュニティのServiceUIプロジェクトを率いました。 ServiceUIは、ユーザインタフェースをJiniサービスに関連付ける事実上の標準的な方法となり、Jiniの決定プロセスを通じて承認された最初のJiniコミュニティ標準とな ビルはまた、Jiniコミュニティの最初の技術監督委員会(TOC)の選出されたメンバーとして機能し、この役割では、コミュニティのガバナンスプロセスを定義 彼は現在、建物に彼のエネルギーのほとんどを費やしていますArtima.com 開発者のためのこれまで以上に有用なリソースに。

You might also like

コメントを残す

メールアドレスが公開されることはありません。