passing a list, one by one to the same test x time

89 views
Skip to first unread message

Eyal

unread,
Jul 5, 2021, 3:13:25 AM7/5/21
to testng-users
Hello,

Using testng, intellij,java.
I have a folder with x files-
- I am running with a loop to get all the files[] names
- now I need to pass my test in each run 1 file from the folder
- purpose that the same test will run as much times as the files in the folder
- I need the report for each test of course.

How an I do that ?

⇜Krishnan Mahadevan⇝

unread,
Jul 5, 2021, 4:03:39 AM7/5/21
to testng-users
You can make use of a "@DataProvider" which serves the list contents and which can be consumed by your "@Test" method.
That should solve this ask for you.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to testng-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/testng-users/d4aae40c-94cd-485c-9620-12f0ff249db3n%40googlegroups.com.

Eyal

unread,
Jul 5, 2021, 6:08:06 AM7/5/21
to testng-users
Hi,

I tried but this is File[] and I don;t understand how to make 1 test to run multiple times with next value from the loop until end of files....
ב-יום שני, 5 ביולי 2021 בשעה 11:03:39 UTC+3, Krishnan Mahadevan כתב/ה:

⇜Krishnan Mahadevan⇝

unread,
Jul 5, 2021, 12:27:19 PM7/5/21
to testng-users
Here's an example

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Objects;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class FilesTest {

  @Test(dataProvider = "dp")
  public void testMethod(File file) {
    System.err.println(file.getAbsolutePath());
  }

  @DataProvider(name="dp")
  public Object[][] getData() throws IOException {
    return Files.list(Paths.get(System.getProperty("user.home")))
        .filter(Objects::nonNull)
        .map(each -> new Object[]{each.toFile()})
        .toArray(size -> new Object[size][1]);
  }

}


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal

unread,
Jul 5, 2021, 2:09:58 PM7/5/21
to testng-users
Works perfectly !!!
Thanks for the amazing answer, did not find any doc on that one :)

ב-יום שני, 5 ביולי 2021 בשעה 13:08:06 UTC+3, Eyal כתב/ה:

Eyal

unread,
Jul 8, 2021, 9:02:15 AM7/8/21
to testng-users
Hi Krishnan,

sometimes I get this:
[Utils] [ERROR] [Error] org.testng.TestNGException: 
Method public void test.api.checkscanApi.CheckScanTestCase$ImageTest.checkScanResults(java.io.File) throws java.io.IOException,java.lang.InterruptedException requires a @DataProvider named : getData in class test.api.checkscanApi.CheckScanTestCase
at org.testng.internal.Parameters.findDataProvider(Parameters.java:561)
at org.testng.internal.Parameters.handleParameters(Parameters.java:772)
at org.testng.internal.Parameters.handleParameters(Parameters.java:740)
at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:59)
at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:38)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:791)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.access$000(SuiteRunner.java:28)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:418)
at org.testng.internal.thread.ThreadUtil.lambda$execute$0(ThreadUtil.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

[INFO ] 2021-07-08 15:58:43.223 [TestNG-tests-1] checkscan - I am in onTestFailure method checkScanResults failed

org.testng.TestNGException: 
Method public void test.api.checkscanApi.CheckScanTestCase$ImageTest.checkScanResults(java.io.File) throws java.io.IOException,java.lang.InterruptedException requires a @DataProvider named : getData in class test.api.checkscanApi.CheckScanTestCase

at org.testng.internal.Parameters.findDataProvider(Parameters.java:561)
at org.testng.internal.Parameters.handleParameters(Parameters.java:772)
at org.testng.internal.Parameters.handleParameters(Parameters.java:740)
at org.testng.internal.ParameterHandler.handleParameters(ParameterHandler.java:59)
at org.testng.internal.ParameterHandler.createParameters(ParameterHandler.java:38)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:791)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.access$000(SuiteRunner.java:28)
at org.testng.SuiteRunner$SuiteWorker.run(SuiteRunner.java:418)
at org.testng.internal.thread.ThreadUtil.lambda$execute$0(ThreadUtil.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)


and I didn't change the code so maybe there is a bug in the data provider area ?

Thanks,
Eyal

ב-יום שני, 5 ביולי 2021 בשעה 21:09:58 UTC+3, Eyal כתב/ה:

⇜Krishnan Mahadevan⇝

unread,
Jul 8, 2021, 9:25:41 AM7/8/21
to testng-users
Thats not possible. There is no bug here. 

The "@Test" annotation has an attribute called "dataProvider" which needs to be set a value which matches with the "name" attribute of the "@DataProvider".
In your case, it looks like that mapping has been changed. The example I shared uses the name "dp" to tie the data provider and the test method.

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal

unread,
Jul 8, 2021, 9:33:02 AM7/8/21
to testng-users
@Test(dataProvider = "getData")
public void checkScanResults(File file) throws IOException {
log.info(file.getAbsolutePath());
//helper.checkSessionId(new File(file.getAbsolutePath()));
}

@DataProvider (name = "getData")
public Object[][] getData(File[] file) throws IOException {
return Files.list(Paths.get("N:\\Images\\E\\Ch\\ChOice\\"))

.filter(Objects::nonNull)
.map(each -> new Object[]{each.toFile()})
.toArray(size -> new Object[size][1]);
}


That is exactly what I did ,attributes names are equals so where I can find the real issue here ???

Thanks
ב-יום חמישי, 8 ביולי 2021 בשעה 16:25:41 UTC+3, Krishnan Mahadevan כתב/ה:

⇜Krishnan Mahadevan⇝

unread,
Jul 8, 2021, 9:37:15 AM7/8/21
to testng-users
Are these two methods (test class and the data provider) in the same class ?
If the data provider method "getData()" exists in a different class, then you would also have to specify the data provider class name via the "dataProviderClass" attribute.


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal

unread,
Jul 8, 2021, 9:40:11 AM7/8/21
to testng-users
They are as I wrote in the same class, that is why I am lost here....

ב-יום חמישי, 8 ביולי 2021 בשעה 16:37:15 UTC+3, Krishnan Mahadevan כתב/ה:

⇜Krishnan Mahadevan⇝

unread,
Jul 8, 2021, 9:47:25 AM7/8/21
to testng-users
The exception stacktrace says this

org.testng.TestNGException:
Method public void test.api.checkscanApi.CheckScanTestCase$ImageTest.checkScanResults(java.io.File) throws java.io.IOException,java.lang.InterruptedException requires a @DataProvider named : getData in class test.api.checkscanApi.CheckScanTestCase

So am guessing that, 

You have a public class named CheckScanTestCase

Inside this class, you have a nested class named "ImageTest" and in that resides the "@Test" method named checkScanResults().
This is referring to a data provider "getData()"

For some reason, TestNG is expecting this method in the outer class (CheckScanTestCase) rather than the inner class (ImageTest).

Can you please confirm if this theory is valid ?


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal

unread,
Jul 8, 2021, 9:51:13 AM7/8/21
to testng-users
@Listeners ({allurelistener.class})
public class CheckScanTestCase {

private static final Logger log = LogManager.getLogger(checkscan.class.getName());
final static ImageHelper helper = new ImageHelper();
private CustomAssertion m_custom = new CustomAssertion();

@BeforeSuite
public void beforeSuite() throws IOException {
ImageTest.runCommand(command);
helper.getCheckScanToken();
}

// @Factory (dataProvider = "passImageList")
// public Object[] factoryMethod(String[] ids) {
// final List<Object> list = new ArrayList<>();
// for (String id : ids) {
// list.add(new ImageTest(id));
// }
//
// return new Object[]{
// list.toArray()
// };
// }

public static class ImageTest {
final String id;


public ImageTest(String id) {
this.id = id;
}

@Story("Post & Get to validate the image scan process, 404 will be a failure !!!")
@Test(dataProvider = "getData")
public void checkScanResults(File file) {
log.info(file.getAbsolutePath());
//helper.checkSessionId(new File(file.getAbsolutePath()));
}

@DataProvider

public Object[][] getData(File[] file) throws IOException {
return Files.list(Paths.get("N:/Images/Julia/CheckScan/CheckScanService"))

.filter(Objects::nonNull)
.map(each -> new Object[]{each.toFile()})
.toArray(size -> new Object[size][1]);
}

ב-יום חמישי, 8 ביולי 2021 בשעה 16:47:25 UTC+3, Krishnan Mahadevan כתב/ה:

Eyal Avramchik

unread,
Jul 8, 2021, 10:56:20 AM7/8/21
to testng...@googlegroups.com
Your theory seems correct, As you can see I attached the code In the previous email,
Any idea why is that error ?

⇜Krishnan Mahadevan⇝

unread,
Jul 9, 2021, 6:31:30 AM7/9/21
to testng-users
The only reason why I can think of that error happening is that your data provider "getData()" is parameterised method whereas in mine its not. The data provider should not be taking in any adhoc values as parameters (It can however be injected with TestNG objects, but that's a different topic)

Here's the cleaned up simple version of the same test case that works fine. 

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.stream.IntStream;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;

public class CheckScanTestCase {

  private static final Logger log = Logger.getAnonymousLogger();

  @BeforeSuite
  public void beforeSuite() throws IOException {
  }

  @DataProvider(name = "passImageList")
  public Object[][] passImageList() {
    return IntStream.rangeClosed(1, 10)
        .mapToObj(Integer::toString)
        .map(each -> new Object[]{new String[]{each, each}})
        .toArray(size -> new Object[size][1]);
  }

  @Factory(dataProvider = "passImageList")
  public Object[] factoryMethod(String[] ids) {
    final List<Object> list = new ArrayList<>();
    for (String id : ids) {
      list.add(new ImageTest(id));
    }

    return new Object[]{
        list.toArray()
    };
  }

  public static class ImageTest {

    final String id;


    public ImageTest(String id) {
      this.id = id;
    }

    @Test(dataProvider = "getData")
    public void checkScanResults(File file) {
      log.info(file.getAbsolutePath());
    }

    @DataProvider
    public Object[][] getData() throws IOException {
      return Files.list(Paths.get(System.getProperty("user.home")))
          .filter(Objects::nonNull)
          .map(each -> new Object[]{each.toFile()})
          .toArray(size -> new Object[size][1]);
    }
  }
}


Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal

unread,
Jul 12, 2021, 10:22:02 AM7/12/21
to testng-users
Thanks.

One more question:
can you please also add sample short code for getting the txt file line by line and return it with data provider to a test ?
to run test 1 by 1 with line by line ?

Just like folders but now with the lines (Strings)

Thanks

ב-יום שישי, 9 ביולי 2021 בשעה 13:31:30 UTC+3, Krishnan Mahadevan כתב/ה:

⇜Krishnan Mahadevan⇝

unread,
Jul 13, 2021, 1:27:07 AM7/13/21
to testng-users
You mean something like this ?

@DataProvider(name="fileContent") public Object[][] getFileContents() throws IOException { return Files.readAllLines( Paths.get(System.getProperty("user.home") + "/my_text_file.txt") ).stream() .map(each -> new Object[]{each}) .toArray(size -> new Object[size][1]); }

Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/
My Technical Scribblings @ https://rationaleemotions.com/

Eyal Avramchik

unread,
Jul 14, 2021, 4:36:24 AM7/14/21
to testng...@googlegroups.com
Thanks Krishnan,

It's works great.

Reply all
Reply to author
Forward
0 new messages