2011-12-19 14 views
10

私は、JUnit 4.8.2を使用して一連のSeleniumテスト(実際にはWebDriverがサポートするSeleniumテスト)を推進しています。私は、テストがアサーションに失敗すると自動的にブラウザのスクリーンショットを取るテストをしたいと思います。すべてのテストはSeleniumBaseTestCaseから継承し、大部分はさらにSeleniumBastTestCaseWithCompany(これは@Before@Afterのメソッドを使用してセレンを介して共通のテストデータを作成し、クリーンアップします)から継承します。テストが失敗した後で、@Afterメソッドの前にJUnit 4.8でコードを実行するにはどうしたらいいですか?

私は、スクリーンショットを撮るためにTestWatchmanfailedメソッドをオーバーライドし、SeleniumBaseTestCase@RuleようTestWatchmanのサブクラスを追加しようとしました。問題は、TestWatchmanfailedメソッドが呼び出される前に、テストデータをクリーンアップするメソッド@Afterが実行されているため、スクリーンショットはすべて、クリーンアップの最後のステップであり、失敗したテストではありません。それに少しを探し

は、それが思わTestWatchmanを残し、@Afterメソッドを呼び出しますTestWatchmanapply方法だけ渡さStatement呼び出す年代は法を評価する(のみ公開されたメソッド)、(または任意の他のRule)ノーチャンステストの実行と@Afterメソッドの間にコードを挿入することができます。

私はまた、カスタム@AfterFailureでアノテート方法は(そのスクリーンショットは、このような@AfterFailure方法で撮影することができます)@Afterメソッドの前に実行されるように作成されたStatement Sを変更するカスタムRunnerを作成するアプローチを見て、これきましたBlockJUnit4ClassRunnerwithAftersメソッドをオーバーライドすることに依存しています。これは非推奨で、プライベートになるため、documentationに従って、代わりにルールを使用することを提案しています。

@Rule lifecycleについての別の答えが見つかりました。このようなことはJUnit 4.8では簡単ではないかもしれませんが、JUnit 4.10では可能かもしれません。それが正しければ十分です、私はちょうどその最初の確認をしたいと思います。

私が欲しいものを達成することができる、エレガントで将来的な方法についての考えは、非常に高く評価されます。

答えて

7

あなたは分析の対象です。ルールの前に@Beforesと@Aftersがステートメントのリストに追加されます。 @Before@Ruleの後に実行され、@After@Ruleの前に実行されます。これをどのように修正するかは、SeleniumBaseTestCaseWithCompanyの柔軟性に依存します。

最も簡単な方法は、@Before/@Afterのメソッドを削除し、ExternalResourceに置き換えることです。

externalResource before 
testHere 
externalResource after 

このフィールドは、お使いのベースクラスに入れることができるので、それは/オーバーライドされた継承されます:これは与え

public class BeforeAfterTest { 
    @Rule public TestRule rule = new ExternalResource() { 
     protected void before() throws Throwable { System.out.println("externalResource before"); } 
     protected void after() { System.out.println("externalResource after"); } 
    }; 

    @Test public void testHere() { System.out.println("testHere"); } 
} 

:これはのようになります。 @RuleChain(4.10ではなく、4.8)を使用して、ルールを注文することができるので、@Afterとルールの間の注文に関する問題は消え去ります。

を変更できない場合は、BlockJUnit4ClassRunnerを拡張できますが、Aftersを上書きしないで、BlockJUnit4ClassRunner#methodBlock()を上書きしてください。これでsuperを呼び出すことができます。methodBlockを呼び出し、必要に応じてステートメントの順序を変更します[*]。

[*]コードをコピーして行を並べ替えることはできますが、withRulesはプライベートなので、サブクラスから呼び出すことはできません。

+0

JUnitをアップグレードする方法があると思います.4.8.2で特に満足できる解決策はありません。 私は 'SeleniumBaseTestCase'でスクリーンショットを取得するために保護されたTestWatcherを持っており、それを唯一のルールとしてRuleChainを持っています。次に、 'SeleniumBaseTestCaseWithCompany'で私は会社を作成/削除するExternalResourceを持っています。そして、スーパークラスのRuleChainをシ​​ャドウし、スクリーンショットと作成/削除ルールの両方を注文します。ありがとう、うまく動作するようです。 – Rowan

+0

ちょうどメモ。 4.11では、メソッドに@Ruleを指定できるので、フィールドをシャドウするのではなく、そのメソッドをオーバーライドすることができます。しかし、4.11はまだリリースされていない。 –

+0

ああ、知っておきたい - 変数をシャドーイングするのは私が不安だった唯一のビットだった... – Rowan

関連する問題