Вариант использования, который вы ищете, своего рода побеждает цель SoftAssert
.SoftAssert
был в основном введен в TestNG, так что вы можете собрать все утверждения в одном методе @Test
, но завершить тестовый метод только в конце (при вызове assertAll()
).
ДанныеУправляемый @Test
метод - это, в основном, @Test
метод, который выполняется "n" раз (каждая итерация выполняется с различным набором данных).Поэтому нет смысла пытаться использовать SoftAssert
и вызывать его assertAll()
на последней итерации.Потому что, если вы это сделаете, это в основном сводится к тому, что только последняя итерация завершится неудачей.
Так что если вы смотрите на повторный запуск тестов с использованием testng-failed.xml
, то он будет содержать только индекс последнейитерация (что является абсурдом, потому что это была не последняя итерация, которая действительно провалилась).
Итак, в идеале, вы должны использовать SoftAssert
только в рамках одной итерации.Это означает, что вы создаете экземпляр объекта SoftAssert
в методе @Test
, вызываете группу вызовов assertXXX()
, а в конце метода вы вызываете assertAll()
.
Все сказано и сделано, есливы все еще ищете образец, который покажет вам, как это сделать, вот пример.
Сначала мы определим интерфейс, который позволит мне установить размер предоставленного поставщиком данных набора данных в качестве атрибута для теста.класс.
public interface IDataSet {
void setSize(int size);
}
Тестовый класс выглядит следующим образом
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.TestInstance;
import org.testng.asserts.SoftAssert;
import java.util.concurrent.atomic.AtomicInteger;
public class SoftAssertDemo implements IDataSet {
private int size;
private SoftAssert assertion = new SoftAssert();
private AtomicInteger counter = new AtomicInteger(1);
@Override
public void setSize(int size) {
this.size = size;
}
@Test(dataProvider = "dp")
public void testMethod(int number) {
if ((number % 2) == 0) {
assertion.fail("Simulating a failure for " + number);
}
if (counter.getAndIncrement() == size) {
assertion.assertAll();
}
}
@DataProvider(name = "dp")
public Object[][] getData(@TestInstance Object object) {
Object[][] data = new Object[][] {{1}, {2}, {3}, {4}, {5}};
if (object instanceof IDataSet) {
((IDataSet) object).setSize(data.length);
}
return data;
}
}
Предостережения при таком подходе:
- Тестовый класс должен иметь только один
@DataProvider
метод в нем, потому что поставщик данных передает размер набора данных обратно в экземпляр класса теста.Поэтому, если у вас есть 2 или более провайдера данных, есть вероятность продолжения гонки данных, при которой один провайдер данных перезаписывает другого. - Если вы хотите разместить двух или более провайдеров данных, вам потребуетсяубедитесь, что эти
@Test
методы, поддерживаемые поставщиками данных, не работают параллельно.