Automatically launch the application during the test?

Is there a way to get appium to run in the code I write for the junit test? Since appium needs to be launched only during my test, it makes no sense for me to maintain a permanent application server.

Right now I'm using junit and maven to run test collections. Due to stability issues in appium, it sometimes dies in the middle of the build, thereby failing all the 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 complete it in the @After method. This should concern any problems with appium errors, as it may reset before starting the next test.

Still study the starting and ending processes in Java to find out if this will work. If I find out, I will update this post to help anyone interested in testing this method.

+3
source share
4 answers

I solved it very similarly, using DefaultExecutorto track the Appium process so that it could be destroyed at the end of the tests. It also allows you to output Appium output during tests using DefaultExecuteResultHandler.

To avoid using sleep to wait for Appium to start, you can create your instance WebDriverinside 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 can add sleep to the catch block if you want to poll less frequently.

0
source

It turned out how to make this work by simply running the terminal command in 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
}

CI, jenkins, , , , . , appium , . , appium, .

+2

I wrote 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();
}
+1
source

I see that we can improve the solution a bit.

  • Create profiles for each environment (specify appium home)
  • You can redirect the process output to a file. The file name can be defined in the profile in the java file.
0
source

All Articles