Pregunta

Is there a way I can get appium to startup within the code I am writing for a junit test? Since appium only needs to run when my test is running it doesnt make sense to me to keep the appium server always going.

Right now I am using junit and maven to run test builds. Due to stability issues with appium it will sometimes die in the middle of the build, thus failing all remaining tests. I want to know if it is possible to add something to the @Before method to start the appium server before connecting the WebDriver to it, and then terminating it in the @After method. This should address any issues with appium failures since it can reset before starting the next test.

Still looking into starting and ending processes in general in java to see if this will work. If I figure this out I will update this post to help anyone else interested in testing this way.

¿Fue útil?

Solución 3

I've solved this in a very similar way using a DefaultExecutor to keep track of the Appium process so it can be destroyed at the end of the tests. This also allows the Appium output to be logged out during the tests using a DefaultExecuteResultHandler.

To avoid using a sleep to wait for Appium to start, you could create your WebDriver instance inside a try-catch

for (int i = 10; i > 0; i--) {
        try {
            driver = new RemoteWebDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
            // If we successfully attach to appium, exit the loop.
            i = 0;
        } catch (UnreachableBrowserException e) {
            LOGGER.info("Waiting for Appium to start");
        }
    }

You could add a sleep in the catch block if you wanted to poll less frequently.

Otros consejos

Figured out how to get this to work by just running the terminal command within the code

@Before
public void setUp() throws Exception {
    closeSimulatorAndInstruments(); // also closes any appium servers
    appium = Runtime.getRuntime().exec("/usr/local/bin/appium");
    Thread.sleep(1000); // wait for appium to start up, not sure how to check the status
    ... // start test
}

@After
public void tearDown() throws Exception {
    captureScreenshot(testName.getMethodName());
    driver.quit();
    appium.destroy(); // kills the appium server so it wont collide with the next run
}

I'm seeing issues with my CI box running jenkins attempting to do this but it's probably unrelated. Locally this is working great since I don't have to remember to run appium separately anymore or check to see if it died. This is not advised however if you need to see the appium output which may contain important errors

I have written a library for this.

/**
 *@author Raghu Nair
 */
public class Appium {

private static volatile Appium instance;

public static Appium getInstance(String outFile, String errFile) {
    if (instance == null) {
        synchronized (Appium.class) {
            if (instance == null) {
                instance = new Appium(outFile, errFile);
            }
        }
    }
    return instance;
}
Process process;
final String outFile;
final String errFile;

private Appium(String outFile, String errFile) {
    this.outFile = outFile;
    this.errFile = errFile;
}

public void start() throws IOException {
    if (process != null) {
        stop();
    }

    String processName = System.getProperty("appium.bin");
    String processString = processName + " -lt 180000";
    ProcessBuilder builder = new ProcessBuilder("bash");
    process = builder.start();
    OutputStream outStream = System.out;
    if (outFile != null) {
        outStream = new FileOutputStream(outFile);
    }
    OutputStream errStream = System.err;
    if (errFile != null) {
        errStream = new FileOutputStream(errFile);
    }

    handleStream(process.getInputStream(), new PrintWriter(outStream));
    handleStream(process.getErrorStream(), new PrintWriter(errStream));
    try (PrintWriter writer = new PrintWriter(process.getOutputStream())) {
        //writer.println("kill -9 `ps -ef | grep appium | cut -d' ' -f2`");
        writer.println("export PATH=$PATH:/usr/bin/:/usr/local/bin/");
        writer.println(processString);
        writer.flush();
    }

}

private void handleStream(final InputStream processOut, final PrintWriter writer) {
    Thread outHandler;
    outHandler = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                BufferedReader stdout = new BufferedReader(
                        new InputStreamReader(processOut));
                String line;
                while ((line = stdout.readLine()) != null) {
                    writer.println(line);
                    writer.flush();
                }
            } catch (IOException ex) {
                ex.printStackTrace(System.err);
            }
        }
    });
    outHandler.start();
}

public void stop() {
    System.out.println("Stopping the process");
    if (process != null) {
        try {
            process.destroy();
            process.getErrorStream().close();
            process.getInputStream().close();
            process.getOutputStream().close();
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
    }
}

public static void main(String[] args) throws Exception {
    System.setProperty("appium.bin", "/Applications/Appium.app//Contents/Resources/node_modules/.bin/appium");
    Appium appium = Appium.getInstance("/Users/<user>/tmp/appium.out", "/Users/<user>/tmp/appium.err");
    appium.start();
    TimeUnit.SECONDS.sleep(30);
    appium.stop();
}

I see we can improve a bit above solution.

  1. Create Profiles for each environment ( define appium home)
  2. you could redirect the Process output stream to a file. File name could be defined in profile are in java file.
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top