Doing BDD with Behave on a Django project

尝试了按照 Behave 文档中的指导在我们的 Django 项目上加入 BDD。今天就来分享下过程中解决的坑和一些心得体会。

坑1 - test db 的初始数据准备

如果你项目中的数据库初始数据一直维护得好,或者你们已经在用 Django 本身提供的测试机制在跑测试了,那你应该不会踩到这个坑。不然,跑测试时动态创建的 test db 中空空如也,代码中的大部分 view 应该都会抛出各种的异常来。

坑2 - 捕获 mechanize 抛出的异常

这个坑和上一个紧密关联。由于使用 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

心得1 - WSGI intercept

和驱动 selenium 或者 splinter 不一样的是,这个方法并不需要真正运行起 server 来(或者需要 django-live-server),而是利用 WSGI intercept 把 mechanize 产生的请求直接短路给 WSGI handler。在 view layer 层面做测试,这样就够了。由于避免了运行一个 browser 进程,以及其加载静态资源和运行 JS 代码的 overhead,跑一遍测试的速度应该是大大加快了的。

心得2 - 为快速跑测试的目的相应优化 PostgreSQL

在 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

你可能感兴趣的:(django,python,mechanize,bdd,behave)