Integrate Appium

I’m trying to start appium server as a pre-build step for my test project, since start appium directly will cause a “Process leaked file descriptors” error, appium server will be closed after build step finish.

So I started appium with this command: daemonize /usr/local/bin/appium, start appium as a daemon, in this situation, ios simulator closed right after started, appium server gave this log:

[INST STDERR] Failed to authorize rights (0x1) with status: -60007
[INST STDERR] instruments[21350:1878375] -[XRSimulatorDevice prepareConnection:]:   Unable to authorize simulated daemon (21390)

Any ideas on how to solve this problem? Or what is a good way to integrate appium with Jenkins? I’ve seen discussions here and there, people all seems to stuck on this problem. Correct me if I’m wrong but I think most people open appium manually and leave it on.

@nieschumi
You can automate the process of controlling the server using this library.

@Hassan_Radi
Thanks to the idea of your library, I use the same idea to make it work on Mac.

But I notice a weird thing:
When I run the test after starting appium server in program, the test will stop in the middle of somewhere, there’s no error or logs, it just stops executing, the test never finish by itself unless I manually stop it.

The test works fine if I first start appium manually and then run the test. Do you have any idea why this happens?

This is how I start and stop appium server

@BeforeClass
public void startAppium(){
    startAppiumServer();
}

@AfterClass
public void stopAppium(){
    stopAppiumServer();
}

Detail in start and stop server function

 public void startAppiumServer() {
    String projectDirectory = Paths.get("").toAbsolutePath().toString();
    String startServerBashScript = projectDirectory + File.separator + "startAppium4724.sh";
    Runtime runtime = Runtime.getRuntime();

    try {
        runtime.exec("sh " + startServerBashScript);
        Thread.sleep(8000);

          } catch (IOException e) {
        System.out.println(e);
          } catch (InterruptedException e) {
        System.out.println(e);
          }
}

public void stopAppiumServer() {
    String projectDirectory = Paths.get("").toAbsolutePath().toString();
    String stopServerBashScript = projectDirectory + File.separator + "stopAppiumServer.sh";
    Runtime runtime = Runtime.getRuntime();

    try {
        runtime.exec("sh " + stopServerBashScript);
    } catch (IOException e) {
        System.out.println(e);
    }
}

What’s in bash script
To start

#!/usr/bin/env bash
appium --port 4724 --command-timeout 120 --log /Users/shuanglang/Desktop/appiumOutput.txt

To stop

#!/usr/bin/env bash
pid=$(lsof -i:4724 -t);
kill -TERM $pid || kill -KILL $pid

Providing Appium logs will help in identifying the cause to this problem, please provide them and also the Appium server version and client binding you are using.

1 try to play with log level
2 we add session-override in case when appium was not killed before by some reason
3 no idea why but we found that starting appium with “Runtime” is working worse during long running tests (1-2h and more) and we use “ProcessBuilder” instead.

e.g. we start as: [appium, --log-level, error, --port, 4725, --session-override]

Example of code:

        List list = new ArrayList<String>();
        list.add("appium");
        list.add("--log-level");
        if(devicePlatform.contains("android")) list.add("error");
        else list.add("error");
        if(devicePlatform.contains("iOS")) {
            //list.add("--locale");
            //list.add("de_DE");
            //list.add("--language");
            //list.add("en");
            //list.add("--show-ios-log");
            //list.add("--show-sim-log");
        }
        /*
        if(deviceID!=null && !deviceID.isEmpty()) {
            list.add("--udid");
            list.add(deviceID);
        }
        */

        list.add("--port");
        if (devicePlatform.contains("android")) {
            System.out.println("    start server for ANDROID");
            list.add("4725");
        } else {
            System.out.println("    start server for iOS");
            list.add("4724");
        }
        list.add("--session-override");

        System.out.println(" start appium as: "+list.toString());
        // create the process builder
        try {
            ProcessBuilder pb = new ProcessBuilder(list);
            appium_Process = pb.start();
            //print inputStream to console
            final Scanner in = new Scanner(appium_Process.getInputStream());
            Thread t = new Thread() {
                public void run() {
                    String output;
                    while (in.hasNextLine()) {
                        output = in.nextLine();
                        System.out.println(output);
                    }
                }
            };
            t.start();
            System.out.println("  appium server started");
            Thread.sleep(5000);
        } catch (Exception e) {
            System.out.println("  appium server start FAILED");
            e.printStackTrace();
        }

I tried with ProcessBuilder, all my tests works fine now, no more weird pausing during test run.

Actually all your three suggestions are helpful, thank you so much!

There’s no extra logs or error messages when test pause, I use ProcessBuilder instead of Runtime, I don’t see any issues now.