I want to add few tests on how my cli app handles different signals (SIGTERM
, etc). And I am using native testing solution click.testing.CliRunner
alongside of pytest.
Test looks pretty standard and simple
def test_breaking_process(server, runner):
address = server.router({'^/$': Page("").exists().slow()})
runner = CliRunner(mix_stderr=True)
args = [address, '--no-colors', '--no-progress']
result = runner.invoke(main, args)
assert result.exit_code == 0
And here I am stuck, how could I send SIGTERM
to process in runner.invoke
? I see no problem to do it if I use e2e tests (calling executable and not CLIrunner), but I would like to try to implement this (at least able to send os.kill)
is there a way to do it?
So, if you want to test your click powered application for handling different signals, you can do next procedure.
def test_breaking_process(server, runner):
from multiprocessing import Queue, Process
from threading import Timer
from time import sleep
from os import kill, getpid
from signal import SIGINT
url = server.router({'^/$': Page("").slow().exists()})
args = [url, '--no-colors', '--no-progress']
q = Queue()
# Running out app in SubProcess and after a while using signal sending
# SIGINT, results passed back via channel/queue
def background():
Timer(0.2, lambda: kill(getpid(), SIGINT)).start()
result = runner.invoke(main, args)
q.put(('exit_code', result.exit_code))
q.put(('output', result.output))
p = Process(target=background)
p.start()
results = {}
while p.is_alive():
sleep(0.1)
else:
while not q.empty():
key, value = q.get()
results[key] = value
assert results['exit_code'] == 0
assert "Results can be inconsistent, as execution was terminated" in results['output']