Запустите bat-файл из кода Java и подождите, пока он выполнит скрипт TestComplete - нет, ничего не поделаешь :( - PullRequest
1 голос
/ 29 июля 2011

Я пишу этот вопрос, связанный с моей предыдущей темой:

Запустите bat-файл из java-кода, чтобы получить желаемый результат в txt-файле - no can do: ( Вкратце: я написал программу на Java, которая запускает файл bat. Этот bat-файл запускает скрипт TestComplete8, который выполняет тестирование настольного приложения. После завершения теста bat-файл генерирует файл result.txt и выводит в него информацию о тесте. Я застрял с другой проблемой прямо сейчас: теперь из моего Java-кода я хотел бы подождать, пока работа с битой не закончится. Я делаю это циклически, пока не появится файл с именем result.txt. Не самое приятное решение, я думаю, но я думал, что оно может работать, также пробовал разные решения. Что происходит, так это то, что он будет нормально зацикливаться и ждать, пока файл не будет создан, но testcomplete не выполняет тест. Это очень странно, потому что testcomplete запускается, я вижу, что тест начинается, мой AUT также запускается, но потом ничего не происходит. Testcomplete ждет любого объекта и нигде не щелкает, просто ждет, пока закончится заранее определенное время для действия. Когда я запускаю тест без ожидания в коде, все в порядке. Я просто не понимаю, почему во время теста ничего не происходит, когда включено ожидание, и почему оно работает нормально, когда я просто удаляю любые do - while или waitFor (), или даже я пытался запустить его в отдельных потоках. (

У меня такое ощущение, что это может быть как-то связано с ОС и иметь какое-то отношение к процессам, поскольку он запускает что-то вроде bat как процесса, а затем bat запускает дочерний процесс как testcomplete или что-то подобное. Спасибо за любые ответы

Исходный код как спрошено: Прямо сейчас я пробовал решение с измененным bat-файлом:

@ECHO OFF
"C:\Program Files (x86)\Automated QA\TestComplete 8\Bin\TestComplete.exe" "C:..." /r /p:projname PathToApp="C:\...p" Login=... Password=B1  /t:"KeywordTests|..." /exit

и код для запуска и ожидания в последней версии:

        new Thread(new Runnable() {
        public void run() {
            File file = new File("D:\\");
            int exitValue = -1;

            try {
                Process process = Runtime.getRuntime().exec(batch, null, file);
                while (true) {
                    try {
                        exitValue = process.exitValue();
                        System.out.println(exitValue);
                        break;
                    } catch (IllegalThreadStateException e) {
                        // e.printStackTrace();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        System.out.println("Waiting for process...");
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

1 Ответ

2 голосов
/ 29 июля 2011

Наиболее вероятной причиной, не зная больше о проблеме, является распространенная причина, возникающая при запуске внешних процессов из Java. При запуске внешнего процесса между родительским и дочерним процессом создаются три потока: ввод, вывод, ошибка.

Вы можете сравнить их с System.in, System.out и System.err. Если родительский процесс (Java) не активно использует данные из потоков out и error, дочерний процесс может заблокироваться, поскольку ОС достигнет предела буфера в потоке и предотвратит дальнейшую запись до тех пор, пока он не будет использован. Это вполне вероятно, если ваш скрипт пишет в стандартную или стандартную ошибку.

Я бы рекомендовал использовать apache commons-exec для управления запуском Java-процессов.

Вот пример кода, который, как я знаю, работает.

    CommandLine commandLine = new CommandLine( "TestComplete8.bat" );
    commandLine.addArgument( ... );
    commandLine.addArgument( ... );

    DefaultExecutor executor = new DefaultExecutor();
    executor.setExitValue( 0 );
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    ByteArrayOutputStream errorStream = new ByteArrayOutputStream();
    executor.setStreamHandler( new PumpStreamHandler( outputStream, errorStream ) );

    try
    {
        executor.execute( commandLine );
    }
    catch ( ExecuteException e )
    {
        // TODO: ...
    }
    catch ( IOException e )
    {
        // TODO: ...
    }

Затем вы можете просмотреть потоки вывода / ошибок, если хотите, когда execute возвращает.

...