tests: Add contrib_bots/test-bots file.

This test uses unittest and mock library. It mocks
'BotHandlerApi' class. This test works independent of
the rest of the code outside contrib_bots folder.

Merged with a few changes by tabbott to fix lint issues; we'll need to
do further work on this framework, but since it's not hooked up to
anything, it's reasonable to merge early so others can collaborate on
improving it.
This commit is contained in:
Abhijeet Kaur 2017-05-22 08:44:56 +05:30 committed by Tim Abbott
parent b540c09768
commit f83ddd658c
6 changed files with 124 additions and 0 deletions

0
contrib_bots/__init__.py Normal file
View file

View file

View file

@ -0,0 +1,52 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import unittest
from unittest import TestCase
our_dir = os.path.dirname(os.path.abspath(__file__))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestDefineBot(TestCase):
# Messages to be sent to bot for testing.
# Eventually more test messages can be added.
def request_messages(self):
# type: None -> List[Dict[str, str]]
messages = []
message1 = {'content': "foo", 'type': "private", 'sender_email': "foo"}
message2 = {'content': "cat", 'type': "stream", 'display_recipient': "foo", 'subject': "foo"}
messages.append(message1)
messages.append(message2)
return messages
# Reply messages from the test bot.
# Each reply message corresponding to each request message.
def bot_response_messages(self):
# type: None -> List[str]
messages = []
message1 = "**foo**:\nDefinition not available."
message2 = ("**cat**:\n\n* (**noun**) a small domesticated carnivorous mammal "
"with soft fur, a short snout, and retractile claws. It is widely "
"kept as a pet or for catching mice, and many breeds have been "
"developed.\n  their pet cat\n\n")
messages.append(message1)
messages.append(message2)
return messages
def test_define(self):
# type: None -> None
# Edit bot_module to test different bots, the below code can be looped for all the bots.
bot_module = "./bots/define/define.py"
messages = self.request_messages()
bot_response = self.bot_response_messages()
test_case = BotTestCase()
test_case.bot_test(messages=messages, bot_module=bot_module, bot_response=bot_response)

View file

@ -0,0 +1,43 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import unittest
from mock import MagicMock, patch
from unittest import TestCase
from run import get_lib_module
from bot_lib import StateHandler
from contrib_bots import bot_lib
from six.moves import zip
class BotTestCase(TestCase):
def mock_test(self, messages, message_handler, bot_response):
# type: (List[Dict[str, str]], Function) -> None
# Mocking BotHandlerApi
with patch('contrib_bots.bot_lib.BotHandlerApi') as MockClass:
instance = MockClass.return_value
for (message, response) in zip(messages, bot_response):
# Send message to the concerned bot
message_handler.handle_message(message, MockClass(), StateHandler())
# Check if BotHandlerApi is sending a reply message.
# This can later be modified to assert the contents of BotHandlerApi.send_message
instance.send_reply.assert_called_with(message, response)
def bot_to_run(self, bot_module):
# type: None -> Function
lib_module = get_lib_module(bot_module)
message_handler = lib_module.handler_class()
return message_handler
def bot_test(self, messages, bot_module, bot_response):
message_handler = self.bot_to_run(bot_module)
self.mock_test(messages=messages, message_handler=message_handler, bot_response=bot_response)

View file

@ -1,5 +1,6 @@
#!/usr/bin/env python
from __future__ import print_function
from __future__ import absolute_import
import importlib
import logging

28
contrib_bots/test-bots Executable file
View file

@ -0,0 +1,28 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import unittest
from unittest import TestCase
if __name__ == '__main__':
def dir_join(dir1, dir2):
# type: (str, str) -> str
return os.path.abspath(os.path.join(dir1, dir2))
bots_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = dir_join(bots_dir, '..')
bots_test_dir = dir_join(bots_dir, 'bots')
sys.path.insert(0, root_dir)
loader = unittest.TestLoader()
suite = loader.discover(start_dir=bots_test_dir, top_level_dir=root_dir)
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)
if result.errors or result.failures:
raise Exception('Test failed!')