Web観点のテストなので、twill か selenium が使えるはず。 JQueryが絡むので、twillだとちょっと荷が重いかな。seleniumを使うことにする。
selenium の構造はこんな感じ。テストコードから Selenium Server を経由してWebブラウザを操作したり Assert する。
http://seleniumhq.org/download/ から Selenium Server と Internet Explorer Driver Server を入手して、jarファイルをダブルクリックして実行しておく。
> "C:\Program Files\BitNami\python\Scripts\easy_install.exe" selenium Searching for selenium Reading http://pypi.python.org/simple/selenium/ Reading http://code.google.com/p/selenium/ Reading http://www.openqa.org/ Reading http://seleniumhq.org/ Best match: selenium 2.28.0 Downloading http://pypi.python.org/packages/source/s/selenium/selenium-2.28.0.tar.gz#md5=fd253a2ea94fe14cc5f3e8328cda7a53 Processing selenium-2.28.0.tar.gz Running selenium-2.28.0\setup.py -q bdist_egg --dist-dir c:\users\matobaa\appdata\local\temp\easy_install-lzspr6\selenium-2.28.0\egg-dist-tmp-gmwns0 C:\PROGRA~1\BitNami\python\lib\distutils\dist.py:267: UserWarning: Unknown distribution option: 'src_root' warnings.warn(msg) warning: no files found matching 'docs\api\py\index.rst' Adding selenium 2.28.0 to easy-install.pth file Installed c:\progra~1\bitnami\python\lib\site-packages\selenium-2.28.0-py2.7.egg Processing dependencies for selenium Finished processing dependencies for selenium >
PyDev Package Explorer で QueryStatusHelperPlugin を選択した状態から、Ctrl-N で、Python Module を作る。uiassist.testsパッケージに、Templateは Unittestを選択して、checkboxtest という名前でモジュールを作る。
で、これにソースをがりがり書いていく。こんな感じ:
from selenium import selenium
import time
import unittest
class Test(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8080/1.0/")
self.selenium.start()
def test_double_click_field_from_uri(self):
sel = self.selenium
sel.open("query?status=!closed")
sel.double_click("label_0_status")
self.failUnless(not sel.is_checked("_0_status_accepted"))
self.failUnless(not sel.is_checked("_0_status_assigned"))
self.failUnless(sel.is_checked("_0_status_closed"))
self.failUnless(not sel.is_checked("_0_status_new"))
self.failUnless(not sel.is_checked("_0_status_reopened"))
def test_double_click_field_added_by_adder(self):
sel = self.selenium
sel.open("query?status=!closed")
time.sleep(2)*1
sel.select("add_filter_0", "Vote")
sel.double_click("label_0_vote")
self.failUnless(sel.is_checked("0_vote_a"))
self.failUnless(sel.is_checked("0_vote_b"))
self.failUnless(sel.is_checked("0_vote_c"))
self.failUnless(sel.is_checked("0_vote_d"))
# regression
sel.double_click("label_0_status")
self.failUnless(not sel.is_checked("_0_status_accepted"))
self.failUnless(not sel.is_checked("_0_status_assigned"))
self.failUnless(sel.is_checked("_0_status_closed"))
self.failUnless(not sel.is_checked("_0_status_new"))
self.failUnless(not sel.is_checked("_0_status_reopened"))
def test_double_click_field_added_by_adder_repeatly(self):
sel = self.selenium
sel.open("query?status=!closed")
time.sleep(2)
sel.select("add_filter_0", "Vote")
sel.double_click("label_0_vote")
sel.uncheck("0_vote_c")
sel.double_click("label_0_vote")
self.failUnless(not sel.is_checked("0_vote_a"))
self.failUnless(not sel.is_checked("0_vote_b"))
self.failUnless(sel.is_checked("0_vote_c"))
self.failUnless(not sel.is_checked("0_vote_d"))
def test_double_click_on_checkbox(self):
sel = self.selenium
sel.open("query?status=!closed")
sel.double_click("_0_status_accepted")
self.failUnless(sel.is_checked("_0_status_accepted"))
self.failUnless(not sel.is_checked("_0_status_assigned"))
self.failUnless(not sel.is_checked("_0_status_closed"))
self.failUnless(not sel.is_checked("_0_status_new"))
self.failUnless(not sel.is_checked("_0_status_reopened"))
def test_double_click_on_checkbox_label(self):
sel = self.selenium
sel.open("query?status=!closed")
sel.double_click("//label[@for='_0_status_accepted']")
self.failUnless(sel.is_checked("_0_status_accepted"))
self.failUnless(not sel.is_checked("_0_status_assigned"))
self.failUnless(not sel.is_checked("_0_status_closed"))
self.failUnless(not sel.is_checked("_0_status_new"))
self.failUnless(not sel.is_checked("_0_status_reopened"))
def test_double_click_on_checkbox_label_added_by_adder(self):
sel = self.selenium
sel.open("query?status=!closed")
time.sleep(2)
sel.select("add_filter_0", "Vote")
sel.double_click("//label[@for='0_vote_a']")
sel.double_click("//label[@for='0_vote_c']")
self.failUnless(not sel.is_checked("0_vote_a"))
self.failUnless(not sel.is_checked("0_vote_b"))
self.failUnless(sel.is_checked("0_vote_c"))
self.failUnless(not sel.is_checked("0_vote_d"))
def tearDown(self):
self.selenium.stop()
self.assertEqual([], self.verificationErrors)
trac.iniはこんな感じ:
[ticket-custom] vote = radio vote.options = a|b|c|dcheckboxtest.py を右クリックして、Run as - python unit test で実行してやって、グリーンを確認する。OK。
*1 このコード動作させるのにすごく苦労した。time.sleep(2)が重要。
気になってたことはクリアしたので、いよいよtrac-Hacks.orgで公開しよう。