Keep appium server running on windows/mac

Hello all,

For creating CI solution for our mobile apps we plan to run tests using appium. We will thus require the appium server to be continuously running for test script execution after every apk/ipa file is generated.

This can be done by starting the appium server through the appium app/command line but that will mean that there is always a window open and if someone accidentally closes them/restarts the server than our test scripts will fail.

Can anyone suggest a better way to this in windows and mac ? (For example like running appium as a service in windows)

Why you do not want to start appium server in test code before start tests? We do this with macMinis which are working as slave machines to Jenkins.

So what exactly do you have installed on the macMinis? Right now, my current setup is jenkins server on one machine, and a couple Appium process running as a user agents on a couple of macMinis. I keep the Appium process running by having it configured as keep alive configured through the LaunchControl UI.

Is Appium always running on the jenkins slave macMinis? Or do you have jenkins jobs configured to start it?

Hello,

Thanks for your reply Aleksei. I am actually very new to appium so my understanding is that we will keep the appium service always up and running and whenever a test script needs to be executed then it will connect to the already running appium server for executing test on the mobile device. So for us appium server start/stop is outside the test code.

Is starting the appium server before every test execution and then stopping it after the test execution finishes a better way to do this?

Hi Brian,

On both my mac and windows I have appium as well as jenkins slave installed. We are currently using windows for android device testing and mac for iphone device testing.

We are using Jenkins jobs for triggering the test on the mac . The test scripts are then making connection to appium server which is already running(started manually).

@Brian_Watson @varun_mathur
Hi,

our macMinis are full jenkins slaves. they used for:

  1. testing (iOS/Android)
  2. building both iOS and Android client
  3. distributing iOS clients into HockeyApp and Android client into dropbox with sending emails with links
  4. monitoring production environment
  5. some other day to day needs

more info how connect slave to jenkins server
Jenkins Slave

jenkins server itself does nothing accept WEB UI and giving orders to user tasks or schedule monitor scipts. it is actually running on some amazon machine and has disabled nodes.

this way is 100 times more convenient cause when your test code running on slave machine it can see itself simulators, devices and so on. thus some tasks that Appium can’t do we can do in code - example add needed photo to Simulator and use it in test.

Hey Varun,

My setup sounds somewhat similar. We have a Windows Jenkins server machine for kicking off our web Selenium tests against SauceLabs (for now) and our mobile iOS and Android tests against a couple MacMini “Servers” running Appium all the time. On those MacMinis, we have 2 Appium sessions started and running on different ports at all times. I used LaunchControl to make them agent processes that could be kept alive all the time.

The problem I run into is on occasion, I lose the ability to start a new session on one of the Appium processes. Usually because of…

  • A previous test has ended early without cleaning itself up properly. Such as when we cancel a Jenkins run.
  • Sometimes the emulators/simulator hangs or runs high on memory.
  • The Appium process just decides to stop responding.

What I then need to do is remote into the MacMini and unload and reload the Appium agent service that is not working. But this is a manual process. I’m trying to make this more automated to be more reliable.

Aleksei,

Why the heck didn’t I already install a Jenkins agent on the MacMinis?!?! I think this will help solve some of the issues I am seeing described in the post above. So I have the Jenkins slaves now running on the MacMinis and I have verified that when the jobs are kicked off from the master, they execute on the slave machines when my Appium process is started already.

My next goal is to add build steps to my Jenkins jobs to start an Appium instance at the beginning of the test run and stop it at the end. Do your test runs do this now? If so, how are your jobs configured may I ask? I just tried adding a shell execute step before the tests run to start Appium by using my same shell script that I use for launchctrl where I just pass in a port number and it starts a new appium process. But it of course stops the whole job from running. So it looks like I need to make sure I’m starting it in the background so the next build step that actually runs my tests can get executed. I’m looking into using a tool called “daemonize” now for that, unless someone else has an idea they are using.

Thanks for the reply, it’s great info! And I’ll follow up a little later about adding photos to the simulator as I need to do that too! :slight_smile:

@Brian_Watson

  1. Appium staring in test in section of “beforeSuite” of testNG. It is reading property inside testNG xml file - does appium need to be started or not.
  2. jobs config is like:
  • git pull of tests
  • run test
  • publish test results with testNG plugin
  • collect screenshots of failed tests as artifacts
  • send email

Okay I see, so you start the Appium process from within your java test code? Would you mind sharing the function you use to start Appium from within java??

the code. take what you need from it. you may skip to check that server started and just sleep few seconds instead.

// server 1
        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");
        }
        list.add("--port");
        list.add(appiumServer1_PortPublic);
        list.add("--bootstrap-port");
        list.add(String.valueOf(Integer.parseInt(appiumServer1_PortPublic)+1000));
        list.add("--command-timeout");
        list.add("90");
        list.add("--session-override");

        try {
            ProcessBuilder pb1 = new ProcessBuilder(list);

            //print inputStream to console
            pb1.redirectErrorStream(true);
            pb1.redirectOutput(ProcessBuilder.Redirect.INHERIT);
            appium_Process = pb1.start();
            for (int i=0; i<10; i++) { //2x10=20sec
                sleep(2);
                responseData = Utils.sendRequest("GET", new URL("http://0.0.0.0:" + appiumServer1_PortPublic));
                if (responseData!=null) {
                    System.out.println("  appium_1 ping - " + responseData.getResponseBody());
                    break;
                }
            }
            System.out.println("  appium server started");
        } catch (Exception e) {
            System.out.println("  appium server start FAILED");
            e.printStackTrace();
        }

Thank you! I’m going to mess with this tonight and I’ll let you know how it goes! :grin:

Thanks. I now have a jenkins agent installed on a remote mac mini, and when the job is pushed over there to execute, it starts up a new Appium server process. Right now, I have it configured to start Appium at the beginning of each suite (class) in JUnit, and it stops Appium at the end of each suite. Rinse… Repeat for all suites (classes). Each runs one after the other and takes a couple hours to run all tests.

What I’d like to figure out next, is how to be able to run them in parallel. Say if we have 3 mac minis, and can run 2 appium processes on each, how to I get my suite of tests to split itself up between all of them?

Hi Brian, I hope you were able to split multiple appium sessions inside Jenkins job.
I am facing a small issue where I am starting appium server using Jenkins slave set up on mac. Below are the logs

[StartAppium] $ /bin/sh -xe /var/folders/bg/2kkn1qlj0jbf4l5wnlt96hch0000gs/T/hudson7050333291051788429.sh
+ /usr/local/lib/node_modules/appium/build/lib/main.js
env: node: No such file or directory
Build step 'Execute shell' marked build as failure
Finished: FAILURE

Could you see something that can be corrected. Though I am able to start the appium exe one using this “/usr/local/bin/node /Applications/Appium.app/Contents/Resources/node_modules/appium/build/lib/main.js”