I'm doing some acceptance tests at work
now, as I try to clarify our deployment process. I call them
acceptance tests because they are fairly black-box, and are run in a
different process.
To do this I added a new fixture to paste.fixture
in TestFileEnvironment. It expects to be used in a py.test environment, though
that just means it prints a lot (py.test captures prints and only
displays them when errors occur) and produces plain assertion errors
(without assertEqual style exceptions).
You set it up like:
testenv = TestFileEnvironment(
os.path.join(os.path.dirname(__file__), 'scratch')
The testenv object generally writes things in the scratch/
directory. To use it:
def test_paster_create():
# Delete any files in the scratch directory:
testenv.clear()
result = testenv.run('paster', 'create', 'ProjectName')
# Make sure a file or directory was created:
assert 'ProjectName' in result.files_created
# Get a file wrapper:
setup = result.files_created['ProjectName/setup.py']
# Test that the file contains particular text:
setup.mustcontain('ProjectName')
result = testenv.run('rm ProjectName/setup.py')
assert 'ProjectName/setup.py' in result.files_deleted
If an exit code is non-zero, or anything is written to stderr, then an
exception is raised. It looks for what files were created, deleted,
or updated during the command too. There's a couple other methods,
but I haven't needed a whole lot yet.
Anyway, I've found it makes an often annoying process (automatically
testing command-line scripts) much more pleasant. And subprocess is like
a million times better than all the ways we had to execute commands in
the past. OK, a million might be high -- 4x at least (a hint: just
use the .communicate() method, the other methods are Too Hard).