programming


Since a few days I’ve been using vim in full screen mode, that is, the only thing on my screen is my editor. No panel, no task bar, no systray. It may be subjective, but I have the impression that without all the distractions, bells and whistles on my desktop, it is easier for me to concentrate on the task at hand. Compare

to

With metacity and GNOME, you can set for example Shift-Alt-Enter to toggle full screen mode. This is similar to Alt-Enter for toggling maximized mode, so it’s easy to remember:

Google Code Search was launched. Let’s listen to a soliloquy:

This is buggy, but I’ll fix it later. It’s also racy, but who cares, I don’t understand why, anyway. Let’s just hope that this will never happen. Or ?!?!

You can also search for buffer overflows.

I read an interesting article about Haskell today, so I tried to learn a little Haskell. It’s a very interesting language. I installed hugs and started. On haskell.org you can read that Haskell means no core dumps. I got a core dump relatively fast. Here’s how:

  • Install hugs
  • Create an empty file foo.hs
  • start hugs
markus@katerina2:~/src/haskell$ touch foo.hs
markus@katerina2:~/src/haskell$ hugs
__   __ __  __  ____   ___      _________________________________________
||   || ||  || ||  || ||__      Hugs 98: Based on the Haskell 98 standard
||___|| ||__|| ||__||  __||     Copyright (c) 1994-2005
||---||         ___||           World Wide Web: http://haskell.org/hugs
||   ||                         Report bugs to: hugs-bugs@haskell.org
||   || Version: 20050308       _________________________________________

Haskell 98 mode: Restart with command line option -98 to enable extensions

Type :? for help
Hugs.Base> :load foo.hs
Main> :edit

:edit calls the editor with the last loaded file – here foo.hs. Put the following in the file:

times 1 x = x
times n x = times (n-1) x ++ x

This defines a function times which takes two arguments: one from which 1 can be subtracted and another one that can be concatenated with itself. Haskell infers this from how you use the parameters in the function. times concatenates its second argument n times with itself.

Main> times 2 [3]
[3,3]
Main> times 2 [42]
[42,42]

Now in order to produce the seg fault (or core dump) in hugs, you have to call times with a nonpositive number of times:

Main> times 0 [42]
Segmentation fault

Nothing earth-shattering, but I find it interesting to have found a possibility to crash Haskell in half an hour after reading about its core dump immunity.

This is meant humoristically, not as a rant. Take it with a grain of salt :)

Unit testing web applications is relatively hard, because you usually have quite a lot of layers: starting from the database, over PHP/Python/Ruby, the web server, the browser and HTML up to Javascript. Traditional unit testing hooks into the code at the PHP/Python/Ruby level. It does quite a good job at testing this layer of web applications. There also exist testing frameworks that allow you to unit test Javascript. Alas, none of these solutions test the whole experience that the end user has. This is where functional unit testing comes into play.

Selenium, a framework that supports functional unit testing of web applications, simulates a user clicking links, filling out forms and submitting them. It can determine whether a blog post appeared in a list, after you used a form to submit it. It can test whether your AJAX screenname availability check works. It supports cookies. And all that because it runs directly in your browser. The Javascript that runs in your browser receives commands like “click the submit button” or “wait for the spinner to appear” or “make sure this error message didn’t appear on the page”.

Selenium comes in several flavours: one is Selenium Core, which runs directly and only in the browser. As a language for writing tests it supports only selenese, which can express only a simple sequence of actions and tests. This is of course too little for most web applications. But there’s a flavour of Selenium that can be integrated with traditional unit testing frameworks like SimpleTest (for PHP) and PyUnit: Selenium Remote Control.

Selenium Remote Control is essentially a server written in Java with two functions: it acts as a proxy server for the browser and takes commands via HTTP that will be executed in the browser. The proxy server is needed because browsers rightfully don’t allow Javascript from one site to run on another site. Read Selenium Remote Control: The Same Origin Policy if you’d like to know more.

Selenium Remote Control comes with client drivers for Python, Ruby, Perl and Java – a PHP client driver has not made it in the official release yet.

To start using Selenium Remote Control for doing functional tests of your web application, download the current release (http://openqa.org/selenium-rc/download.action), unpack it and start the server:

wget selenium-remote-control-0.8.1.zip
unzip selenium-remote-control-0.8.1.zip
cd selenium-remote-control-0.8.1/server
java -jar selenium-server.jar

This starts the two servers: the proxy server for the browser and the server that takes the commands. Then write a unit test case, using one of the client drivers provided in the archive. I’ll use Python here:

mkdir functional-tests
cd functional-tests
cp path/to/selenium-remote-control-0.8.1/python/selenium.py .

and put this in a file test-login.py

import unittest

class LoginTest(unittest.TestCase):
seleniumHost = 'localhost'
seleniumPort = '4444'
browserStartCommand = '*firefox /usr/lib/firefox/firefox-bin'
browserURL = 'http://community'

def setUp(self):
self.selenium = selenium('localhost', '4444', '*firefox /usr/lib/firefox/firefox-bin', 'http://www.example.com')
self.selenium.start()

def tearDown(self):
self.selenium.stop()

def testLogin(self):
self.selenium.open("/login")
self.selenium.type("name=username", "john")
self.selenium.type("name=password", "johnspassword")
self.selenium.click("id=Submit")
self.selenium.wait_for_page_to_load(15000)
self.failUnless(self.selenium.is_text_present("Login successful"))

if __name__ == '__main__':
unittest.main()

Then run

python ./test-login.py

and watch selenium opening a Firefox instance for you, loading the login page, typing username and password, submitting the form and finally checking for the message about successful login. After that Firefox is closed and PyUnit reports that the test ran successfully.

Links

« Previous Page