как протестировать консольное приложение на основе jline

Я пытаюсь протестировать консольное приложение, которое использует jline для обработки взаимодействия с пользователем.

Я запускаю приложение с помощью ProcessBuilder. который дает мне доступ к приложениям:

Я ожидал использовать рабочий процесс, подобный этому:

  • Запустить приложение
  • Читать вывод, пока не появится приглашение приложения >
  • Отправить ввод для моего тестового примера, например. login
  • Читайте вывод, пока я не увижу ожидаемый ответ, например. Username:
  • и так далее

Однако тест просто зависает. Проходя код, оказывается, что jline зависает при вызовах JNI на _getch в Windows. Я предполагаю, что проблема в том, что я запускаю Java из ProcessBuilder, который безголовый, поэтому нет консоли, и это сбивает с толку окна. Установка -Djline.terminal=jline.UnsupportedTerminal в соответствии с документами Jline также не помогает.

Я нашел ветку, в которой обсуждается Python pexpect для тестирования (не-java) приложения readline.

Вопрос: как я могу протестировать приложение на основе jline, используя только инструменты Java?


person Chris Snow    schedule 04.05.2014    source источник
comment
У меня точно такая же проблема. Достигли ли вы какого-то прогресса?   -  person Alex    schedule 18.02.2015
comment
Я добавил ответ, показывающий решение, с которым я пошел.   -  person Chris Snow    schedule 18.02.2015


Ответы (1)


Я отказался от попыток протестировать только с помощью инструментов Java и использовал библиотеку python pexpect для выполнения консольного приложения. Тесты были интегрированы в сборку maven, но для их запуска требовался хост *nix:

import unittest
import pexpect
import os
import signal
import subprocess
import urllib
import urllib2
import json

from wiremock import WiremockClient

class TestInteractive(unittest.TestCase):

    cli_cmd = "java -jar " + os.environ["CLI_JAR"]

    # ... code omitted for brevity 

    def test_interactive_mode_username_and_password_sent_to_server(self):
        child = pexpect.spawn(TestInteractive.cli_cmd, timeout=10)
        child.expect   ('Username: ')
        child.sendline ('1234')
        child.expect   ('Password: ')
        child.sendline ('abcd')
        child.expect   ('Successfully authenticated')
        child.expect   ('stratos> ')
        child.sendline ('exit')
        child.expect   (pexpect.EOF)
        # CLI sends GET request to mock server url /stratos/admin/coookie
        self.assertEqual(self.wiremock.get_cookie_auth_header(), "1234:abcd")

    # ... code omitted for brevity

if __name__ == '__main__':
    try: 
        unittest.main()
    # handle CTRL-C
    except KeyboardInterrupt:
        # shut down wiremock 
        TestInteractive.wiremock.stop()
        exit(1) 

Полный набор тестов CLI для проекта, над которым я работал, можно найти здесь.

person Chris Snow    schedule 17.02.2015
comment
Ага, понятно. Это хорошо. Спасибо. - person Alex; 18.02.2015