Killer Web Development Walkthrough Part 4

Section 4 Structure, Design and Tests

Marco introduced how to develop the structure of an example application called tukker.
Firstly is to come up with the design of the application and write down what users will do on this page. i think this is a very practical process at the web app initial development stage and subsequently as well.
Things to do at this stage:
1. list down website requirements – what can the users do on the page?
2. write those user stories (with Agile software development)
3. basically just write down every function that you think the users would need on sticky note, then elaborate on what can the users do with those functions.

Then he introduced a very useful tool to design the web app. it is called “Pencil“, which is a Firefox add-on fro GUI prototyping. it is an easy drag-and-drop web design tool. you can design all your pages and functions here. Quite cool huh, i shall try it next time.

After you are satisfied with your web app design, it is time to test the Tukker App. I shall call mine the Z-App or zapp.
Marco introduced an approach called Test-driven development (TDD). Basically it means you have to fail before you succeed and the importance of simulation.

Writing the first test!

$ cd /your/web2py/folder # cd /home/www-data/web2py
$ ./web2py.py -S tukker # zapp instead of tukker
$ cd applications/tukker/
$ gedit .hgignore

Add the following to the .hgignore, save and close gedit:

syntax: glob
cache/**
databases/**
errors/**
sessions/**

*.pyc

Then initialize Mercurial repository again (good practice!)

$ hg init
$ hg add .
$ hg commit -m"Initial commit"

Push the repository to BitBucket
First, go to the website and create a new repository called your_app (zapp)
Then at the terminal,

$ hg push https://your_username@bitbucket.org/your_username/tukker # hg push https://yzoe@bitbucket.org/yzoe/zapp
...
$ Password: [your password]

Setup testing environment – Selenium, which allows Firefox to behave like a real user.

$ cd /your/web2py/folder/applications/tukker # cd /home/www-data/web2py/applications/zapp
$ mkdir fts
$ cd fts
$ mkdir lib
$ cd lib
$ curl -O http://pypi.python.org/packages/source/s/selenium/selenium-2.15.0.tar.gz  #download will start
$ tar zxf selenium-2.15.0.tar.gz
$ rm selenium-2.15.0.tar.gz
$ mv selenium-2.15.0 selenium

Not too sure if the directory is correct because i get an error later on.
Next we need to create 2 files:
1. __init__.py in fts directory

$ cd /home/www-data/web2py/applications/zapp/fts
$ gedit __init__.py

leave it blank, save and close.

2. functional_tests.py in my zapp application base directory

$ cd /home/www-data/web2py/applications/zapp
$ gedit functional_tests.py

copy and type in the following:

#!/usr/bin/env python
try: import unittest2 as unittest #for Python <= 2.6
except: import unittest
import sys, urllib2
sys.path.append('./fts/lib')
from selenium import webdriver
import subprocess
import sys
import os.path

ROOT = ‘http://localhost:8001&#8217;

class FunctionalTest(unittest.TestCase):

@classmethod
def setUpClass(self):
self.web2py = start_web2py_server()
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(1)

@classmethod
def tearDownClass(self):
self.browser.close()
self.web2py.kill()

def get_response_code(self, url):
“””Returns the response code of the given url

url     the url to check for
return  the response code of the given url
“””
handler = urllib2.urlopen(url)
return handler.getcode()

def start_web2py_server():
#noreload ensures single process
print os.path.curdir
return subprocess.Popen([
‘python’, ‘../../web2py.py’, ‘runserver’, ‘-a “passwd”‘, ‘-p 8001’
])

def run_functional_tests(pattern=None):
print ‘running tests’
if pattern is None:
tests = unittest.defaultTestLoader.discover(‘fts’)
else:
pattern_with_globs = ‘*%s*’ % (pattern,)
tests = unittest.defaultTestLoader.discover(‘fts’, pattern=pattern_with_globs)

runner = unittest.TextTestRunner()
runner.run(tests)

if __name__ == ‘__main__’:
if len(sys.argv) == 1:
run_functional_tests()
else:
run_functional_tests(pattern=sys.argv[1])

Then i created a new file in fts directory

$ cd fts
$ gedit test_static_pages.py

Fill in the following content:

from functional_tests import FunctionalTest, ROOT
class TestHomePage (FunctionalTest):
def test_can_view_home_page(self):

# John opens his browser and goes to the home-page of the tukker app
self.browser.get(ROOT + ‘/tukker/’)

# He’s looking at the homepage and sees the Heading “Messages With 300 Chars”
body = self.browser.find_element_by_tag_name(‘body’)
self.assertIn(‘Messages With 300 Chars’, body.text)

I save and close it.

Now, for the test:

$ python functional_tests.py

and here i got an error:

Traceback (most recent call last):
File "functional_tests.py", line 6, in <module>
from selenium import webdriver
Import Error: No module named selenium

My selenium is in /home/www-data/web2py/applications/zapp/fts/lib. After examining the file, i found out that webdriver is in another selenium folder in that selenium folder.
so i changed this:

sys.path.append('./fts/lib')
from selenium import webdriver

into this:
sys.path.append('./fts/lib/selenium/py')
from selenium import webdriver

And it started running tests. But there are some other errors… well, we don’t have Firefox on Raspberry Pi my dear! The only thing we have is Iceweasel! and selenium doesn’t support that?

sigh. Progress halted.

4 comments

  1. I also ran into this problem using the subject code…

    I was able to fix the selenium error by copying a complete version of selenium into the fts/lib file…

    Hope this helps..

Leave a comment