I'm trying to test a console application that uses jline for handling interaction with the user.
I'm starting the application using ProcessBuilder which gives me access to the application's:
I was expecting to use a workflow similar to this:
>
login
Username:
However, the test just freezes. Stepping through the code, it appears that jline is freezing on JNI calls to _getch on Windows. I'm guessing that the problem is because I am running Java from ProcessBuilder which is headless so there is no console and that is confusing windows. Setting -Djline.terminal=jline.UnsupportedTerminal
as per the Jline docs doesn't help either.
I've found a thread discussing Python pexpect for testing a (non-java) readline application.
Question: how can I test a jline based application using just java tools?
I gave up on trying to test just using java tools and went with using the python pexpect library to execute the console application. The tests were integrated into the maven build, but required a *nix host to run them:
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)
The full CLI test suite for the project I was working on can be found here.