testing

The fabric.testing subpackage contains a handful of test helper modules:

  • fabric.testing.base which only depends on things like mock and is appropriate in just about any test paradigm;
  • fabric.testing.fixtures, containing pytest fixtures and thus only of interest for users of pytest.

All are documented below. Please note the module-level documentation which contains install instructions!

testing.base

This module contains helpers/fixtures to assist in testing Fabric-driven code.

It is not intended for production use, and pulls in some test-oriented dependencies such as mock. You can install an ‘extra’ variant of Fabric to get these dependencies if you aren’t already using them for your own testing purposes: pip install fabric[testing].

Note

If you’re using pytest for your test suite, you may be interested in grabbing fabric[pytest] instead, which encompasses the dependencies of both this module and the fabric.testing.fixtures module, which contains pytest fixtures.

New in version 2.1.

class fabric.testing.base.Command(cmd=None, out='', err='', in_=None, exit=0, waits=0)

Data record specifying params of a command execution to mock/expect.

Parameters:
  • cmd (str) – Command string to expect. If not given, no expectations about the command executed will be set up. Default: None.
  • out (bytes) – Data yielded as remote stdout. Default: b"".
  • err (bytes) – Data yielded as remote stderr. Default: b"".
  • exit (int) – Remote exit code. Default: 0.
  • waits (int) – Number of calls to the channel’s exit_status_ready that should return False before it then returns True. Default: 0 (exit_status_ready will return True immediately).

New in version 2.1.

__weakref__

list of weak references to the object (if defined)

class fabric.testing.base.MockChannel(*args, **kwargs)

Mock subclass that tracks state for its recv(_stderr)? methods.

Turns out abusing function closures inside MockRemote to track this state only worked for 1 command per session!

New in version 2.1.

class fabric.testing.base.MockRemote

Class representing mocked remote state.

By default this class is set up for start/stop style patching as opposed to the more common context-manager or decorator approach; this is so it can be used in situations requiring setup/teardown semantics.

Defaults to setting up a single anonymous Session, so it can be used as a “request & forget” pytest fixture. Users requiring detailed remote session expectations can call methods like expect, which wipe that anonymous Session & set up a new one instead.

New in version 2.1.

__weakref__

list of weak references to the object (if defined)

expect(*args, **kwargs)

Convenience method for creating & ‘expect’ing a single Session.

Returns the single MockChannel yielded by that Session.

New in version 2.1.

expect_sessions(*sessions)

Sets the mocked remote environment to expect the given sessions.

Returns a list of MockChannel objects, one per input Session.

New in version 2.1.

sanity()

Run post-execution sanity checks (usually ‘was X called’ tests.)

New in version 2.1.

start()

Start patching SSHClient with the stored sessions, returning channels.

New in version 2.1.

stop()

Stop patching SSHClient.

New in version 2.1.

class fabric.testing.base.MockSFTP(autostart=True)

Class managing mocked SFTP remote state.

Used in start/stop fashion in eg doctests; wrapped in the SFTP fixtures in conftest.py for main use.

New in version 2.1.

__weakref__

list of weak references to the object (if defined)

class fabric.testing.base.Session(host=None, user=None, port=None, commands=None, cmd=None, out=None, in_=None, err=None, exit=None, waits=None)

A mock remote session of a single connection and 1 or more command execs.

Allows quick configuration of expected remote state, and also helps generate the necessary test mocks used by MockRemote itself. Only useful when handed into MockRemote.

The parameters cmd, out, err, exit and waits are all shorthand for the same constructor arguments for a single anonymous Command; see Command for details.

To give fully explicit Command objects, use the commands parameter.

Parameters:
  • user (str) –
  • host (str) –
  • port (int) – Sets up expectations that a connection will be generated to the given user, host and/or port. If None (default), no expectations are generated / any value is accepted.
  • commands

    Iterable of Command objects, used when mocking nontrivial sessions involving >1 command execution per host. Default: None.

    Note

    Giving cmd, out etc alongside explicit commands is not allowed and will result in an error.

New in version 2.1.

__weakref__

list of weak references to the object (if defined)

generate_mocks()

Mocks SSHClient and Channel.

Specifically, the client will expect itself to be connected to self.host (if given), the channels will be associated with the client’s Transport, and the channels will expect/provide command-execution behavior as specified on the Command objects supplied to this Session.

The client is then attached as self.client and the channels as self.channels.

Returns:None - this is mostly a “deferred setup” method and callers will just reference the above attributes (and call more methods) as needed.

New in version 2.1.

testing.fixtures

pytest fixtures for easy use of Fabric test helpers.

To get Fabric plus this module’s dependencies (as well as those of the main fabric.testing.base module which these fixtures wrap), pip install fabric[pytest].

The simplest way to get these fixtures loaded into your test suite so Pytest notices them is to import them into a conftest.py (docs). For example, if you intend to use the remote and client fixtures:

from fabric.testing.fixtures import client, remote

New in version 2.1.

fabric.testing.fixtures.client()

Mocks SSHClient for testing calls to connect().

Yields a mocked SSHClient instance.

This fixture updates get_transport to return a mock that appears active on first check, then inactive after, matching most tests’ needs by default:

  • Connection instantiates, with a None .transport.
  • Calls to .open() test .is_connected, which returns False when .transport is falsey, and so the first open will call SSHClient.connect regardless.
  • .open() then sets .transport to SSHClient.get_transport(), so Connection.transport is effectively client.get_transport.return_value.
  • Subsequent activity will want to think the mocked SSHClient is “connected”, meaning we want the mocked transport’s .active to be True.
  • This includes Connection.close, which short-circuits if .is_connected; having a statically True active flag means a full open -> close cycle will run without error. (Only tests that double-close or double-open should have issues here.)

End result is that:

  • .is_connected behaves False after instantiation and before .open, then True after .open
  • .close will work normally on 1st call
  • .close will behave “incorrectly” on subsequent calls (since it’ll think connection is still live.) Tests that check the idempotency of .close will need to tweak their mock mid-test.

For ‘full’ fake remote session interaction (i.e. stdout/err reading/writing, channel opens, etc) see remote.

New in version 2.1.

fabric.testing.fixtures.connection()

Yields a Connection object with mocked methods.

Specifically:

  • the hostname is set to "host" and the username to "user";
  • the primary API members (Connection.run, Connection.local, etc) are replaced with mock.Mock instances;
  • the run.in_stream config option is set to False to avoid attempts to read from stdin (which typically plays poorly with pytest and other capturing test runners);

New in version 2.1.

fabric.testing.fixtures.cxn()

Yields a Connection object with mocked methods.

Specifically:

  • the hostname is set to "host" and the username to "user";
  • the primary API members (Connection.run, Connection.local, etc) are replaced with mock.Mock instances;
  • the run.in_stream config option is set to False to avoid attempts to read from stdin (which typically plays poorly with pytest and other capturing test runners);

New in version 2.1.

fabric.testing.fixtures.remote()

Fixture allowing setup of a mocked remote session & access to sub-mocks.

Yields a MockRemote object (which may need to be updated via MockRemote.expect, MockRemote.expect_sessions, etc; otherwise a default session will be used) & calls MockRemote.sanity and MockRemote.stop on teardown.

New in version 2.1.

fabric.testing.fixtures.sftp()

Fixture allowing setup of a mocked remote SFTP session.

Yields a 3-tuple of: Transfer() object, SFTPClient object, and mocked OS module.

For many/most tests which only want the Transfer and/or SFTPClient objects, see sftp_objs and transfer which wrap this fixture.

New in version 2.1.

fabric.testing.fixtures.sftp_objs(sftp)

Wrapper for sftp which only yields the Transfer and SFTPClient.

New in version 2.1.

fabric.testing.fixtures.transfer(sftp)

Wrapper for sftp which only yields the Transfer object.

New in version 2.1.