尝试了按照 Behave 文档中的指导在我们的 Django 项目上加入 BDD。今天就来分享下过程中解决的坑和一些心得体会。
如果你项目中的数据库初始数据一直维护得好,或者你们已经在用 Django 本身提供的测试机制在跑测试了,那你应该不会踩到这个坑。不然,跑测试时动态创建的 test db 中空空如也,代码中的大部分 view 应该都会抛出各种的异常来。
这个坑和上一个紧密关联。由于使用 mechanize 来模拟一个浏览器来访问,这中间抛出的异常的内容其实就是用 Django 开发过程中经常看到的异常信息页,是一个 HTML 页面。Behave 驱动 mechanize 时的输出没有进一步的细节,只能知道是 500 INTERNAL ERROR。而且如果只是把异常内容打印到 console,HTML 的内容也很难阅读。我的解决办法是把异常内容写到临时文件去:
try: ... except Exception as e: with open("/tmp/error.html", 'w') as f: f.write(e.read())
当然目前这个办法只能应对一次 test run 中只抛出一个异常。抛出多个时的情况还需要进一步改进。
也可能 Behave 本身就能做到这样的事情,不过目前还不知道。
运行的输出样子是这样:
» behave tests/features Feature: Demonstrate how to use the mechanize browser to do useful things. # tests/features/browser.feature:1 Creating test database for alias 'default'... Scenario: Logging in to our new Django site # tests/features/browser.feature:3 Given a user # tests/features/steps/browser_steps.py:7 When I log in # tests/features/steps/browser_steps.py:15 Then I see my account summary # tests/features/steps/browser_steps.py:29 And I see a warm and welcoming message # tests/features/steps/browser_steps.py:37 Destroying test database for alias 'default'... 1 feature passed, 0 failed, 0 skipped 1 scenario passed, 0 failed, 0 skipped 4 steps passed, 0 failed, 0 skipped, 0 undefined Took 0m0.7s
和驱动 selenium 或者 splinter 不一样的是,这个方法并不需要真正运行起 server 来(或者需要 django-live-server),而是利用 WSGI intercept 把 mechanize 产生的请求直接短路给 WSGI handler。在 view layer 层面做测试,这样就够了。由于避免了运行一个 browser 进程,以及其加载静态资源和运行 JS 代码的 overhead,跑一遍测试的速度应该是大大加快了的。
在 postgresql.conf 中修改下列参数
fsync=off full_page_writes=off synchronous_commit=off checkpoint_segments = 6 checkpoint_timeout = 1h
依据参照 SO 上的这个回答。
作者:czhang
原文链接:http://czhang.writings.io/articles/5-django-bdd-behave-20130519