18

でシステムからログアウトし、で@Afterブラウザを閉じるテスト スイートがあり@AfterClassます。@Ruleすべてのテスト方法でSeleniumを使用して、失敗したテストのスクリーンショットを撮ろうとしています。@Rulebefore every のみ実行されることを手動で確認しましたが、 afterと before@Beforeを設定したいと思います。簡単な解決策を見つけることができませんでした。どんな助けでも大歓迎です。@Test@After

public class MorgatgeCalculatorTest  {

@Before
public void before(){
    System.out.println("I am before");
}
@BeforeClass
public static void beforeclass(){
    System.out.println("I am beforeclass");
}
@Test
    public void test(){
        System.out.println("I am Test");
    }
@Test
public void test2(){
    System.out.println("I am Test2");
}
@After
    public void after(){
        System.out.println("I am after");
    }
@AfterClass
        public static  void afterclass(){
            System.out.println("I am afterclass");

}
@Rule
ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource();

static class ExpensiveExternalResource implements MethodRule  {
    public ExpensiveExternalResource(){
        System.out.println("I am rule");
    }

    @Override
    public Statement apply(Statement arg0, FrameworkMethod arg1, Object arg2) {
        // TODO Auto-generated method stub
        return null;
    }    
}               

私が得ている出力は

I am beforeclass
I am rule
I am before
I am Test
I am after
I am rule
I am before
I am Test2
I am after
I am afterclass
4

3 に答える 3

25

ルールの設定方法により、@before または @after の前にルールを指定することはできません。テスト メソッドに配置するシェルのようなルールを考えることができます。最初に実行されるシェルは @before/@after です。その後、@rules が適用されます。

やりたいことをすばやく実行するには、@After を完全に避けることです。メソッドが失敗した場合にスクリーンショットを撮り、コードの後に​​自分のメソッドを実行するようにルールを作成できます。@After ほどきれいではありませんが、機能します。(また、MethodRule が減価償却されたため、TestRule を実装しました)。

public class MortgageCalculatorTest  {
    @Before
    public void before(){
        System.out.println("I am before");
    }

    @BeforeClass
    public static void beforeclass(){
        System.out.println("I am beforeclass");
    }

    @Test
    public void test(){
        System.out.println("I am a Test");
    }

    @Test
    public void test2(){
        System.out.println("I am a Failed Test");
        fail();
    }

    @AfterClass
            public static  void afterclass(){
                System.out.println("I am afterclass");

    }

    @Rule
    public ExpensiveExternalResource ExpensiveExternalResource = new ExpensiveExternalResource();

    public static class ExpensiveExternalResource implements TestRule  {


      //  public ExpensiveExternalResource(){}


        public class ExpansiveExternalResourceStatement extends Statement{

            private Statement baseStatement;

            public ExpansiveExternalResourceStatement(Statement b){
                baseStatement = b;
            }

            @Override
            public void evaluate() throws Throwable {
                try{
                    baseStatement.evaluate();
                }catch(Error e){
                    System.out.println("I take a Screenshot");
                    throw e;   
                }finally{
                    after();
                }
            }

            //Put your after code in this method!
            public void after(){
                System.out.println("I am after");
            }
        }

        public Statement apply(Statement base, Description description) {
            return new ExpansiveExternalResourceStatement(base);

        }


    }
}

ルールのすべての作業はステートメントで行われます。org.junit.runners.model.Statement は、コードのバンドルを表すクラスです。したがって、ここでapplyメソッドは、シェルを配置するコードのバンドルを受け取ります。Apply は、指定したコードのバンドルを実行するステートメントを返し、そのステートメントを try/catch ステートメントで囲んでメソッドの失敗をキャッチします。

このメソッドの出力は次のとおりです。

I am beforeclass
I am before
I am a Test
I am after
I am before
I am a Failed Test
I take a Screenshot
I am after
I am afterclass

お役に立てれば!

于 2012-08-24T01:31:37.480 に答える
5
public class ScreenshotTestRule implements MethodRule {
    public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                try {
                    statement.evaluate();

                } catch (Throwable t) {
                    captureScreenshot(frameworkMethod.getName());
                    throw t; // rethrow to allow the failure to be reported to JUnit                     
                } finally {
                    tearDown();
                }
            }

            public void tearDown() {
                //logout to the system;
            }


            public void captureScreenshot(String fileName) {
                try {
                    new File("target/surefire-reports/screenshot").mkdirs(); // Insure directory is there
                    FileOutputStream out = new FileOutputStream("target/surefire-reports/screenshot/screenshot-" + fileName + ".png");
                    out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
                    out.close();
                } catch (Exception e) {
                    // No need to crash the tests if the screenshot fails
                }
            }
        };
    }
}
于 2012-08-27T14:42:29.487 に答える
1

ExternalResourceルールの使用についてはどうですか?
必要なものに十分な柔軟性を与えることができるようです。
これが必要なものではない場合は、外部リソースのソース コードを参照してください。
たとえば、テストの呼び出し後にのみ機能するルールを実装する方法は非常に理解できます。

于 2012-08-22T18:43:33.783 に答える