Search code examples
mavenmobileautomationappiumcucumber-jvm

Can I run the same cucumber suite on multiple devices using one maven command?


I have a cucumber/appium framework for testing on mobile devices. Now that cucumber and appium support parallel runs, I have it set up to distribute features to each connected device (junit only splits features, not scenarios). I achieve this using a DriverFactory class. This class works great, but parallel runs in this situation are only really useful if it's the same driver each time (e.g. ChromeDriver). My devices are added to a pool during the junit @BeforeClass method and my DriverFactory uses them one by one until empty.

My issue though is that, although quick, I sometimes want to run the entire suite on each connected device (just because a test passes on one device, doesn't make mean it would pass on the other devices).

I'm thinking that a batch file with multiple maven commands might do it but is there a way I can do it all with the one command?

I use maven-failsafe as I don't want the run to stop for failed tests, my pom setup is below, which splits the features across the devices if there's 2 devices connected

I have a single cucumber runner class. I haven't looked at Jenkins. I was first hoping to see if I could do all this from my mac considering I already have it working on a per feature basis.

This is my relevant maven-failsafe code. I can update the threadCount for however many devices I have connected (looking into doing this dynamically). I tried using suites instead of methods but it then runs the entire suite on only one device

                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/RunCucumberTest.java</include>
                            </includes>
                            <parallel>methods</parallel>
                            <threadCount>2</threadCount>
                            <perCoreThreadCount>false</perCoreThreadCount>
                        </configuration>
                    </execution>
                </executions>

Any help would be appreciated. If there's anything you need to know, please let me know or if there's any of my code that would help, I can post it here


Solution

  • late response to my own question, but I am using the following setup to use an individual runner class based on the number of devices I have connected. I use this plugin to get the number of devices and then use the runner per device. Not a dev, so take this with a pinch of salt. It works, but not sure if works right :-)

    @RunWith(AllTests.class)
    public class ClassRunnerTest {
    
        public static TestSuite suite() {
    
            int numberOfDevices;
    
            try {
                DeviceInfo deviceInfo = new DeviceInfoImpl(DeviceType.ALL);
                List<Device> devices = deviceInfo.getDevices();
                numberOfDevices = devices.size();
            } catch (IOException e) {
                throw new Exception();
            } catch (DeviceNotFoundException e) {
                throw new Exception();
            }
    
            TestSuite suite = new ActiveTestSuite();
    
            for (int i = 0; i < numberOfDevices; i++) {
                suite.addTest(new JUnit4TestAdapter(RunCucumberTest.class));
            }
    
            return suite;
        }
    }
    

    The RunCucumberTest class is a Cucumber class. The side effect of this is that it seems some cucumber plugins don't work with while using this method (e.g. cluecumber only reports on one class, haven't dug into the reasons though), but other than that it seems to work so far.

    Sometimes I want to run distributed tests rather than fragmentation, so looking into easily making that switch. Maybe a cucumber plugin.