[testng-dev] Adding support for cartesian dataproviders

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

[testng-dev] Adding support for cartesian dataproviders

Mark Derricutt
Cedric,

I was just updating some tests and came up with a pattern that I was thinking would be good to include in TestNG directly. The concept is a simple cartesian product support for data providers.

In my test I know have three providers, the first two providing discreet sets of data, with their concerns separated out, the third being the cartesian procut:

    @DataProvider
    public Object[][] provideBillingReferences() {
        return new Object[][] {...};
    }

    @DataProvider
    public Object[][] provideSplitData() {
        return new Object[][] {...};
    }

    @DataProvider
    public Iterator<Object[]> provideMergedSplitData() {
        return DataProviderUtil.cartesianProviderFrom(ImmutableList.of(provideSplitData(), provideBillingReferences()));
    }

    @Test(dataProvider = "provideMergedSplitData")
    ….


What I was thinking was this could be handy to incorporate directly into TestNG then I could do something

    @Test(dataProvider = {"provideBillingReferences", "provideSplitData"})

and have TestNG handle the cartesian itself. Thoughts?

My current implementation of this uses Google Guava:

public class DataProviderUtil {

    /**
     * Given a list of @DataProvider results, generate a cartesian product of available combinations.
     * @param dataProviderData A list of @DataProvider results
     * @return The cartesian product of available combinations.
     */
    public static Iterator<Object[]> cartesianProviderFrom(List<Object[][]> dataProviderData) {

        ImmutableList.Builder<Set<Object[]>> cartesianSets = ImmutableList.builder();
        for (Object[][] objects : dataProviderData) {
            cartesianSets.add(Sets.newHashSet(objects));
        }

        Set<List<Object[]>> cartesianData = Sets.cartesianProduct(cartesianSets.build());
        List<Object[]> data = Lists.newArrayList();

        for (List<Object[]> objects : cartesianData) {
            Object[] mergedArray = flattenObjectArray(objects);
            data.add(mergedArray);
        }

        return data.iterator();
    }

    private static Object[] flattenObjectArray(List<Object[]> arrays) {

        int len = 0;
        for (Object[] array : arrays) {
            len += array.length;
        }

        int index = 0;

        Object[] mergedArray = new Object[len];

        for (Object[] array : arrays) {
            for (int i = 0; i < array.length; i++) {
                mergedArray[index++] = array[i];
            }
        }

        return mergedArray;
    }

}


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

Reply | Threaded
Open this post in threaded view
|

Re: [testng-dev] Adding support for cartesian dataproviders

Cédric Beust ♔-2
Hey Mark,

Happy to add your DataProviderUtils class to TestNG, mind sending me a pull request?

-- 
Cédric




On Mon, Aug 6, 2012 at 9:00 PM, Mark Derricutt <[hidden email]> wrote:
Cedric,

I was just updating some tests and came up with a pattern that I was thinking would be good to include in TestNG directly. The concept is a simple cartesian product support for data providers.

In my test I know have three providers, the first two providing discreet sets of data, with their concerns separated out, the third being the cartesian procut:

    @DataProvider
    public Object[][] provideBillingReferences() {
        return new Object[][] {...};
    }

    @DataProvider
    public Object[][] provideSplitData() {
        return new Object[][] {...};
    }

    @DataProvider
    public Iterator<Object[]> provideMergedSplitData() {
        return DataProviderUtil.cartesianProviderFrom(ImmutableList.of(provideSplitData(), provideBillingReferences()));
    }

    @Test(dataProvider = "provideMergedSplitData")
    ….


What I was thinking was this could be handy to incorporate directly into TestNG then I could do something

    @Test(dataProvider = {"provideBillingReferences", "provideSplitData"})

and have TestNG handle the cartesian itself. Thoughts?

My current implementation of this uses Google Guava:

public class DataProviderUtil {

    /**
     * Given a list of @DataProvider results, generate a cartesian product of available combinations.
     * @param dataProviderData A list of @DataProvider results
     * @return The cartesian product of available combinations.
     */
    public static Iterator<Object[]> cartesianProviderFrom(List<Object[][]> dataProviderData) {

        ImmutableList.Builder<Set<Object[]>> cartesianSets = ImmutableList.builder();
        for (Object[][] objects : dataProviderData) {
            cartesianSets.add(Sets.newHashSet(objects));
        }

        Set<List<Object[]>> cartesianData = Sets.cartesianProduct(cartesianSets.build());
        List<Object[]> data = Lists.newArrayList();

        for (List<Object[]> objects : cartesianData) {
            Object[] mergedArray = flattenObjectArray(objects);
            data.add(mergedArray);
        }

        return data.iterator();
    }

    private static Object[] flattenObjectArray(List<Object[]> arrays) {

        int len = 0;
        for (Object[] array : arrays) {
            len += array.length;
        }

        int index = 0;

        Object[] mergedArray = new Object[len];

        for (Object[] array : arrays) {
            for (int i = 0; i < array.length; i++) {
                mergedArray[index++] = array[i];
            }
        }

        return mergedArray;
    }

}


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


--
You received this message because you are subscribed to the Google Groups "testng-dev" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/testng-dev?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: [testng-dev] Adding support for cartesian dataproviders

Mark Derricutt
I'll try and clean it up and remove the Guava dependency ( I'm not sure if TestNG currently have any Guava dependencies at all? I don't think it does ).

Currently it feels a little... wrong to add the class/dependency for just one method so I may hold off for now.

On 7/08/2012, at 4:04 PM, Cédric Beust ♔ <[hidden email]> wrote:

> Happy to add your DataProviderUtils class to TestNG, mind sending me a pull request?

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

Reply | Threaded
Open this post in threaded view
|

Re: [testng-dev] Adding support for cartesian dataproviders

Cédric Beust ♔-2
Indeed, I had to remove the Guava (and Guice) dependency from TestNG because it was close to impossible to have those and still produce a jar file that works for both ant and maven.

-- 
Cédric




On Tue, Aug 7, 2012 at 2:26 AM, Mark Derricutt <[hidden email]> wrote:
I'll try and clean it up and remove the Guava dependency ( I'm not sure if TestNG currently have any Guava dependencies at all? I don't think it does ).

Currently it feels a little... wrong to add the class/dependency for just one method so I may hold off for now.

On 7/08/2012, at 4:04 PM, Cédric Beust ♔ <[hidden email]> wrote:

> Happy to add your DataProviderUtils class to TestNG, mind sending me a pull request?

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


--
You received this message because you are subscribed to the Google Groups "testng-dev" group.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/testng-dev?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: [testng-dev] Adding support for cartesian dataproviders

Karel Rank
Any progress regarding combinations?

On Tuesday, August 7, 2012 1:43:33 PM UTC+2, Cédric Beust ♔ wrote:
Indeed, I had to remove the Guava (and Guice) dependency from TestNG because it was close to impossible to have those and still produce a jar file that works for both ant and maven.

-- 
Cédric




On Tue, Aug 7, 2012 at 2:26 AM, Mark Derricutt <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="TayrV-At0hoJ">ma...@...> wrote:
I'll try and clean it up and remove the Guava dependency ( I'm not sure if TestNG currently have any Guava dependencies at all? I don't think it does ).

Currently it feels a little... wrong to add the class/dependency for just one method so I may hold off for now.

On 7/08/2012, at 4:04 PM, Cédric Beust ♔ <<a href="javascript:" target="_blank" gdf-obfuscated-mailto="TayrV-At0hoJ">ced...@...> wrote:

> Happy to add your DataProviderUtils class to TestNG, mind sending me a pull request?

--
You received this message because you are subscribed to the Google Groups "testng-dev" group.
To post to this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="TayrV-At0hoJ">testn...@....
To unsubscribe from this group, send email to <a href="javascript:" target="_blank" gdf-obfuscated-mailto="TayrV-At0hoJ">testng-dev+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-dev?hl=en.


--
You received this message because you are subscribed to the Google Groups "testng-dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/testng-dev/-/DR5RRQTHHmkJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/testng-dev?hl=en.
Reply | Threaded
Open this post in threaded view
|

Re: [testng-dev] Adding support for cartesian dataproviders

Mark Derricutt
To be honest I got sidetracked with other things to try and refactor it to not use Guava.

For now one could simply pull in the class to their own project.  ( Or I could extract it to an artifact and push it to maven central ).

If I get some time this week I'll see if I can rework it tho.

On 17/09/2012, at 9:34 PM, Karel Rank <[hidden email]> wrote:

> Any progress regarding combinations?

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

Reply | Threaded
Open this post in threaded view
|

[testng-dev] Re: Adding support for cartesian dataproviders

Roman Hiden
In reply to this post by Mark Derricutt
Thanks that would be helpful at least for me. Instead of creating manually all the combinations you could just rely on Cartesian provider

On Tuesday, August 7, 2012 12:00:04 AM UTC-4, Mark Derricutt wrote:
Cedric,

I was just updating some tests and came up with a pattern that I was thinking would be good to include in TestNG directly. The concept is a simple cartesian product support for data providers.

In my test I know have three providers, the first two providing discreet sets of data, with their concerns separated out, the third being the cartesian procut:

    @DataProvider
    public Object[][] provideBillingReferences() {
        return new Object[][] {...};
    }

    @DataProvider
    public Object[][] provideSplitData() {
        return new Object[][] {...};
    }

    @DataProvider
    public Iterator<Object[]> provideMergedSplitData() {
        return DataProviderUtil.cartesianProviderFrom(ImmutableList.of(provideSplitData(), provideBillingReferences()));
    }

    @Test(dataProvider = "provideMergedSplitData")
    ….


What I was thinking was this could be handy to incorporate directly into TestNG then I could do something

    @Test(dataProvider = {"provideBillingReferences", "provideSplitData"})

and have TestNG handle the cartesian itself. Thoughts?

My current implementation of this uses Google Guava:

public class DataProviderUtil {

    /**
     * Given a list of @DataProvider results, generate a cartesian product of available combinations.
     * @param dataProviderData A list of @DataProvider results
     * @return The cartesian product of available combinations.
     */
    public static Iterator<Object[]> cartesianProviderFrom(List<Object[][]> dataProviderData) {

        ImmutableList.Builder<Set<Object[]>> cartesianSets = ImmutableList.builder();
        for (Object[][] objects : dataProviderData) {
            cartesianSets.add(Sets.newHashSet(objects));
        }

        Set<List<Object[]>> cartesianData = Sets.cartesianProduct(cartesianSets.build());
        List<Object[]> data = Lists.newArrayList();

        for (List<Object[]> objects : cartesianData) {
            Object[] mergedArray = flattenObjectArray(objects);
            data.add(mergedArray);
        }

        return data.iterator();
    }

    private static Object[] flattenObjectArray(List<Object[]> arrays) {

        int len = 0;
        for (Object[] array : arrays) {
            len += array.length;
        }

        int index = 0;

        Object[] mergedArray = new Object[len];

        for (Object[] array : arrays) {
            for (int i = 0; i < array.length; i++) {
                mergedArray[index++] = array[i];
            }
        }

        return mergedArray;
    }

}


--
You received this message because you are subscribed to the Google Groups "testng-dev" group.
To view this discussion on the web visit https://groups.google.com/d/msg/testng-dev/-/UO_xPApKewYJ.
To post to this group, send email to [hidden email].
To unsubscribe from this group, send email to [hidden email].
For more options, visit this group at http://groups.google.com/group/testng-dev?hl=en.