Рассмотрим следующие тестовые классы:
<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);
но я не уверен, что это правильный способ решить проблему. И никаких возможных последствий ....
Я вижу проблему, и ваше предложение, к сожалению, не работает. Это немного сложно решить, потому что аннотации разрешаются на этапе инициализации, а это означает, что при анализе родительской аннотации дочерняя аннотация добавит к ней больше групп ...
Седрик, спасибо за оперативный отзыв по этому вопросу. Вы говорите «это немного сложно решить», значит ли это, что вы не думаете, что у этого вопроса будет шанс решить в ближайшем будущем? Можете ли вы придумать возможные обходные пути?
Я имел в виду следующее: когда выполняется разрешение группы, тестовый класс еще не создан, поэтому, когда я смотрю на parentTestMethod (), у меня нет экземпляра ChildTest, который позволил бы мне поместить этот метод в эту группу.
Разрешение группы чисто статическое, в то время как приведенный выше пример может быть разрешен только динамически.
Имеет ли это смысл?
Я тоже видел такое поведение. Когда я запускаю свои тесты без группового фильтра, все проходит, но при работе с группами ничего не получается. В некоторых случаях это происходит из-за того, что мой тестовый класс наследуется от другого тестового класса, но в других случаях у меня есть тестовые классы POJO, и кажется, что мои методы @BeforeMethod
и @AfterMethod
не вызываются должным образом.
Кстати, мое решение - использовать исключенные группы, которые, конечно, не будут работать во всех ситуациях. @cbeust , была ли работа над подходящим решением для этого?
Прошло больше года, а это все еще не работает.
@cbeust IMHO это не имеет никакого смысла: поскольку родительский класс является абстрактным, его групповое разрешение должно основываться на конкретном экземпляре тестового класса.
FWIW Я тоже столкнулся с этим.
Я создал настраиваемый селектор методов, который использует группы из аннотации подкласса Test
/* *****************************************************************************
* 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) {
}
}