Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android support for running tests on multiple connected devices or emulators #570

Open
Tracked by #4236
hoda0013 opened this issue Feb 13, 2018 · 4 comments
Open
Tracked by #4236

Comments

@hoda0013
Copy link

Description

In the Android Gradle Plugin there is a Gradle task called connectedCheck. This Gradle task identifies any devices connected to adb and then runs all tests on all connected devices then generates a test report. As far as I can tell this functionality is not possible in Detox.

It would be nice if there were a way to write the Detox configuration that would allow us to test on all connected devices and not have to specify a name (or type for that matter). This would make things possible such as creating a device farm by plugging devices into a build agent and having the build agent run functional tests on all connected devices as part of a build pipeline.

@simonbuchan
Copy link
Contributor

Detox doesn't actually use module-level values that much, so It's possible to run detox in parallel by poking into the detox internals:

parallel-detox.js
const ADB = require('detox/src/devices/android/ADB');
const Detox = require('detox/src/Detox');

async function main() {
  const devices = await new ADB().devices();
  await Promise.all(devices.map(async device => {
    const deviceConfig = {
      binaryPath: 'path/to/output/apk/your-app.apk',
      type: 'android.emulator',
      name: device.name,
    };
    const detoxGlobals = await getDetoxGlobals(deviceConfig);
    await runTestsWith(detoxGlobals);
  });
}

async function getDetoxGlobals(deviceConfig) {
  const detox = new Detox({ deviceConfig });
  await detox.init({ initGlobals: false });

  const { device } = detox;
  const { expect, element, by, waitFor } = detox.deviceDriver.expect;
  return { detox, device, expect, element, by, waitFor };
}

main().catch(error => {
  console.error(error);
  process.exit(1);
});

You probably shouldn't do this, but it seems to work?

So the problem becomes how do you run this in the context of jest or whatever, where it expects to be calling you? In theory, you could do something like:

for (const device of await new ADB().devices()) {
  describe(`Device: ${device.name}`, async () => {
    const { ... } = await getDetoxGlobals(...);
    it(...);
  };
}

but:

  • You can't await at module level
  • Jest/mocha etc. will all want the describe() to be sync called on module evaluation
  • How does this work across test files?

I played around a bit and ended up generating a detox config JSON, then invoking detox test --configuration ${name} for each in parallel:

test-all.js
const cp = require('child_process');
const fs = require('fs');
const util = require('util');

const ADB = require('detox/src/devices/android/ADB');

new ADB().devices().then(devices => {
  const detoxConfig = {
    configurations: {},
  };

  for (const device of devices) {
    detoxConfig.configurations[device.name] = {
      binaryPath: '...',
      type: 'android.emulator',
      name: device.name,
    };
  }

  fs.writeFileSync(
    `${__dirname}/detox.json`,
    JSON.stringify(detoxConfig, null, 2));

  return Promise.all(devices.map(device => {
    return util.promisify(cp.spawn)(
      `yarn detox test --configuration ${device.name}`,
      { stdio: 'inherit', shell: true });
  }));
}).catch(error => {
  console.error(error);
  process.exit(1);
});

then in your tests use detox.init(require('./detox.json')).

This seems to work OK, though detox could definitely make it easier!

@d4vidi d4vidi added this to the Detox20 milestone Apr 13, 2022
@d4vidi d4vidi removed this from the Detox20 milestone May 17, 2022
@stale
Copy link

stale bot commented Jun 18, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest Detox and report back.

Thank you for your contributions!

For more information on bots in this reporsitory, read this discussion.

@stale stale bot added the 🏚 stale label Jun 18, 2022
@stale
Copy link

stale bot commented Jun 27, 2022

The issue has been closed for inactivity.

@stale stale bot closed this as completed Jun 27, 2022
@d4vidi
Copy link
Collaborator

d4vidi commented Jul 5, 2022

We might add support for that one day 😄
If we do, it would be through a thought-out, dedicated API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants