t.me/atinfo_chat Telegram группа по автоматизации тестирования

Можно ли запускать тест только с одним набором данных из множества @DataProvider или @Factory

factory
design-patterns
framework
dataprovider
java
testng
Теги: #<Tag:0x00007f21dce01ac8> #<Tag:0x00007f21dce01820> #<Tag:0x00007f21dce01690> #<Tag:0x00007f21dce01550> #<Tag:0x00007f21dce01370> #<Tag:0x00007f21dce011e0>

(Necrosium) #1

Есть набор тестов для проверки оплаты/переводов.
Сценарий теста идентичный, меняются только данные. Использую @DataProvider, чтобы не дублировать код. Удобно, хорошо, понятно, компактно. Но, возникают случаи когда необходим запуск теста только с 1 набором данных (например перевод только с одной конкретной карты на другую), а не всех вариантов, прописанных в DataProvider.

Что делать в этом случае ???

я не нашел никакой информации о том, как можно запустить тесты использующие #dataprovider или #factory только с одним определенным набором данных, если их по факту прописано множество.

Ситуация возникла в связи с тем, что каждый перевод/оплата снимает комиссию и дополнительные ежедневные траты на тесты, которые сейчас проверять не нужно - бессмысленны.

С другой стороны, создавать 10 одинаковых тестовых методов, но с разными параметрами только для того, чтобы была возможность запустить какие-то из них точечно, а не скопом - мне такой подход тоже не нравится.

Подскажите какой-то наиболее правильный выход в данной ситуации ?


(Necrosium) #2

Нашел решение на оверфлоу. Копипастну, может кому полезно будет.

@DataProvider(name = "testInternational")
@Parameters({ "indices" })
public Object[][] testInternational(String indices) {
    // Instead of parameters, you can use sys env
    // String[] ids = System.getProperty("indices").split(":");
    String[] ids = indices.split(":"); 
    Object[][] values = new Object[][]{
            {"TC1", "Afghanistan",Abo},
            {"TC2", "Albanië",Abo},
            {"TC3", "Zwitserland",Abo},    
    };
    Object[][] result = new Object[ids.length][];
    for (int i=0; i<ids.length; i++) {
       result[i] = values[Integer.parseInt(ids[i]);
    }
    return result;
}
<test name="TestDataProvider">
    <parameter name="Browser" value="firefox /> 
    <classes>
        <class name="Test"/>
          <methods>
            <parameter name="indices" value="0:2" />
            <include name="testInternational" />
        </methods>
    </classes>
</test>

или

Можно использовать indices свойство @DataProvider . Можно сделать модификацию IAnnotationTransformer2 .

public class MyAnnotationTransformer implements IAnnotationTransformer2 {
  [...empty methods...]

  public void transform(IDataProviderAnnotation annotation, Method method) {
    if (method.getName().equals("testInternational")) {
      // Custom way to find indices (sys properties?)
      annotation.setIndices(Collections.asList(0, 2));
    }
  }
}

подключить лисенеры через suite.xml или @Listeners .


(Necrosium) #3

Странно, но почему-то не видит переменные в xml файле.

Проверил 3мя способами

вот xml файл:

xml

1. Через getProperty

dataprovider1

выполняю mvn clean test -Dsurefire.suiteXmlFiles=everyday.xml -Dmaven.surefire.debug

получаю

null

2. Через @Parameters

dataprovider2

получаю:

3. Тоже самое происходит если использую

ITestContext context
String[] ids = context.getCurrentXmlTest().getParameter("counter");

помогите пожалуйста. На пол дня завис уже и не могу понять, почему параметры не передаются из xml

в корне проекта лежит несколько testng.xml файлов, запуск делаю через
mvn clean test -Dsurefire.suiteXmlFiles=everyday.xml указывая явно.


(Necrosium) #4

Заработало вот так:

context

но через testng @parameters по прежнему не работает с ошибкой:

буду крайне благодарен за подсказку, почему не работает через @Parameters
если нужны какие-то еще данные/скрины - добавлю.


(Сергей Кузьмин) #5

@Necrosium так вы же уже научились получать counter через вызов context.getCurrentXmlTest() .getLocalParameters ? или нет ? или вам шашечки ? простите случай с передачей индекса из testng.xml в теле метода для фильтрования внутри другого метода
дающего параметры для данного и все это инлайн мне кажется немного пере-усложненным решением…


(Necrosium) #6

да, через .getLocalParameters() работает.

НЕ работает через аннотацию testng @parameter и я так и понял почему он выдает ошибку:


(Сергей Кузьмин) #7

приведите пожалуйста работающий пример c доступом к параметром заданным на уровне метода класса через context.getCurrentXmlTest().getLocalParameters()

и опишите еще раз какой конкретно эффект ожидаете оп применения @Parameters и @Test(dataProvider = ... одновременно и почему getLocalParameters не дает этого эффекта. обе аннотации служат для автоматичаского заполнения аргументов у метода и аргументы можно задать только один раз …


(Михаил Братухин) #8

Кстати, да. Можно сделать какой-то простой прототип проекта и выложить на гитхаб?
Я похожую проблему для junit у себя для параметризованных тестов решал, в смысле как сделать разовый запуск конкретных сценариев. Костыльное было и много нюансов, но вроде работало хорошо.


(Сергей Кузьмин) #9

я включу науку в https://github.com/sergueik/testng-dataproviders хотя лично мне непонятно чего суетиться так как вот это все работает уже

	@Test(enabled = true, dataProvider = "data provider with index")
	
	public void testIndex(Object expectedCount, Object searchKeyword)
			throws InterruptedException {
		dataTest(searchKeyword.toString(), expectedCount.toString());
	}

	// data provider with index
		@DataProvider(parallel = true, name = "data provider with index")
		public Object[][] dataProviderInline(ITestContext context) {

//		String indices = context.getCurrentXmlTest().getParameter("indices");
		String indices = context.getCurrentXmlTest().getLocalParameters()
				.get("indices");
		String[] ids = indices.split(":");
		Object[][] values = new Object[][] { { "junit", 100.0 },
				{ "junit-jupiter", 110.0 }, { "testng", 30.0 }, { "spock", 10.0 }, };
		Object[][] result = new Object[ids.length][];
		for (int i = 0; i < ids.length; i++) {
			result[i] = values[Integer.parseInt(ids[i])];
		}
		return result;
	}

<?xml version="1.0"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite 1" verbose="10" configfailurepolicy="continue">
<test name="Indexed Parameter Provider" preserve-order="true" parallel="false">
    <parameter name="indices" value="0:1"/>
    <parameter name="debug" value="true"/>
    <classes>
      <class name="com.github.sergueik.testng.FilterIndexTest">
        <methods>
          <include name="testIndex"/>
        </methods>
      </class>
    </classes>
  </test>
</suite>

производит

Added to parameter data index 0
Added to parameter data index 1
Running data test with 100.0, junit, allowing it to fail the assertion
Running data test with 110.0, junit-jupiter, allowing it to fail the assertion
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.294 sec - in TestSuite