Testng: 継承されたテストメソッドは、期待されるグループの動作を取得しません

作成日 2012年03月01日  ·  8コメント  ·  ソース: cbeust/testng

次のテストクラスを検討してください。

<strong i="6">@Test</strong>
public abstract class ParentTest {
    public void parentTestMethod() {
    }
}

@Test(groups = "myGroup")
public class ChildTest extends ParentTest {
    public void childTestMethod() {
    }
}

このテスト(ChildTest)を実行するとき、両方のテストメソッド(childTestMethodとparentTestMethod)がグループ 'myGroup'に属していることを期待します。 どうやらこれは実際の動作ではありません(バージョン6.4でテスト済み)。

私はこの問題を調査するためにいくつかのコードをまとめました:

TestNGMethodFinder testNGMethodFinder = new TestNGMethodFinder(new RunInfo(), new JDK15AnnotationFinder(new DefaultAnnotationTransformer()));
ITestNGMethod[] testMethods = testNGMethodFinder.getTestMethods(ChildTest.class, new XmlTest());
for (ITestNGMethod testMethod : testMethods) {
    String[] groups = testMethod.getGroups();
    System.out.println(testMethod + " groups:" + Arrays.toString(groups));
}

このコードの実行からの出力:

ChildTest.childTestMethod()[pri:0, instance:null] groups:[myGroup]
ParentTest.parentTestMethod()[pri:0, instance:null] groups:[]

TestNGソースコードを調べたところ、この動作はメソッドorg.testng.internal.BaseTestMethod#initGroups(Class>)に起因しているようです。 正確には、次のステートメントがこのかなり奇妙な動作の原因だと思います。

ITestOrConfiguration classAnnotation = (ITestOrConfiguration) getAnnotationFinder().findAnnotation(getMethod().getDeclaringClass(), annotationClass);

この問題を修正するために、このステートメントを次のように変更できます。

ITestOrConfiguration classAnnotation = (ITestOrConfiguration) getAnnotationFinder().findAnnotation(getInstance().getClass(), annotationClass);

しかし、これが問題を解決する正しい方法であるかどうかはわかりません。 最終的な影響もありません...

groups inheritance

全てのコメント8件

問題が発生しましたが、残念ながらあなたの提案はうまくいきません。 アノテーションは初期化フェーズで解決されるため、解決するのは少し難しいです。つまり、親の@Testアノテーションが解析されると、子アノテーションがさらにグループを追加するという事実については明らかに何も知りません...

セドリック、この問題に関する迅速なフィードバックをありがとうございます。 「解決するのは少し難しい」とおっしゃっていますが、近い将来、この問題が解決される可能性はないと思いますか? 考えられる回避策について考えていただけますか?

つまり、グループ解決が実行されたとき、テストクラスはまだインスタンス化されていないため、parentTestMethod()を見ると、そのメソッドをこのグループに入れることができるChildTestのインスタンスがありません。

グループの解決は純粋に静的ですが、上記の例は動的にしか解決できません。

これは理にかなっていますか?

私もこの振る舞いを見てきました。 グループフィルターを使用せずにテストを実行すると、すべてが合格しますが、グループを使用して実行すると、失敗します。 テストクラスが他のテストクラスから継承していることが原因の場合もありますが、POJOテストクラスがあり、 @BeforeMethod @AfterMethodメソッドと

ところで、私の解決策は、もちろんすべての状況で機能するとは限らない除外グループを使用することです。 @cbeust 、これに対する適切な解決策に関する作業はありましたか?

1年以上経っても、これはまだ機能しません。
@cbeust IMHOこれは意味がありません。親クラスは抽象であるため、そのグループ解決はテストクラスの具体的なインスタンスに基づいている必要があります。

FWIW私もこれに遭遇しました。

サブクラスTestannoationのグループを使用するカスタムメソッドセレクターを作成しました

/* *****************************************************************************
 * Copyright 2017 VMware, Inc.  All rights reserved. VMware Confidential
 * ****************************************************************************/
package com.vmware.cloud.systemtests.util;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;
import org.testng.IMethodSelector;
import org.testng.IMethodSelectorContext;
import org.testng.ITestNGMethod;
import org.testng.annotations.Test;
import org.testng.xml.XmlTest;

/**
 * Selector that uses groups in subclass <strong i="6">@Test</strong> annotations to determine if methods should be included
 */
public class SubclassAwareXmlMethodsSelector implements IMethodSelector {
    <strong i="7">@Override</strong>
    public boolean includeMethod(IMethodSelectorContext context, ITestNGMethod method, boolean isTestMethod) {
        XmlTest xmlTest = method.getXmlTest();
        if (xmlTest == null) {
            return method.isAlwaysRun();
        }
        Class realTestClass = isTestMethod ? method.getTestClass().getRealClass() : method.getRealClass();
        Test testClassAnnotation = (Test) realTestClass.getAnnotation(Test.class);
        String[] classAnnotationGroups = testClassAnnotation != null ? testClassAnnotation.groups() : new String[0];
        List<String> groups = Arrays.asList(ArrayUtils.addAll(classAnnotationGroups, method.getGroups()));

        context.setStopped(true);
        if (groups.size() == 0 && xmlTest.getIncludedGroups().isEmpty()) {
            return true;
        } else if (groups.size() > 0 && xmlTest.getExcludedGroups().stream().anyMatch(groups::contains)) {
            return false;
        } else if (groups.size() > 0 && xmlTest.getIncludedGroups().stream().anyMatch(groups::contains)) {
            return true;
        } else {
            return method.isAlwaysRun();
        }
    }

    <strong i="8">@Override</strong>
    public void setTestMethods(List<ITestNGMethod> list) {
    }
}
このページは役に立ちましたか?
0 / 5 - 0 評価