errbot.backends.test module

class errbot.backends.test.FullStackTest(methodName='runTest')[source]

Bases: TestCase, TestBot

Test class for use with Python’s unittest module to write tests against a fully functioning bot.

For example, if you wanted to test the builtin !about command, you could write a test file with the following:

from errbot.backends.test import FullStackTest

class TestCommands(FullStackTest):
    def test_about(self):
        self.push_message('!about')
        self.assertIn('Err version', self.pop_message())
setUp(extra_plugin_dir=None, extra_test_file=None, loglevel=10, extra_config=None) None[source]
Parameters:
  • extra_plugin_dir – Path to a directory from which additional plugins should be loaded.

  • extra_test_file – [Deprecated but kept for backward-compatibility, use extra_plugin_dir instead] Path to an additional plugin which should be loaded.

  • loglevel (int) – Logging verbosity. Expects one of the constants defined by the logging module.

  • extra_config – Piece of extra bot config in a dict.

tearDown() None[source]

Hook method for deconstructing the test fixture after testing it.

class errbot.backends.test.ShallowConfig[source]

Bases: object

class errbot.backends.test.TestBackend(config)[source]

Bases: ErrBot

__init__(config)[source]

Those arguments will be directly those put in BOT_IDENTITY

build_identifier(text_representation) TestPerson[source]
build_reply(msg: Message, text=None, private: bool = False, threaded: bool = False) Message[source]

Should be implemented by the backend

change_presence(status: str = 'online', message: str = '') None[source]

Signal a presence change for the bot. Should be overridden by backends with a super().send_message() call.

connect() None[source]

Connects the bot to server or returns current connection

property mode: str
pop_message(timeout: int = 5, block: bool = True)[source]
prefix_groupchat_reply(message: Message, identifier: Identifier)[source]

Patches message with the conventional prefix to ping the specific contact For example: @gbin, you forgot the milk !

push_message(msg: Message, extras='')[source]
push_presence(presence)[source]

presence must at least duck type base.Presence

query_room(room: TestRoom) TestRoom[source]

Query a room for information.

Return type:

TestRoom

Parameters:

room (TestRoom) – The room to query for.

Returns:

An instance of Room.

reset_rooms() None[source]

Reset/clear all rooms

rooms() List[TestRoom][source]

Return a list of rooms the bot is currently in.

Returns:

A list of Room instances.

send_message(msg: Message) None[source]

This needs to be overridden by the backends with a super() call.

Parameters:

msg (Message) – the message to send.

Returns:

None

send_stream_request(user: Identifier, fsource: BinaryIO | None, name: str | None, size: int | None, stream_type: str | None) None[source]
serve_forever() None[source]

Connect the back-end to the server and serve forever.

Back-ends MAY choose to re-implement this method, in which case they are responsible for implementing reconnection logic themselves.

Back-ends SHOULD trigger connect_callback() and disconnect_callback() themselves after connection/disconnection.

shutdown() None[source]
zap_queues() None[source]
class errbot.backends.test.TestBot(extra_plugin_dir=None, loglevel=10, extra_config=None)[source]

Bases: object

A minimal bot utilizing the TestBackend, for use with unit testing.

Only one instance of this class should globally be active at any one time.

End-users should not use this class directly. Use testbot() or FullStackTest instead, which use this class under the hood.

__init__(extra_plugin_dir=None, loglevel=10, extra_config=None)[source]
assertCommand(command, response, timeout=5, dedent=False)[source]

Assert the given command returns the given response

assertCommandFound(command, timeout=5)[source]

Assert the given command exists

assertInCommand(command, response, timeout=5, dedent=False)[source]

Assert the given command returns the given response

property bot: ErrBot
exec_command(command, timeout: int = 5)[source]

Execute a command and return the first response. This makes more py.test’ist like: assert ‘blah’ in exec_command(‘!hello’)

inject_mocks(plugin_name: str, mock_dict: dict)[source]

Inject mock objects into the plugin

Example:

mock_dict = {
    'field_1': obj_1,
    'field_2': obj_2,
}
testbot.inject_mocks(HelloWorld, mock_dict)
assert 'blah' in testbot.exec_command('!hello')
pop_message(timeout: int = 5, block: bool = True)[source]
push_message(msg: Message, extras='')[source]
push_presence(presence: Presence)[source]

presence must at least duck type base.Presence

setup(extra_plugin_dir: str | None = None, loglevel=10, extra_config=None)[source]
Parameters:
  • extra_config – Piece of extra configuration you want to inject to the config.

  • extra_plugin_dir – Path to a directory from which additional plugins should be loaded.

  • loglevel (int) – Logging verbosity. Expects one of the constants defined by the logging module.

start(timeout: int = 2) None[source]

Start the bot

Calling this method when the bot has already started will result in an Exception being raised. :type timeout: int :param timeout: Timeout for the ready message pop. pop will be done 60 times so the total timeout is 60*timeout

stop() None[source]

Stop the bot

Calling this method before the bot has started will result in an Exception being raised.

zap_queues()[source]
class errbot.backends.test.TestOccupant(person, room)[source]

Bases: TestPerson, RoomOccupant

This is a MUC occupant represented as a string. DO NOT USE THIS DIRECTLY AS IT IS NOT COMPATIBLE WITH MOST BACKENDS,

__init__(person, room)[source]
property room: Room

Some backends have the full name of a user.

Returns:

the fullname of this user if available.

class errbot.backends.test.TestPerson(person, client=None, nick=None, fullname=None, email=None)[source]

Bases: Person

This is an identifier just represented as a string. DO NOT USE THIS DIRECTLY AS IT IS NOT COMPATIBLE WITH MOST BACKENDS, use self.build_identifier(identifier_as_string) instead.

Note to back-end implementors: You should provide a custom <yourbackend>Identifier object that adheres to this interface.

You should not directly inherit from SimpleIdentifier, inherit from object instead and make sure it includes all properties and methods exposed by this class.

__init__(person, client=None, nick=None, fullname=None, email=None)[source]
property aclattr

This needs to return the part of the identifier pointing to a person.

property client: str | None

This needs to return the part of the identifier pointing to a client from which a person is sending a message from. Returns None is unspecified

property email: str | None

This needs to return an email for this identifier e.g. Guillaume.Binet@gmail.com. Returns None is unspecified

property fullname: str | None

This needs to return a long display name for this identifier e.g. Guillaume Binet. Returns None is unspecified

property nick: str | None

This needs to return a short display name for this identifier e.g. gbin. Returns None is unspecified

property person

This needs to return the part of the identifier pointing to a person.

class errbot.backends.test.TestRoom(name: str, occupants: List[TestOccupant] | None = None, topic: str | None = None, bot: ErrBot = None)[source]

Bases: Room

__init__(name: str, occupants: List[TestOccupant] | None = None, topic: str | None = None, bot: ErrBot = None)[source]
Parameters:
  • name (str) – Name of the room

  • occupants – Occupants of the room

  • topic – The MUC’s topic

create() None[source]

Create the room.

Calling this on an already existing room is a no-op.

destroy() None[source]

Destroy the room.

Calling this on a non-existing room is a no-op.

property exists: bool

Boolean indicating whether this room already exists or not.

Getter:

Returns True if the room exists, False otherwise.

find_croom() TestRoom | None[source]

find back the canonical room from a this room

invite(*args)[source]

Invite one or more people into the room.

Parameters:

*args

One or more identifiers to invite into the room.

join(username: str | None = None, password: str | None = None) None[source]

Join the room.

If the room does not exist yet, this will automatically call create() on it first.

property joined: bool

Boolean indicating whether this room has already been joined.

Getter:

Returns True if the room has been joined, False otherwise.

leave(reason: str | None = None) None[source]

Leave the room.

Parameters:

reason – An optional string explaining the reason for leaving the room.

property occupants: List[TestOccupant]

The room’s occupants.

Getter:

Returns a list of occupant identities.

Raises:

MUCNotJoinedError if the room has not yet been joined.

property topic: str

The room topic.

Getter:

Returns the topic (a string) if one is set, None if no topic has been set at all.

Note

Back-ends may return an empty string rather than None when no topic has been set as a network may not differentiate between no topic and an empty topic.

Raises:

MUCNotJoinedError if the room has not yet been joined.

class errbot.backends.test.TestRoomAcl(name, occupants=None, topic=None, bot=None)[source]

Bases: TestRoom

__init__(name, occupants=None, topic=None, bot=None)[source]
Parameters:
  • name – Name of the room

  • occupants – Occupants of the room

  • topic – The MUC’s topic

property aclattr
Returns:

returns the unique identifier that will be used for ACL matches.

errbot.backends.test.testbot(request) TestBot[source]

Pytest fixture to write tests against a fully functioning bot.

For example, if you wanted to test the builtin !about command, you could write a test file with the following:

def test_about(testbot):
    testbot.push_message('!about')
    assert "Err version" in testbot.pop_message()

It’s possible to provide additional configuration to this fixture, by setting variables at module level or as class attributes (the latter taking precedence over the former). For example:

extra_plugin_dir = '/foo/bar'

def test_about(testbot):
    testbot.push_message('!about')
    assert "Err version" in testbot.pop_message()

..or:

extra_plugin_dir = '/foo/bar'

class Tests:
    # Wins over `extra_plugin_dir = '/foo/bar'` above
    extra_plugin_dir = '/foo/baz'

    def test_about(self, testbot):
        testbot.push_message('!about')
        assert "Err version" in testbot.pop_message()

..to load additional plugins from the directory /foo/bar or /foo/baz respectively. This works for the following items, which are passed to the constructor of TestBot:

  • extra_plugin_dir

  • loglevel