Well, besides setup scripts the other thing I want to take from Rails is building testability into the system. But I haven't quite figured out how to do that. The specific idea I want to take is that of data fixtures -- data that puts the site into a "known" state that can be tested against. In the Rails world that's a bunch of rows to be inserted into the database, which is a particular case I'm interested in, but of course it should be more general.
That's not too terribly hard; it's mostly grunt work. Not super-simple, but not hard. I've added the necessary configuration file hooks to handle different kind of environments running out of the same directory: include() and load(), both of which have access to previous files, so you could do:
if debug: include('database_debug.conf') else: include('database.conf')
Or any number of things, like testing if profile == 'debug'. This kind of flexibility (among other things) makes Python files very useful; I was skeptical at first about Python syntax (having invested much time into an INI-file based configuration), but it makes so many things so easy.
Oh, but back to the actual testing. One thing I like about how things have shaped up in Paste is that testing has been pretty easy. paste.wsgilib has a function raw_interactive(app, path_info) that is quite useful, and I use it in paste.tests.fixture in fake_request(). It lets me do things like:
res = fake_request(p, '/') res.all_okay() # Asserts status is 200 OK, no errors logged assert 'Welcome' in res assert res.header('content-type') == 'text/html'
And so on. There's some things I feel should be tweaked. For instance, it should normal throw an error for any status besides 200 OK (with a keyword to explicitly say that another status is okay or expected). Maybe test for compliant HTML (paste.wdg_validate is a start for this). It should make requests a little easier to perform -- maybe it should be a wrapper around an application, for instance. But it's pretty close as it is, it just needs a little loving to get all the convenience methods in (and a good testing framework is all about convenience). And then you could do the whole thing in doctest, maybe like:
>>> app = FakeApp(this_app) >>> res = app.post('/login', data={'username': 'bob', 'password': 'bob'}) >>> res.element(id='message') <div id="message">User 'bob' logged in</div>
And so on. You could put this right into your object's docstrings. Using things like doctest_xml_compare you can make your test say just what you mean, and no more.
That could be really sweet. Interested? Join paste-users and we'll talk there.
Update: There's been some progress on this in paste.tests.fixture.TestApp
Do you have an RSS feed for this site?
Auto-discoverable, yes; it's at https://ianbicking.org/feeds/new_pages.xml
Awesome. Exactly what I was looking for. Loved pbp and twill, but couldn't integrate it very well with py.test. Once you go py.test, you can't go back. :)