Size of DataProvider at runtime

1,052 views
Skip to first unread message

testNgUser

unread,
Feb 12, 2010, 12:01:56 PM2/12/10
to testng-users
I recently converted from JUnit4.x to TestNG after hitting the
limitations of parameterized test cases....All good with testNG so
far.

My question: Is it possible to determine at runtime, the number of
rows in a dataprovider array i.e., the number of times that a test
case will be invoked?

Thanks

Kartik Kumar

unread,
Feb 12, 2010, 1:20:05 PM2/12/10
to testng...@googlegroups.com
I don't think you can but you can put a counter value for in your data provider parameter for information.


--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.


Cédric Beust ♔

unread,
Feb 12, 2010, 3:45:53 PM2/12/10
to testng...@googlegroups.com
If the data provider is the only one that can know this value, then Kartik is right:  just have it return that value as part of its job:

@Test(dataProvider = "...")
public void myMethod(int count, ... /* other parameters */) {}

It's a bit wasteful to pass this `count` at each invocation since that value will probably not change, but this will work fine.

If this value can be known earlier, then maybe you could have a special test method connected to a special "count provider" that will return that value.  The test method can store this value in a field and future test methods can then use that value.

This is more complicated, though, so I would definitely go with Kartik's suggestion.

-- 
Cédric

testNgUser

unread,
Feb 15, 2010, 5:13:02 PM2/15/10
to testng-users
That works a treat. Thanks for the responses

On Feb 12, 8:45 pm, Cédric Beust ♔ <cbe...@google.com> wrote:
> If the data provider is the only one that can know this value, then Kartik
> is right:  just have it return that value as part of its job:
>
> @Test(dataProvider = "...")
> public void myMethod(int count, ... /* other parameters */) {}
>
> It's a bit wasteful to pass this `count` at each invocation since that value
> will probably not change, but this will work fine.
>
> If this value can be known earlier, then maybe you could have a special test
> method connected to a special "count provider" that will return that value.
>  The test method can store this value in a field and future test methods can
> then use that value.
>
> This is more complicated, though, so I would definitely go with Kartik's
> suggestion.
>
> --

> ***Cédric
> *


>
> On Fri, Feb 12, 2010 at 10:20 AM, Kartik Kumar <krishnan.1...@gmail.com>wrote:
>
>
>
> > I don't think you can but you can put a counter value for in your data
> > provider parameter for information.
>

> > On Fri, Feb 12, 2010 at 9:01 AM, testNgUser <johnadegb...@yahoo.co.uk>wrote:
>
> >> I recently converted from JUnit4.x to TestNG after hitting the
> >> limitations of parameterized test cases....All good with testNG so
> >> far.
>
> >> My question: Is it possible to determine at runtime, the number of
> >> rows in a dataprovider array i.e., the number of times that a test
> >> case will be invoked?
>
> >> Thanks
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "testng-users" group.
> >> To post to this group, send email to testng...@googlegroups.com.
> >> To unsubscribe from this group, send email to

> >> testng-users...@googlegroups.com<testng-users%2Bunsubscribe@google groups.com>


> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/testng-users?hl=en.
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "testng-users" group.
> > To post to this group, send email to testng...@googlegroups.com.
> > To unsubscribe from this group, send email to

> > testng-users...@googlegroups.com<testng-users%2Bunsubscribe@google groups.com>

AE6RT

unread,
Sep 29, 2012, 10:05:52 PM9/29/12
to testng...@googlegroups.com
This ITestListener implementation works for me, but it only works where the DataProvider resides in the same class as the test class instance.  You should also make sure that you code your DataProvider method in such a way that you compute the Object[][] array once (such as in some @BeforeClass scenario), then return that array each time you call the DataProvider method.

    @Override
    public void onTestStart(ITestResult iTestResult) {
        // Attempt to count invocations of a DataProvider-instrumented test
        Object instance = iTestResult.getInstance();
        ITestNGMethod testNGMethod = iTestResult.getMethod();
        Method testMethod = testNGMethod.getMethod();
        if (testMethod.isAnnotationPresent(Test.class) && testMethod.isAnnotationPresent(Count.class)) {
            Test testMethodTestAnnotation = testMethod.getAnnotation(Test.class);
            String dataProviderName = testMethodTestAnnotation.dataProvider();
            if (dataProviderName != null && !dataProviderName.isEmpty()) {
                Class<?> aClass = instance.getClass();
                Method[] allTestClassMethods = aClass.getMethods();
                for (Method m : allTestClassMethods) {
                    /*
                    Counting will silently fail for Test classes using a DataProvider defined outside the test class instance itself.
                    The reason is that the following code does not look outside the test class instance for the DataProvider method.
                     */
                    if (m.isAnnotationPresent(DataProvider.class)) {
                        DataProvider dataProviderAnnotation = m.getAnnotation(DataProvider.class);
                        String thisDataProviderName = dataProviderAnnotation.name();
                        if (dataProviderName.equals(thisDataProviderName)) {
                            try {
                                Object[][] theData = (Object[][]) m.invoke(instance);
                                Integer numberOfDataProviderRows = theData.length;
                                System.out.printf("Executing %s %d / %d\n", iTestResult.getName(), testNGMethod.getCurrentInvocationCount() + 1, numberOfDataProviderRows);
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();

AE6RT

unread,
Sep 29, 2012, 10:08:49 PM9/29/12
to testng...@googlegroups.com
Here is a Gist that points to the code, which may feature better formatting than the text I pasted earlier:

Reply all
Reply to author
Forward
0 new messages