Django是一個(gè)很棒的Web框架,非常成熟搔课,并且很簡潔胰柑。最大的好處是,使用上很有趣爬泥。為了讓它更方便使用柬讨,lettuce已經(jīng)內(nèi)置支持它。
讓我們開始
1. 安裝Lettuce Django應(yīng)用
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
# ... other apps here ...
'my_app',
'foobar',
'another_app',
'lettuce.django', # this guy will do the job :)
)
假設(shè)我們想編寫my_app Django應(yīng)用的測試袍啡,請參考上面的配置踩官。
2. 創(chuàng)建feature目錄
Lettuce會去進(jìn)入每一個(gè)已安裝的app里找一個(gè)features目錄:
/home/user/projects/djangoproject
| settings.py
| manage.py
| urls.py
| my_app
| features
- index.feature
- index.py
| foobar
| features
- carrots.feature
- foobar-steps.py
| another_app
| features
- first.feature
- second.feature
- many_steps.py
3. 編寫你的第一個(gè)feature
@index.feature:
Feature: Rocking with lettuce and django
Scenario: Simple Hello World
Given I access the url "/"
Then I see the header "Hello World"
Scenario: Hello + capitalized name
Given I access the url "/some-name"
Then I see the header "Hello Some Name"
@index-steps.py:
from lettuce import *
from lxml import html
from django.test.client import Client
from nose.tools import assert_equals
@before.all
def set_browser():
world.browser = Client()
@step(r'I access the url "(.*)"')
def access_url(step, url):
response = world.browser.get(url)
world.dom = html.fromstring(response.content)
@step(r'I see the header "(.*)"')
def see_header(step, text):
header = world.dom.cssselect('h1')[0]
assert header.text == text
4. 運(yùn)行這個(gè)測試
一旦你安裝lettuce.django這個(gè)應(yīng)用,命令harvest就可用:
user@machine:~projects/djangoproject $ python manage.py harvest path/to/my-test.feature
啟動Django服務(wù)前葬馋,harvest命令執(zhí)行django.test.utils.setup_test_environment功能卖鲤。通常肾扰,調(diào)用這個(gè)功能會使用locmen內(nèi)存中郵箱去配置Django畴嘶。然而,Lettuce使用自定義的Django郵箱去接收Lettuce測試腳本發(fā)送的郵件集晚。細(xì)節(jié)窗悯,請參考“檢查郵件”。
5. 識別feature文件
harvest命令允許使用文件路徑偷拔,這樣可以只執(zhí)行你想執(zhí)行的具體的features蒋院。
例子:
user@machine:~projects/djangoproject $ python manage.py harvest path/to/my-test.feature
6. 獲取實(shí)際案例代碼
為了確保lettuce很好的集成Django亏钩,提供了一系列的集成測試,有很多實(shí)際的Lettuce+Django項(xiàng)目欺旧。
你可以在lettuce Git倉庫的alfaces目錄下獲取代碼姑丑。
技術(shù)細(xì)節(jié)
如果你想使用web瀏覽器編寫驗(yàn)收測試,你可以使用的工具有:twill, selenium, webdriver和windwill辞友。
red-tape-less內(nèi)置服務(wù)
Lettuce會智能地后臺運(yùn)行一個(gè)內(nèi)置Gjango HTTP服務(wù)的實(shí)例栅哀。首先它會嘗試將HTTP服務(wù)綁定在localhost:8000。但是如果這個(gè)端口被占用称龙,它繼續(xù)嘗試運(yùn)行在其他端口:8001留拾,8002等等,直到嘗試到最大的端口數(shù)65535鲫尊。
注
你可以使用任何你想用的端口號替換默認(rèn)端口“8000”痴柔。
為此,可以參考下面的“在8000以外的其他端口上運(yùn)行HTTP服務(wù)器”疫向。
如此你就可以使用上面列出的基于瀏覽器的工具來訪問Django咳蔚。
警告
當(dāng)運(yùn)行HTTP服務(wù),lettuce設(shè)置環(huán)境變量SERVER_NAME和SERVER_PORT鸿捧。它會導(dǎo)致一個(gè)GAE問題屹篓。如果它帶來了任何錯(cuò)誤,注意這個(gè)問題匙奴。
找出Django地址
因?yàn)镈jango HTTP服務(wù)能夠使用8000到65535范圍里面的任意端口運(yùn)行堆巧,就比較難找出你項(xiàng)目確切的地址,對吧泼菌?
錯(cuò)谍肤!
你可以使用django_url功能定義到你的步驟中。
from lettuce import step, world
from lettuce.django import django_url
@step(r'Given I navigate to "(.*)"')
def navigate_to_url(step, url):
full_url = django_url(url)
world.browser.get(full_url)
django_url是如何工作的哗伯?
它附加了一個(gè)Django內(nèi)部地址在HTTP服務(wù)地址上荒揣。
換句話說,如果lettuce綁定HTTP服務(wù)到localhost:9090焊刹,然后你使用“/admin/login”調(diào)用django_url:
from lettuce.django import django_url
django_url("/admin/login")
它會返回:
"http://localhost:9090/admin/login"
在django項(xiàng)目中系任,terrian也可用
你可能知道terrian.py怎么工作,它同樣可以在Django項(xiàng)目中使用虐块。
你可以在Django項(xiàng)目根路徑下的terrian.py文件俩滥,設(shè)置環(huán)境和其他的配置。
以這個(gè)文檔的第一個(gè)例子為例贺奠,你的Django項(xiàng)目目錄結(jié)構(gòu)如下:
/home/user/projects/djangoproject
| settings.py
| manage.py
| urls.py
| terrain.py
| my_app
| features
- index.feature
- index.py
| foobar
| features
- carrots.feature
- foobar-steps.py
| another_app
| features
- first.feature
- second.feature
- many_steps.py
注意項(xiàng)目根路徑下的terrain.py文件霜旧,你可以使用它填充和組織你的features和steps。
檢查郵件
當(dāng)你運(yùn)行l(wèi)ettuce下的Django項(xiàng)目儡率,郵件將不通過網(wǎng)絡(luò)傳輸發(fā)送挂据。而是被添加到對象lettuce.django.mail.queue以清。
例子:
from lettuce import step
from lettuce.django import mail
from nose.tools import assert_equals
@step(u'an email is sent to "([^"]*?)" with subject "([^"]*)"')
def email_sent(step, to, subject):
message = mail.queue.get(True, timeout=5)
assert_equals(message.subject, subject)
assert_equals(message.recipients(), [to])
不使用HTTP服務(wù)執(zhí)行
有時(shí)您可能不想后臺運(yùn)行Django內(nèi)置HTTP服務(wù)器,在這些情況下崎逃,你需要做的就是使用--no-server或-S選項(xiàng)運(yùn)行harvest命令掷倔。
python manage.py harvest --no-server
python manage.py harvest -S
在8000以外的其他端口上運(yùn)行HTTP服務(wù)
如果Lettuce在端口8000上運(yùn)行遇到問題,就可以改變這個(gè)端口个绍。
在運(yùn)行服務(wù)之前今魔,Lettuce將嘗試讀取LETTUCE_SERVER_PORT,該設(shè)置必須為整數(shù)障贸。
例子:
LETTUCE_SERVER_PORT = 7000
假如7000是你的默認(rèn)開發(fā)端口错森,這將非常有用。
使用settings.DEBUG = True運(yùn)行HTTP服務(wù)
為了使用最接近生產(chǎn)的配置運(yùn)行測試篮洁,Lettuce設(shè)置settings.DEBUG=False涩维。
但是,出于調(diào)試目的袁波,在Django中如果不使用追蹤瓦阐,則可能會遇到誤導(dǎo)性的HTTP 500錯(cuò)誤。 對于這些場景篷牌,Lettuce提供--debug-mode或-d選項(xiàng)睡蟋。
python manage.py harvest --debug-mode
python manage.py harvest -d
使用測試數(shù)據(jù)庫
如果你想使用默認(rèn)測試數(shù)據(jù)庫,而不是在線數(shù)據(jù)庫枷颊。在你的測試服務(wù)中戳杀,你可以使用-T標(biāo)簽,或者在setting.py中設(shè)置下面的配置變量夭苗。
LETTUCE_USE_TEST_DATABASE = True
只運(yùn)行特定場景
你也可以通過命令指定你想運(yùn)行的場景信卡,為此,使用--scenarios或-s選項(xiàng)運(yùn)行题造,后面跟上用逗號分隔的場景號傍菇。
例如,假設(shè)你要運(yùn)行場景4界赔、7丢习、8和10:
python manage.py harvest --scenarios=4,7,8,10
python manage.py harvest -s 4,7,8,10v
運(yùn)行或不運(yùn)行,這是個(gè)問題淮悼!
在開發(fā)工作流程中咐低,你可能會遇到兩種情況:
從某些特定應(yīng)用運(yùn)行測試
Lettuce會以逗號分隔的應(yīng)用名稱列表來運(yùn)行測試。
例如敛惊,下面的命令將僅在應(yīng)用myapp和foobar中運(yùn)行測試:
python manage.py harvest --apps=myapp,foobar
# or
python manage.py harvest --a myapp,foobar
你也可以在settings.py中指定渊鞋,這樣就不必一直輸入相同的命令行參數(shù):
LETTUCE_APPS = (
'myapp',
'foobar',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
'my_app',
'foobar',
'another_app',
'lettuce.django',
)
運(yùn)行除了某些應(yīng)用除外的所有測試
Lettuce運(yùn)行使用逗號分隔的應(yīng)用名稱且沒有標(biāo)記NOT的列表绰更。
例如瞧挤,下面的命令將運(yùn)行所有測試锡宋,但不包含another_app和foobar中的測試:
python manage.py harvest --avoid-apps=another_app,foobar
你也可以在settings.py中指定,這樣就不必一直輸入相同的命令行參數(shù):
LETTUCE_AVOID_APPS = (
'another_app',
'foobar',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
'my_app',
'foobar',
'another_app',
'lettuce.django',
)
上一篇:Lettuce:使用nose作斷言
下一篇:結(jié)束特恬,以上所有篇章暫時(shí)夠用