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 as needed. 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=b'', err=b'', 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)

expect_execution(channel)

Assert that the channel was used to run this command.

New in version 2.7.

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

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(enable_sftp=False)

Class representing mocked remote SSH/SFTP state.

It supports stop/start style patching (useful for doctests) but then wraps that in a more convenient/common contextmanager pattern (useful in most other situations). The latter is also leveraged by the fabric.testing.fixtures module, recommended if you’re using pytest.

Note that the expect and expect_sessions methods automatically call start, so you won’t normally need to do so by hand.

By default, a single anonymous/internal Session is created, for convenience (eg mocking out SSH functionality as a safety measure). Users requiring detailed remote session expectations can call methods like expect or expect_sessions, which wipe that anonymous Session & set up a new one instead.

New in version 2.1.

Changed in version 3.2: Added the enable_sftp init kwarg to enable mocking both SSH and SFTP at the same time.

Changed in version 3.2: Added contextmanager semantics to the class, so you don’t have to remember to call safety/stop.

__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.

safety()

Run post-execution safety checks (eg ensuring expected calls happened).

New in version 3.2.

sanity()

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

New in version 2.1.

Deprecated since version 3.2: This method has been renamed to safety & will be removed in 4.0

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(*args, **kwargs)

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.

Deprecated since version 3.2: This class has been merged with MockRemote which can now handle SFTP mocking too. Please switch to it!

__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, enable_sftp=False, transfers=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.

  • enable_sftp (bool) – Whether to enable basic SFTP mocking support.

  • transfers – None if no transfers to expect; otherwise, should be a list of dicts of the form {"method": "get|put", **kwargs} where **kwargs are the kwargs expected in the relevant SFTPClient method. (eg: {"method": "put", "localpath": "/some/path"})

New in version 2.1.

Changed in version 3.2: Added the enable_sftp and transfers parameters.

__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.

stop()

Stop any internal per-session mocks.

New in version 3.2.

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

A pseudo-command that expects an interactive shell to be executed.

New in version 2.7.

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()

A convenience rebinding of connection.

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.safety and MockRemote.stop on teardown.

New in version 2.1.

fabric.testing.fixtures.remote_with_sftp()

Like remote, but with enable_sftp=True.

To access the internal mocked SFTP client (eg for asserting SFTP functionality was called), note that the returned MockRemote object has a .sftp attribute when created in this mode.

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.