2017-02-21 31 views
1

У меня есть dataProvider, который считывает данные из текстового файла.Testng split dataProvider между параллельными методами

@DataProvider (name = "dynamicDP", parallel = true) 
    public Iterator<Object> matchIDs() throws IOException { 
     final List<Object> list = new ArrayList<>(); 

     for (final String line: Files.readAllLines(Paths.get("C:\\mypath"), 
      StandardCharsets.UTF_8)) 
      list.add(new Object[]{ line}); 

     return list.iterator();  
} 

Мой текстовый файл действительно просто он содержит только эти данные ниже (каждой пары букв на отдельной строке):

AA BB CC DD EE FF GG HH II KK

Вот мой тестовый класс:

public class dataProviderParallelTest { 

@Test (dataProvider="dynamicDP") 
public void verifyDPdata(String comingFromDP){ 
System.out.printf("%nDP#1..: "+comingFromDP); 
} 


@Test (dataProvider="dynamicDP") 
public void verifyDPdata2(String comingFromDP){ 
System.out.printf("%nDP#2..: "+comingFromDP); 
} 
} 

Вот результат:

[TestNG] Running: 
    C:\projects\test\currentTest.xml 

DP#1..: AA 
DP#2..: BB 
DP#1..: BB 
DP#2..: AA 
DP#1..: CC 
DP#2..: CC 
DP#1..: DD 
DP#1..: EE 
DP#2..: EE 
DP#2..: DD 
DP#1..: FF 
DP#2..: FF 
DP#1..: GG 
DP#1..: HH 
DP#2..: HH 
DP#2..: GG 
DP#1..: II 
DP#2..: II 
DP#1..: KK 
DP#2..: KK 
=============================================== 
Regression 
Total tests run: 20, Failures: 0, Skips: 0 
=============================================== 

А вот мой файл XML, который я использую, чтобы начать свой тест:

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 

<suite name="Regression" parallel="methods" thread-count="2" data-provider-thread-count="2"> 

    <test name="smokeTest11"> 
     <classes> 
     <class name="regression.bo.dataProviderParallelTest"/> 
     </classes> 
    </test> 

</suite> 

То, что я пробовал: Я прочитал эту статью: cedricBlog и это StackOverflow post: stackOverFlow

Что я пытаюсь достичь: Я пытаюсь разделить данные между двумя потоками. На данный момент я только что достиг обоих потоков для выполнения тех же данных, предоставленных DP. Моя цель состоит в том, чтобы разделить данные между этими двумя методами и имеют такой вывод (данные DP совместно между 2 методами):

DP#1..: AA 
DP#2..: BB 
DP#1..: DD 
DP#2..: EE 
DP#1..: CC 
DP#2..: GG 
DP#1..: KK 
DP#1..: HH 
DP#2..: II 
DP#2..: FF 

Это даже возможно, или я что-то отсутствует? Заранее спасибо за вашу помощь!

+1

Пропустив другой способ, будет хорошо для вас? –

+0

Привет, Grzergorz, большое спасибо за ваш интерес. К сожалению, нет, потому что конечная цель состоит в том, чтобы выполнять их одновременно на разных узлах сетки. Но независимо, спасибо за вашу помощь. Я начинаю думать; что то, что я пытаюсь достичь, - это не хорошая практика с dataProvider. У меня есть «альтернативное» решение, но это Java-решение, а не решение testNG. В любом случае, все равно будет голосовать, любой, кто может это решить :) –

+1

Будет также голосовать, мне удалось пропустить эти тесты (используя синхронизированную коллекцию), но я знаю, что это не желаемый результат. Каково ваше решение Java? –

ответ

0

Хорошо, размещение и мое решение для справки. Короче говоря, это так. Подсчитайте строки в файле и начните читать по 1 строке за раз (из 10 разных потоков), пока не достигнете EOF. Вот оно:

public volatile int currentLine=0; 
    public static Object writeLock = new Object(); 
    public static Object readLock = new Object(); 
    public long currentThread = Thread.currentThread().getId(); 



@Test(invocationCount = 50) 
    public void readOneLineGetID() throws IOException{ 

    countLines();   
    if(currentLine==noOfLines){throw new SkipException("%nSkipping this test method as we got all the records we need.");} 
    long threadID = Thread.currentThread().getId(); 

    synchronized(readLock){ 
     if(currentLine<noOfLines){ 
     System.out.printf("%nCurrent thread is..: "+ threadID); 
     readASpecificLineFromATextFile(currentLine); 
     System.out.printf("%n----------------------------------------------------------");  
     } 
    } 

    synchronized(writeLock){ 
    currentLine++;   
    }  

    } 

Так что у меня 10 из этих методов, и я толкая мои тесты одновременно на ступице сетки, который затем использует 10 различных поставщиков данных, чтобы накормить узлы.

Только второстепенная точка - это invocationCount (в идеале я должен делить на 10, а затем установить счетчик вызовов для каждого отдельного метода соответственно, но, поскольку у меня нет времени, чтобы заново изобрести колесо, и это работает очень быстро (только с 200 стандартными файлами, я решил пропустить оставшиеся методы после того, как номер строки достигнет EOF;))

Вот результат (10 методов, с 50 подсчетами наведения 10 строк макета из моего файл и пропуски остальных):

enter image description here

После некоторых возиться с синхронизацией, красиво !!! :)

1

Возьмите метод как параметр для вашего датапортера. Разделите свои данные в двух списках, в зависимости от того, что вам нравится. На основе имени метода возвращайте один список каждому.

например.

Например, следующий код выводит имя метода испытаний внутри его @DataProvider:

@DataProvider(name = "dynamicDP", parallel = true) 
public Object[][] dynamicDP(Method m) { 
    System.out.println(m.getName()); 
    //Divide list in two lists 
    if (m.getName().equals("Met1") 
    return list1 
    else 
    return list2 
} 

@Test(dataProvider="dynamicDP") 
public void test1(String s) { 
} 

@Test(dataProvider="dynamicDP") 
public void test2(String s) { 
} 

НТН

+0

Хорошая попытка, спасибо нихарике; Я проголосовал за это, так как это решает проблему. Тем не менее, в конечном итоге я буду запускать эти «списки» на 10 узлов (т. Е. 10 разных методов), и хотя это не проблема, делящаяся на 10 и работающая с остатком; это не совсем параллельное исполнение в лучшем виде. Я нашел еще лучше (для своих нужд) более динамичное пользовательское решение, которое будет обрабатывать данные по очереди. Скоро опубликует! Еще раз спасибо за помощь, ребята, очень ценные за ваши усилия и время! –