3

有没有办法让 appium 在我为 junit 测试编写的代码中启动?因为 appium 只需要在我的测试运行时运行,所以让 appium 服务器始终运行对我来说没有意义。

现在我正在使用 junit 和 maven 来运行测试构建。由于 appium 的稳定性问题,它有时会在构建过程中死掉,从而导致所有剩余测试失败。我想知道是否可以在 @Before 方法中添加一些东西来启动 appium 服务器,然后再将 WebDriver 连接到它,然后在 @After 方法中终止它。这应该解决 appium 失败的任何问题,因为它可以在开始下一个测试之前重置。

仍在研究java中的一般开始和结束进程,看看这是否可行。如果我弄清楚这一点,我将更新这篇文章以帮助其他有兴趣以这种方式进行测试的人。

4

4 回答 4

2

弄清楚如何通过在代码中运行终端命令来使其工作

@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 输出,则不建议这样做

于 2014-02-21T22:04:19.850 回答
1

我为此编写了一个库。

/**
 *@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();
}
于 2015-02-25T23:32:08.977 回答
0

我已经以非常相似的方式解决了这个问题,使用 aDefaultExecutor来跟踪 Appium 进程,以便在测试结束时将其销毁。这也允许在测试期间使用DefaultExecuteResultHandler.

为了避免使用睡眠等待 Appium 启动,您可以WebDriver在 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");
        }
    }

如果您想减少轮询频率,可以在 catch 块中添加睡眠。

于 2014-07-22T14:42:53.940 回答
0

我看到我们可以改进上述解决方案。

  1. 为每个环境创建配置文件(定义 appium 主页)
  2. 您可以将 Process 输出流重定向到文件。文件名可以在配置文件中定义在 java 文件中。
于 2015-02-18T20:06:33.210 回答