<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4142358</id><updated>2012-02-16T09:31:55.443Z</updated><category term='hibernate'/><category term='oracle'/><title type='text'>Goul In Space</title><subtitle type='html'>My day-day technical notes and chat.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.goulbourn.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default?start-index=26&amp;max-results=25'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>83</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4142358.post-1589993499553592021</id><published>2011-05-31T17:31:00.000Z</published><updated>2011-05-31T17:31:10.668Z</updated><title type='text'>Alfred App + RTM</title><content type='html'>A month or so ago I raved about &lt;a href="http://www.alfredapp.com/"&gt;Alfred App&lt;/a&gt;&amp;nbsp;and how impressed I was with it. I've also been a long time user of &lt;a href="http://www.rememberthemilk.com/"&gt;Remember The Milk&lt;/a&gt;&amp;nbsp;to keep lists of the things I should be doing.&lt;br /&gt;&lt;br /&gt;The good folks over at Ruk have shown how to bring these &lt;a href="http://ruk.ca/content/alfred-remember-milk"&gt;two worlds together&lt;/a&gt; using a Ruby command line script. This now means entering a TODO/reminder can be as simple as :&lt;br /&gt;&lt;br /&gt;&lt;b&gt;alt-space&lt;/b&gt;&lt;br /&gt;&lt;b&gt;r Mail Jim about bulk purchase rates of hamsters ^Wed 9am&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;This really helps my flow through the day - things that would have become interruptions can be quickly added to the TODO list without any real context switch.&lt;br /&gt;&lt;br /&gt;If you are a Mac user you really owe it to yourself to go try AlfredApp out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-1589993499553592021?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/1589993499553592021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=1589993499553592021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1589993499553592021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1589993499553592021'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2011/05/alfred-app-rtm.html' title='Alfred App + RTM'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-8178588949510327513</id><published>2011-04-16T11:57:00.000Z</published><updated>2011-04-16T11:57:44.989Z</updated><title type='text'>IPad2 Xoom Initial development with PhoneGap</title><content type='html'>After a year of envy of my better half having an original iPad, I was lucky enough to pick one up about ten days ago. In this time its already become my go to device for a bunch of scenarios and I'm delighted with it.&lt;br /&gt;&lt;br /&gt;With my professional hat on, we have been asked to take a look at building some tablet based applications. Much as I love my IOS based device, Apple keep a &lt;b&gt;very&lt;/b&gt; tight reign on whats happens on that platform so I wanted to show the client alternatives.&lt;br /&gt;&lt;br /&gt;To demonstrate the alternatives I went shopping for an Android device - initially planning to buy an Android 2.2 based table, the Vega Tablet PC - 512MB.&lt;br /&gt;However when I got to the store, I spotted that they has both the Motorola Xoom and the ACER Iconia Tab A500 Android 3.0 (Honeycomb) tablets in stock. Android 3 is the first version of the OS designed to run on tablets.&amp;nbsp;So I got upsold and bought a Xoom as an alternate platform for the tests.&lt;br /&gt;&lt;br /&gt;Initial feelings about the Xoom are very positive.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Hardware&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Noticeably heavier/thicker than iPad 2.&lt;/li&gt;&lt;li&gt;Screen is great, touch response etc excellent.&lt;/li&gt;&lt;li&gt;Sound through speakers is awful (although better when in the "stand mode" of portfolio case).&lt;/li&gt;&lt;li&gt;Camera - front and rear clearly better than iPad2 (although I'm still dubious about cameras for anything other that video conferencing on this type of device).&lt;/li&gt;&lt;li&gt;Charging - you can't charge over USB it has a power brick - unforgivable - (am considering returning it for the ACER if that is USB chargeable).&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Software&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The setup is nice, integration to google applications etc is all very quick.&lt;/li&gt;&lt;li&gt;Browser is quick (no difference side by side with iPad2 on BBC, Guardian etc).&lt;/li&gt;&lt;li&gt;Flash video - works fine.&lt;/li&gt;&lt;li&gt;I've struggled a little with general navigation etc. I don't think its bad, its just different to what I know from Apple side (interesting that colleagues with Android phones also notice its different).&lt;/li&gt;&lt;li&gt;Bult in apps for mail/calendar etc etc are good - but lack polish.&lt;/li&gt;&lt;li&gt;I've crashed the OS 3 or 4 times pressing navigation etc while apps are running.&lt;/li&gt;&lt;li&gt;Notifications - as people have noted, Android 3 nails this - clearly better than IOS.&lt;/li&gt;&lt;li&gt;App Store is short of tablet specific format apps right now (and Amazon won't let folks purchase in UK on that store yet) - this is clearly going to change fast.&lt;/li&gt;&lt;li&gt;Now the important stuff - Angry Birds Rio - feels identical to iPad2 version.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;A quick note, I bought the Motorola Portfolio case. IMHO it has a huge design flaw, you can't charge the device with the case/screen protected.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;General&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;These are the first of this generation of Android devices, we are going to see dozens of these within a year.For me the Apple user experience is still the benchmark, but its close. This market is going to be fun over the next few years, I hope this pushes both vendors forward - we should all gain.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Development&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Initial application development proof of concept had been built using &lt;a href="http://www.phonegap.com/"&gt;PhoneGap&lt;/a&gt; and &lt;a href="http://www.sencha.com/products/touch/"&gt;Sencha Touch&lt;/a&gt;. I'd had this running as an IOS bundle for a few days, it took 10 minutes to migrate same code to native Android App. Application has worked with almost identical performance on the Xoom.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-8178588949510327513?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/8178588949510327513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=8178588949510327513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/8178588949510327513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/8178588949510327513'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2011/04/ipad2-xoom-initial-development-with.html' title='IPad2 Xoom Initial development with PhoneGap'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-875335771145738897</id><published>2011-04-05T12:14:00.000Z</published><updated>2011-04-05T12:14:25.016Z</updated><title type='text'>Alfred App</title><content type='html'>I've been a long time user (3+years) of&amp;nbsp;&lt;a href="http://www.blacktree.com/"&gt;Quick Silver&lt;/a&gt;&amp;nbsp;as a task launcher and general tool for keeping hands on keyboard rather than a mouse.&lt;br /&gt;&lt;br /&gt;Around 6 weeks ago I decided to trial&amp;nbsp;&lt;a href="http://www.alfredapp.com/"&gt;Alfred&lt;/a&gt;, Quick Silver got uninstalled about an hour later. Alfred lets you launch applications, web search, find local docs, open recent files etc etc with amazing ease. If you own a Mac, go try the free version either from&amp;nbsp;&lt;a href="http://www.alfredapp.com/"&gt;http://www.alfredapp.com/&lt;/a&gt; or the Apple Store. Once you are hooked go spend a few pounds to get the PowerPack and support an independent developer who is doing a great job.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-875335771145738897?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/875335771145738897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=875335771145738897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/875335771145738897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/875335771145738897'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2011/04/alfred-app.html' title='Alfred App'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2291933695004559706</id><published>2011-04-04T13:46:00.000Z</published><updated>2011-04-04T13:46:12.083Z</updated><title type='text'>ITerm2 - Growl Notification</title><content type='html'>As a heavy user of the Mac command line toolset, I spend a lot of time logged into remote machines. I've been an avid &lt;a href="http://iterm.sourceforge.net/"&gt;ITerm&lt;/a&gt;&amp;nbsp;user for a long time, it allows me to have radically different looking consoles for QA/EA/Production machines.&lt;br /&gt;&lt;br /&gt;I was reading&amp;nbsp;&amp;nbsp;&lt;a href="http://aming-blog.blogspot.com/2011/01/growl-notification-from-iterm-2.html"&gt;http://aming-blog.blogspot.com/2011/01/growl-notification-from-iterm-2.html&lt;/a&gt;&amp;nbsp;on changes in &lt;a href="http://code.google.com/p/iterm2/downloads/list"&gt;ITerm2&lt;/a&gt; to allow console commands to use Growl Notifications (including from remote machine). Typical use case would be a large data import/build etc - followed by growl telling you he jobs complete.&lt;br /&gt;&lt;br /&gt;One quick spot - the blog above talks about the Growl settings being in Iterm2/Preferences/Advanced - on the nightly I am using they are in Iterm2/Preferences/General/Services.&lt;br /&gt;&lt;br /&gt;Add the following to&lt;b&gt; .bash_profile&lt;/b&gt; :&lt;br /&gt;&lt;br /&gt;&lt;b&gt;growl() { echo -e $'\e]9;'${1}'\007' ; return ; }&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You can then perform actions like &amp;nbsp;:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ant bigTarget; growl "Big Target Complete"&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This has the advantage over using something like the &lt;b&gt;say &lt;/b&gt;command in that it will update your local growl even if running on a remote box.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2291933695004559706?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2291933695004559706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2291933695004559706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2291933695004559706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2291933695004559706'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2011/04/iterm2-growl-notification.html' title='ITerm2 - Growl Notification'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-7228494651514988453</id><published>2011-04-03T20:27:00.001Z</published><updated>2011-04-03T20:31:46.568Z</updated><title type='text'>Static Hosting Using S3/AWS</title><content type='html'>We have been gradually moving large amount of our managed and internal services to AWS. EC2/RDS make for a very compelling model. As a software/consultancy house using these services let us concentrate on our core competencies. The benefit of no longer sitting waiting for hardware to fail and ruin someones weekend is hard to beat.&lt;br /&gt;&lt;br /&gt;For those wanting to dip a toe in the water, Amazon now support S3 as a static website. i.e. you can link an S3 "bucket" to being a static website. Announcement blog post is&amp;nbsp;&lt;a href="http://aws.typepad.com/aws/2011/02/host-your-static-website-on-amazon-s3.html"&gt;here&lt;/a&gt;&amp;nbsp;- it boils down to uploading the content to S3 and then pointing a CNAME at it.&lt;br /&gt;&lt;br /&gt;You can then simply use a tool like &amp;nbsp;&lt;a href="http://cyberduck.ch/"&gt;Cyberduck&lt;/a&gt;&amp;nbsp;to allow your creatives to upload the content.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-7228494651514988453?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/7228494651514988453/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=7228494651514988453' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7228494651514988453'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7228494651514988453'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2011/04/static-hosting-using-s3aws.html' title='Static Hosting Using S3/AWS'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-689412596901923082</id><published>2009-05-17T16:31:00.005Z</published><updated>2010-09-06T09:49:30.143Z</updated><title type='text'>Page Based Testing With Tools Like Selenium - tips</title><content type='html'>After the grand experiment described below I ported a large number of the smoke tests over, these happily ran on my Mac under both Safari and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Firefox&lt;/span&gt; 3.&lt;br /&gt;&lt;br /&gt;Of course despite my bias for &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OSX&lt;/span&gt;/Linux apparently one or two &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;internet&lt;/span&gt; users still use IE. So we probably need to test on that "other" platform too.&lt;br /&gt;&lt;br /&gt;To do this I setup three &lt;a href="http://www.virtualbox.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;VirtualBox&lt;/span&gt;&lt;/a&gt; instances, running IE6/7/8 respectively. I then modified our base test to take a set of parameters for test server/port/browser. i.e. make our base test setup the driver as follows :&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;selenium = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;DefaultSelenium&lt;/span&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;seleniumClientIP&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;seleniumClientPort&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;seleniumClientBrowser&lt;/span&gt;, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;baseTestURI&lt;/span&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then I created a quick ant script to perform all my smoke test on each combination, wrapped it up in a &lt;a href="https://hudson.dev.java.net/"&gt;Hudson&lt;/a&gt; instance to run it periodically and report any &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;JUnit&lt;/span&gt; failures.&lt;br /&gt;&lt;br /&gt;All sounds &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;rosy&lt;/span&gt; doesn't it?&lt;br /&gt;&lt;br /&gt;Whilst the tests all run fine in Safari and Firefox on any of the hosts/virtual machines. It appeared that we are not so lucky with IE. Bottom line was that without intervention tests running in the IE VMs fail about 15% of the time with "Internet explorer has encountered a problem". This modal dialog eventually leads to timeouts in the tests, and the windows/IE instances don't go away without manual intervention. As previously discussed if the tests are flakey or out of date they become an irrelevent distraction.&lt;br /&gt;&lt;br /&gt;A lot of internet digging this weekend has led to this &lt;a href="http://clearspace.openqa.org/message/52722?tstart=0"&gt;thread&lt;/a&gt;. This has two salient bits of advice :&lt;br /&gt;&lt;br /&gt;a) Even though the IE selenium runs are much slower that those in Safari/Firefox, it can still get into trouble with timing. setting the default selenium speed like this &lt;span style="font-weight: bold;"&gt;selenium.setSpeed("500")&lt;/span&gt; seems to help.&lt;br /&gt;&lt;br /&gt;b) If the above doesn't fix all issues, turn off windows error reporting to stop the instances getting hit with the modal dialog. (The tests will still fail, but the instance is recoverable without manual intervention).&lt;br /&gt;&lt;br /&gt;Since I put these changes in place, we have not had a single IE fail. Time will tell of course but things certainly look positive so far!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-689412596901923082?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/689412596901923082/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=689412596901923082' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/689412596901923082'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/689412596901923082'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/05/page-based-testing-with-tools-like_17.html' title='Page Based Testing With Tools Like Selenium - tips'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-3990182620615725612</id><published>2009-05-13T19:36:00.003Z</published><updated>2009-05-13T19:47:49.305Z</updated><title type='text'>Page Based Testing With Tools Like Selenium</title><content type='html'>For a while I have been doing ad hoc runtime smoke testing of deployments with tools like &lt;a href="http://seleniumhq.org/"&gt;Selenium&lt;/a&gt;. i.e. running a set of simple tests that exercise a series of pre-defined application points. The scripts where typically recorded using the excellent Selenium IDE then replayed through ant/Junit on one or more target browser platforms.&lt;br /&gt;&lt;br /&gt;Not full regression testing but a start - right? Well these tests become a pain to maintain, and unmaintained/unreliable tests are pointless. A typical test would be something like the following :&lt;br /&gt;&lt;br /&gt;a) login to the application&lt;br /&gt;b) pick an object from an info set.&lt;br /&gt;c) pass that object through several workflow steps.&lt;br /&gt;d) complete the workflow.&lt;br /&gt;e) log out.&lt;br /&gt;&lt;br /&gt;The majority of the tests would be around the differences between step c) the options chosen during workflow.&lt;br /&gt;&lt;br /&gt;I tried to take a step back and look at why these became such a pain to maintain. If I had 10 tests scripted as defined above a small change (like how I select a workflow) would effect all 10 test scripts. Multiply this to a hundred or so tests on a project with half a dozen active developers then you quickly have more broken smoke tests than working ones.&lt;br /&gt;&lt;br /&gt;So I took a step back to try to look at a new way of writing these sort of tests so that they become less brittle. The method that seems to be working for me is to produce a more "Page" based approach rather than the test "stream" approach described above.&lt;br /&gt;The concept is pretty simple, write a class that offers public methods for the types of operations that a user can perform through a browser on that page. Ensure that the operation returns another page based object.&lt;br /&gt;&lt;br /&gt;As a simple example, lets look at a typical login page,it contains two fields userId and password. The Page object looks something like this :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public class LoginPage&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;      /** Contains the actual driver we are using. */&lt;br /&gt;  private final Selenium selenium;&lt;br /&gt;&lt;br /&gt;     /**&lt;br /&gt;      * Create the page.&lt;br /&gt;      * @param driver the driver.&lt;br /&gt;      */&lt;br /&gt;      public LoginPage(Selenium selenium)&lt;br /&gt;      {&lt;br /&gt;            this.selenium = selenium;&lt;br /&gt;&lt;br /&gt;             assert (selenium.getTitle().equalsIgnoreCase("My Applications Login Page));&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;      /** A "good" login. i.e. one we know should allow us into the site.&lt;br /&gt;        *&lt;br /&gt;        * @param userName userId.&lt;br /&gt;        * @param password password to log in with.&lt;br /&gt;        * @return HomePage as "logged in".&lt;br /&gt;        */&lt;br /&gt;   public HomePage performLogin(String userName, String password)&lt;br /&gt;       {&lt;br /&gt;&lt;br /&gt;           selenium.type("userName", userName);&lt;br /&gt;           selenium.type("password", password);&lt;br /&gt;&lt;br /&gt;           selenium.click("login");&lt;br /&gt;          selenium.waitForPageToLoad(SeleniumConstants.MAX_PAGE_LOAD_TIMEOUT);&lt;br /&gt;&lt;br /&gt;          return new HomePage(selenium);&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;then a simple HomePage with a search method might look like this :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;public class HomePage&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;     /** Contains the actual driver we are using. */&lt;br /&gt;      private final Selenium selenium;&lt;br /&gt;&lt;br /&gt;     /**&lt;br /&gt;      * Create the page.&lt;br /&gt;   * @param driver the driver.&lt;br /&gt;       */&lt;br /&gt;       public HomePage(Selenium selenium)&lt;br /&gt;   {&lt;br /&gt;       super(selenium);&lt;br /&gt;              this.selenium = selenium;&lt;br /&gt;               assert (selenium.getTitle().equalsIgnoreCase("My Application Home"));&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;     /** Perform a search with the supplied term.&lt;br /&gt;      *&lt;br /&gt;      * @param searchTerm term to look for.&lt;br /&gt;      * @return a search result page.&lt;br /&gt;      */&lt;br /&gt;      public SearchResultPage performSearch(String searchTerm)&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;              selenium.type("searchTerm", searchTerm);&lt;br /&gt;              selenium.click("homeSearchCommand");&lt;br /&gt;               selenium.waitForPageToLoad(SeleniumConstants.MAX_PAGE_LOAD_TIMEOUT);&lt;br /&gt;&lt;br /&gt;               return new SearchResultPage(selenium);&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is implemented using selenium, but the concept is applicable to any of the other tools. Note that the Home constructor contains a simple assertion that checks that the title of the page is "My Applications Home". This is important because if anything with the login fails and I stay on the login page rather than going to the home page my test will automatically terminate.&lt;br /&gt;&lt;br /&gt;The home page again exposes methods like performSearch that again return result pages etc. This form of testing leads to tests that are *really* simple to view/read eg.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    public void testPerformLoginThenSearch()&lt;br /&gt;  {&lt;br /&gt;           // these 3 lines should probably be put into a base/setup method for all tests&lt;br /&gt;           selenium = new DefaultSelenium("localhost", 4444, "*safari", "http://myapplication.com/");&lt;br /&gt;           selenium.open("/myApp/Login");&lt;br /&gt;           selenium.waitForPageToLoad(SeleniumConstants.MAX_PAGE_LOAD_TIMEOUT); &lt;br /&gt;&lt;br /&gt;     HomePage homePage=new HomePage(selenium);&lt;br /&gt;&lt;br /&gt;     homePage.performLogin("goul","notthatdaft!");&lt;br /&gt;  &lt;br /&gt;     assertTrue( selenium.getHtmlSource().contains("Welcome back master how may I help"));&lt;br /&gt;&lt;br /&gt;     SearchResultPage searchResult=homePage.performSearch("banana hammock");&lt;br /&gt;     .&lt;br /&gt;     .&lt;br /&gt;     .&lt;br /&gt;     .  &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Something to note, if you know a test should do something different i.e. return a non-standard return page (like login fail - returning you to login) then create another public method - the page flow is the key thing here i.e. add a method like&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    /** A "bad" login. i.e. one we know should not allow us into the site.&lt;br /&gt;   *&lt;br /&gt;   * @param userName userId.&lt;br /&gt;   * @param password password to log in with.&lt;br /&gt;   * @return LoginPage because we are still not logged in.&lt;br /&gt;   */&lt;br /&gt;  public LoginPage performLoginExpectingFail(String userName, String password)&lt;br /&gt;  {&lt;br /&gt;&lt;br /&gt;           selenium.type("userName", userName);&lt;br /&gt;           selenium.type("password", password);&lt;br /&gt;&lt;br /&gt;           selenium.click("login");&lt;br /&gt;           selenium.waitForPageToLoad(SeleniumConstants.MAX_PAGE_LOAD_TIMEOUT);&lt;br /&gt;&lt;br /&gt;           return new LoginPage(selenium);&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;Going back to the test view, we can easily hide some of the minor complexity to get started and check page content. We can easily add some utility methods to hide that ugly login and the selenium content. Lets also assume that the SearchResultPage adds methods like routeFirstObject that launches the first returned search object into a named workflow.&lt;br /&gt;&lt;br /&gt;Our test now looks like :&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;br /&gt;public void testSearch()&lt;br /&gt;{&lt;br /&gt;     HomePage homePage=login();&lt;br /&gt;     checkPageContains("Welcome back master how may I help");&lt;br /&gt;&lt;br /&gt;     SearchResultPage resultPage=homePage.performSearch("banana hammock");&lt;br /&gt;     checkPageContains("Hammock Object");&lt;br /&gt;&lt;br /&gt;     WorkflowRoutePage workflowRoute=resultPage.routeFirstObject("Author, Review and Translate");&lt;br /&gt;   .&lt;br /&gt;   .&lt;br /&gt;   .&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;This test is now amazingly simple to write, in fact you could probably convince the QA department that they can write the tests if the developers provide the page objects. Any modern IDE is going to give you strongly typed Pages for results of functions, the method names are self explanatory etc.&lt;br /&gt;&lt;br /&gt;So how does this solve my initial problem around brittle tests?&lt;br /&gt;&lt;br /&gt;Well lets say that how the search on the home page is launched changes (new design/ids for field etc etc.) I only have to fix the HomePage object, and fixing that single object in place means that *all* tests that use it should now run cleanly without needing changes.&lt;br /&gt;&lt;br /&gt;I believe this approach gives the following advantages :&lt;br /&gt;&lt;br /&gt;a) Page objects can be "grown" as tests are needed. As functionality is added to the page object, everyone using that object gets the advantage over time. i.e. the effort for new tests actually reduces as the cumulative methods are added to Pages.&lt;br /&gt;&lt;br /&gt;b) The test scripts are very strongly typed, and are simple to understand. The page approach means the tests obviously model the flow through the application.&lt;br /&gt;&lt;br /&gt;c) Tooling like SeleniumIDE can still be used - but take the simple steps and apply them into Page objects.&lt;br /&gt;&lt;br /&gt;d) By making all tests that perform a login do it through the LoginPage object, you only have to change the LoginPage object if the layout/operation of login changes. i.e. fix one page object rather than a all the places calling login in scripts.&lt;br /&gt;&lt;br /&gt;I've moved about 20 of our "smoke tests" over to this approach so far and coupled with hudson am able to run them on a series of browsers. So far so good, I'll blog further if I've been missing some huge pitfall in this approach.&lt;br /&gt;&lt;br /&gt;Turns out this is not an original idea the good folks at &lt;a href="http://code.google.com/p/webdriver/"&gt;WebDriver&lt;/a&gt; have a &lt;a href="http://code.google.com/p/webdriver/wiki/PageObjects"&gt;paper&lt;/a&gt; almost identical to this. Hopefully this means it is an approach that will really work!&lt;br /&gt;&lt;br /&gt;(BTW - WebDriver looks very interesting, the HTMLUnit headless mode is great).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-3990182620615725612?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/3990182620615725612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=3990182620615725612' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/3990182620615725612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/3990182620615725612'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/05/page-based-testing-with-tools-like.html' title='Page Based Testing With Tools Like Selenium'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-1789132859150595185</id><published>2009-02-07T20:12:00.002Z</published><updated>2009-02-07T20:16:31.320Z</updated><title type='text'>Selenium - OSX Safari not opening second window</title><content type='html'>I've been testing a new site with Selenium. Part of this work was on my Mac and in addition to running the tests in Firefox, I wanted to use Safari too. Whenever I launched the test case the first driver window opened, but the content window didn't ever appear. No errors, no fuss, it just didn't happen.&lt;br /&gt;&lt;br /&gt;After walking away from the problem for a while, the penny finally dropped........Safari blocks pop-ups by default! Turning that off instantly solved all my problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-1789132859150595185?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/1789132859150595185/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=1789132859150595185' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1789132859150595185'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1789132859150595185'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/02/selenium-osx-safari-not-opening-second.html' title='Selenium - OSX Safari not opening second window'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2562324583012100132</id><published>2009-01-28T14:33:00.002Z</published><updated>2009-01-28T14:36:41.228Z</updated><title type='text'>SVN commit hook</title><content type='html'>If you need to enforce certain patterns in commit messages for svn (eg. ticket nos etc) create a script in ~repos/hooks/pre-commit :&lt;br /&gt;&lt;br /&gt;REPOS="$1"&lt;br /&gt;TXN="$2"&lt;br /&gt;&lt;br /&gt;# Make sure that the log message contains some text of form Feedback nnnnn:&lt;br /&gt;&lt;br /&gt;SVNLOOK=/usr/local/bin/svnlook&lt;br /&gt;match=`$SVNLOOK log -t "$TXN" "$REPOS" | grep -i 'feedback.*[0-9]:'| wc -c`&lt;br /&gt;if [ $match -eq 0 ]&lt;br /&gt;then&lt;br /&gt;        echo "COMMIT HAS FAILED:Log message does not contain feedback number eg. feedback nnnn: commit message" 2&gt;&amp;1&lt;br /&gt;        exit 1&lt;br /&gt;else&lt;br /&gt;        exit 0&lt;br /&gt;fi&lt;br /&gt;&lt;br /&gt;exit 0&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2562324583012100132?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2562324583012100132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2562324583012100132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2562324583012100132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2562324583012100132'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/01/svn-commit-hook.html' title='SVN commit hook'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2316794818320424766</id><published>2009-01-15T12:20:00.004Z</published><updated>2009-01-15T12:40:40.544Z</updated><title type='text'>Apache SSL config on Solaris 10 for 443</title><content type='html'>After installing most recent Apache on our Solaris 10 box we got a lot of errors with the default config for listening on SSL. Many many lines like :&lt;br /&gt;&lt;br /&gt;(128)Network is unreachable: connect to listener on [::]:443&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Basically on Solaris Listen 443 doesn't hack it anymore. If you want to listen on all interfaces use :&lt;br /&gt;&lt;br /&gt;Listen 0.0.0.0:443&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2316794818320424766?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2316794818320424766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2316794818320424766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2316794818320424766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2316794818320424766'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/01/apache-ssl-config-on-solaris-10-for-443.html' title='Apache SSL config on Solaris 10 for 443'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-7922838646284675271</id><published>2009-01-15T12:11:00.002Z</published><updated>2009-01-15T12:17:29.028Z</updated><title type='text'>IE 7 behaviour when passed pdf via https</title><content type='html'>We have had a very odd issue with IE7 being sent pdf files over https. &lt;br /&gt;&lt;br /&gt;Standard headers that look like this :&lt;br /&gt;&lt;br /&gt;Cache-Control: no-cache, must-revalidate&lt;br /&gt;Content-Disposition: attachment;filename=mysecretpdffile.pdf&lt;br /&gt;Content-Type: application/pdf&lt;br /&gt;Content-Length: 19180&lt;br /&gt;Keep-Alive: timeout=5, max=100&lt;br /&gt;Connection: Keep-Alive&lt;br /&gt;&lt;br /&gt;Work fine under IE 5/5.5/6, Opera, Safari et al, but IE 7 reports that the content is not available.&lt;br /&gt;&lt;br /&gt;After a bit of searching I found an excellent post at :&lt;br /&gt;&lt;br /&gt;&lt;a href="http://in2.php.net/manual/en/function.header.php#74736"&gt;http://in2.php.net/manual/en/function.header.php#74736&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For us adding the following headers in Java have resolved the issue :&lt;br /&gt;&lt;br /&gt;response.setHeader( "Pragma", "public" );&lt;br /&gt;response.setHeader( "Content-Transfer-Encoding", "binary" );&lt;br /&gt;response.setHeader( "Expires", "0" );&lt;br /&gt;response.setHeader( "Cache-Control", "must-revalidate, post-check=0, pre-check=0" );&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-7922838646284675271?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/7922838646284675271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=7922838646284675271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7922838646284675271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7922838646284675271'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2009/01/ie-7-behaviour-when-passed-pdf-via.html' title='IE 7 behaviour when passed pdf via https'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-4044131900104796465</id><published>2008-11-11T09:37:00.001Z</published><updated>2008-11-11T09:38:34.996Z</updated><title type='text'>Bash Search History</title><content type='html'>I'm kind of an old school command line hacker, but I've got to face up to the fact that the rest of the world seems to be moving on from the ksh. As such my previous super powers for editing command histories with vi commands (esc-k, /, etc) are going to have to be retired. As the rest of the planet has embraced bash, I've found myself struggling with the fact that crtl-r only lets me get the previous command.&lt;br /&gt;The bask docs suggest that Meta-p will then scroll back through those commands, but esc, alt and apple keys are all major fail for meta on my mac.&lt;br /&gt;&lt;br /&gt;However I have found an acceptable solution. If you create the following .inputrc file then you can start typing any command, then the up/down arrows will allow you to scroll through previous commands that started the same way.&lt;br /&gt;&lt;br /&gt;i.e. type vi then up arrow, up arrow will find the last but 2 vi commands you typed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;# search history via arrows - .inputrc&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"\e[A": history-search-backward&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"\e[B": history-search-forward&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-4044131900104796465?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/4044131900104796465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=4044131900104796465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/4044131900104796465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/4044131900104796465'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2008/11/bash-search-history.html' title='Bash Search History'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2624186499570203040</id><published>2008-07-28T21:13:00.005Z</published><updated>2008-10-09T08:31:51.831Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Oracle 10g doubles and Hibernate</title><content type='html'>I needed to migrate a chunk of data from an example &lt;a href="http://db.apache.org/derby/"&gt;Derby&lt;/a&gt; database up to Oracle 10g today. I found a minor issue with the &lt;a href="http://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; mappings that I was creating. In Derby I could happily have &lt;span style="font-weight: bold;"&gt;double&lt;/span&gt; columns, and these needed to be converted to &lt;span style="font-weight: bold;"&gt;binary_double&lt;/span&gt; columns in Oracle.&lt;br /&gt;&lt;br /&gt;However I kept having issues with the schema validation in hibernate :&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;br /&gt;Wrong column type: binary_double, expected: double precision&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;After looking into the source for the dialect mappings I've found that creating a new dialect that extends the Oracle 9 one as follows solves this problem :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public class Oracle10Dialect extends Oracle9Dialect&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;{&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;public Oracle10Dialect()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;        super();&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;        registerColumnType(Types.DOUBLE, "binary_double"); &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then use this class in the &lt;span style="font-weight: bold;"&gt;persistence.xml&lt;/span&gt; file instead of the Oracle9Dialect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2624186499570203040?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2624186499570203040/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2624186499570203040' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2624186499570203040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2624186499570203040'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2008/07/oracle-10g-doubles-and-hibernate.html' title='Oracle 10g doubles and Hibernate'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-6720451062151485216</id><published>2008-03-10T17:27:00.001Z</published><updated>2008-03-10T17:28:52.944Z</updated><title type='text'>Eclipse Mac Memory Settings</title><content type='html'>I always seem to forget this :&lt;br /&gt;&lt;br /&gt;Edit the eclipse.ini in the Application package, not the one in the install dir.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-6720451062151485216?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/6720451062151485216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=6720451062151485216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/6720451062151485216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/6720451062151485216'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2008/03/eclipse-mac-memory-settings.html' title='Eclipse Mac Memory Settings'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-1723967292484243645</id><published>2008-03-06T11:49:00.003Z</published><updated>2008-03-08T20:38:22.500Z</updated><title type='text'>Parallels Update Problem</title><content type='html'>I've had a problem with upgrading Parallels the excellent tool for running VMs in OSX. For some reason that I could not initially spot the install would hang in the preflight check before applying all the files. I also had a similar problem trying to force an uninstall.&lt;br /&gt;&lt;br /&gt;To cut a long story short it appears that the install/uninstall scripts try to shut down the InternetSharing and bootpd daemons.....in my case these would simply not die through the current script and I had to intervene manually - the install then ran fine.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Edit&lt;br /&gt;NB - Turns out this was actually a symptom of a problem I really struggled to find. The internal script was failing to kill the processes because weirdly the 'awk' calls where causing Bus errors. I could reproduce this with the simplest print $1 style call. Turned out that this was actually a corrupt binary - no idea how this has occurred, but replacing /usr/bin/awk has fixed it all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-1723967292484243645?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/1723967292484243645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=1723967292484243645' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1723967292484243645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/1723967292484243645'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2008/03/parallels-update-problem.html' title='Parallels Update Problem'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2653103510718119140</id><published>2008-02-28T09:48:00.002Z</published><updated>2008-02-28T09:54:11.795Z</updated><title type='text'>Leopard - Spaces - Keyboard shortcut</title><content type='html'>I got frustrated with spaces on Leopard because moving windows around between active spaces didn't seem easy. Turns out it is - all you need to do is click on the menu bar for the window you want moved and then use CTL-LeftArrow/RightArrow to move the window to another space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2653103510718119140?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2653103510718119140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2653103510718119140' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2653103510718119140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2653103510718119140'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2008/02/leopard-spaces-keyboard-shortcut.html' title='Leopard - Spaces - Keyboard shortcut'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-7358426916992704028</id><published>2007-11-14T08:52:00.000Z</published><updated>2007-11-15T11:50:42.196Z</updated><title type='text'>Test Suite Problems</title><content type='html'>One of the projects I work on has a reasonable number of JUnit 3 tests (2500). We also use &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;Cruise Control&lt;/a&gt; to automate the build cycle. Each package has a suite which defines all the tests to be run, but this has become more and more error prone over time. Developers forget to add tests to the suites, leaving orphaned tests etc.&lt;br /&gt;&lt;br /&gt;The obvious solution is to use the batchtest mechanism provided in &lt;a href="http://ant.apache.org/"&gt;Apache Ant&lt;/a&gt;. However this produces an XML file for each test run, containing about 20K of setup information for the tests.&lt;br /&gt;Cruise will then attempt to merge all these XML files for its build reports, which takes a lot of time and a *lot* of RAM.&lt;br /&gt;&lt;br /&gt;So the core issue is that I want to run a single test suite, without having to maintain the suite methods.&lt;br /&gt;&lt;br /&gt;Turns out that using the &lt;a href="http://junit-addons.sourceforge.net/"&gt;JUnit-addons&lt;/a&gt; allows us to do this pretty easily :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;public class AutoTests&lt;br /&gt;{&lt;br /&gt; &lt;br /&gt;       public static Test suite() throws Exception&lt;br /&gt;       {&lt;br /&gt;        DirectorySuiteBuilder builder = new DirectorySuiteBuilder();&lt;br /&gt;&lt;br /&gt;        builder.setFilter(new SimpleTestFilter()&lt;br /&gt;               {&lt;br /&gt;            public boolean include(Class classs)&lt;br /&gt;                       {&lt;br /&gt;                               return super.include(class);&lt;br /&gt;                       }&lt;br /&gt;               });&lt;br /&gt;               return builder.suite("classes");&lt;br /&gt;    }&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This will then select any class that ends Test to a suite. You just call the test as per any JUnit test :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;test outfile="${junit.log.location}/myProj/Tests" name="com.AutoTests"&gt;&lt;/test&gt;&lt;/span&gt;&lt;br /&gt; &lt;span style="font-weight: bold;"&gt;&amp;lt;test outfile="${junit.log.location}/odyssey/Tests" name="com.AutoTests" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I didn't like the fact that you have to know the classes directory in the above example, a really simple (slightly hacky) way around this is to do the following :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;String testClassesLocation=System.getProperty("junit.test.class.location", "classes");&lt;br /&gt;return builder.suite(testClassesLocation);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;then in the ant build file define the class location like this :&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&amp;lt;jvmarg value="-Djunit.test.class.location=classes"/&amp;gt;   &lt;br /&gt;&amp;lt;test outfile="${junit.log.location}/Test" name="com.AutoTests" /&amp;gt;&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;At least this way the junit class location can change without changing the source code for the tests.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-7358426916992704028?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/7358426916992704028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=7358426916992704028' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7358426916992704028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7358426916992704028'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2007/11/test-suite-problems.html' title='Test Suite Problems'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-7157664831730372477</id><published>2007-05-28T18:05:00.001Z</published><updated>2007-05-28T19:05:12.545Z</updated><title type='text'>Passing Parameters To JMeter In Ant</title><content type='html'>As well as using &lt;a href="http://jchav.blogspot.com/"&gt;JChav&lt;/a&gt; as part of our deployment cycle, I have additionally been using it to monitor some production servers. For the production servers you obviously don't run them at any load that is likely to affect the real users. However 1 thread running a set of tests once an hour (thanks to cron) can give a good view of performance over time. I am fully aware of other software that can be used to monitor my sites, but given that I already have a &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; script designed to test key points of the application it seems like the right solution.&lt;br /&gt;&lt;br /&gt;The production server I am using is a cluster placed behind a load balancer and I want to be able to run the tests against each instance. The application already has a URI to manually set each server to use (i.e. the load balancer server affinity), my issue is how do I maintain a single &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; script but be able to set domain/server specific details?&lt;br /&gt;&lt;br /&gt;The great news is that the good folks responsible for &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; have already thought this through and added a property system.&lt;br /&gt;&lt;br /&gt;So given an HTTPSampler that looks like this :&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-weight: bold;"&gt;&amp;lt;HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="SetServer to server1 " enabled="true"&amp;gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;it can be replaced with :&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;  &amp;lt;HTTPSampler guiclass="HttpTestSampleGui" testclass="HTTPSampler" testname="SetServer to ${__property(affinity)} " enabled="true"&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The JMeter &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt; task also allows you to set the property, so you can do the following :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span style="font-weight: bold;"&gt;     &amp;lt;jmeter&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        jmeterhome="${jmeter.install.dir}"&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        testplan="${jmeter.testplan}"&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        resultlog="${jmeter.result.file}"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="affinity" value="server1"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="jmeter.save.saveservice.output_format" value="xml"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;/jmeter&amp;gt;&lt;/span&gt;&lt;br /&gt;           &lt;br /&gt;This will call my JMeter script passing a parameter named affinity with the value server1.&lt;br /&gt;&lt;br /&gt;I want to call my script with several values and store them in different output directories etc. i.e. call my ant script with the property affinitty set to server1, then server2 etc etc.&lt;br /&gt;&lt;br /&gt;I've come up with a hack that works for me, but I'm sure that a better way exists. What I have done is to separate   my ant builds into 2 files. The first builds a single instance, and looks like this :&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt; &lt;span style="font-weight: bold;"&gt;                 &amp;lt;jmeter&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        jmeterhome="${jmeter.install.dir}"&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        testplan="${jmeter.testplan}"&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        resultlog="${jmeter.result.file}"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="affinity" value="${servername}"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="jmeter.save.saveservice.output_format" value="xml"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;/jmeter&amp;gt;&lt;/span&gt;&lt;br /&gt;servername is now a parameter into this script, and all the other directory dependencies etc use that parameter too.&lt;br /&gt;&lt;br /&gt;I then create a master build which calls the build single for each value :&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;                &amp;lt;echo&amp;gt;Testing server1.&amp;lt;/echo&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;ant antfile="build-singleone.xml"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="servername" value="server1"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;/ant&amp;gt;&lt;/span&gt;  &lt;span style="font-weight: bold;"&gt;                &amp;lt;echo&amp;gt;Testing server2.&amp;lt;/echo&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;ant antfile="build-singleone.xml"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="servername" value="server2"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;/ant&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;echo&amp;gt;Testing server3.&amp;lt;/echo&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;ant antfile="build-singleone.xml"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                        &amp;lt;property name="servername" value="server3"/&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &amp;lt;/ant&amp;gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;                &lt;/span&gt;&lt;br /&gt;I don't like the repetition in the script, but it does work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-7157664831730372477?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/7157664831730372477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=7157664831730372477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7157664831730372477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/7157664831730372477'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2007/05/passing-parameters-to-jmeter-in-ant_28.html' title='Passing Parameters To JMeter In Ant'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-2602330121853267688</id><published>2007-05-17T19:44:00.000Z</published><updated>2007-05-17T19:45:02.462Z</updated><title type='text'>Clues on getting started with GWT under Eclipse</title><content type='html'>After an interesting JavaOne session on GWT, I thought I would have a quick play with the toolkit. I hit a little roadblock initially which after discussions with other colleagues they had problems with too.&lt;br /&gt;&lt;br /&gt;In the &lt;a href="http://code.google.com/webtoolkit/gettingstarted.html"&gt;Getting Started&lt;/a&gt; guide the section on building an Eclipse project skips one step that caught me out. Do not create the project in your Eclipse workspace, instead perform the two steps in a temporary area. Then import that temporary project using Eclipse/import/Existing files into workspace - be sure to click the copy source.&lt;br /&gt;&lt;br /&gt;I found if I didn't do that I get errors about the project I was trying to import being already inside the workspace.&lt;br /&gt;&lt;br /&gt;My first impressions of the toolkit are that it is excellent. This all looks much easier than supporting a big ball of JavaScript, and some of the 1.4 features described in the JavaOne talk really seemed to have been well thought out. In particular the idea of combining many small graphics into one large and clipping for view(automatically) will cut down lots of http requests and speed up application start.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-2602330121853267688?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/2602330121853267688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=2602330121853267688' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2602330121853267688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/2602330121853267688'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2007/05/clues-on-getting-started-with-gwt-under.html' title='Clues on getting started with GWT under Eclipse'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-116515881662934532</id><published>2006-12-03T15:02:00.000Z</published><updated>2006-12-03T15:13:36.640Z</updated><title type='text'>Terminator - Tabbed Terminal</title><content type='html'>My formative education was all shell based, and its a tough habbit for an old timer like me to break. I've never quite got on with &lt;b&gt;screens&lt;/b&gt; so was delighted to find &lt;a href="http://software.jessies.org/terminator/"&gt;Terminator&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Terminator is a java application that provides a fast responsive terminal with additional features like searching. However the killer feature for me is tabbed terminals, this is going to save me so much desktop realestate!&lt;br /&gt;&lt;br /&gt;I've only run it on OSX so far, but ports are available for Windows and Linux.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-116515881662934532?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/116515881662934532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=116515881662934532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/116515881662934532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/116515881662934532'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/12/terminator-tabbed-terminal.html' title='Terminator - Tabbed Terminal'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-116042284256479337</id><published>2006-10-09T19:25:00.000Z</published><updated>2006-10-10T18:01:47.276Z</updated><title type='text'>JChav</title><content type='html'>I've been working on &lt;a href="http://jchav.blogspot.com/"&gt;JChav&lt;/a&gt; with a couple of colleagues. It allows you to take the output generated by &lt;a href="http://jakarta.apache.org/jmeter/"&gt;JMeter&lt;/a&gt; and track performance over time.&lt;br /&gt;&lt;br /&gt;The general idea is that you build a JMeter script that gets run from &lt;a href="http://ant.apache.org/"&gt;ant&lt;/a&gt;. So after every automated build/deploy the ant task generates an XML file showing the performance for that build.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://jchav.blogspot.com/"&gt;JChav&lt;/a&gt; ant task then operates on the stored XML files to produce a set of charts. Each chart shows the performance of a given page for each build that has run. Each chart shows you how the performance of the page has changed over time. That way you can show everyone how much better your code is improving (or not) over time.&lt;br /&gt;&lt;br /&gt;Pictures are worth a thousand words, a live demo is available &lt;a href="http://www.cognitran.com/jchav/diggjchavresults/index.html"&gt;here&lt;/a&gt; showing some statistics on accessing digg.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-116042284256479337?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/116042284256479337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=116042284256479337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/116042284256479337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/116042284256479337'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/10/jchav.html' title='JChav'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-115903405905449979</id><published>2006-09-23T17:51:00.000Z</published><updated>2006-09-23T18:00:03.190Z</updated><title type='text'>Distributed Browser Testing With Selenium and CruiseControl</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.openqa.org/selenium-rc/"&gt;Selenium RC&lt;/a&gt; provides an excellent framework for automating UI tests. The issue that we have had with this approach in the past is that we have struggled to automate the use of these tools as no single platform can run the full set of browsers we need for our regression testing.&lt;br /&gt;&lt;br /&gt;I missed the google London Test Automation conference but google video has an excellent &lt;a href="http://video.google.co.uk/videoplay?docid=-594153467742593805"&gt;presentation&lt;/a&gt; by Jason Huggons from the day on exactly these topics. Jason suggests using subordinate machines to perform browser specific tests after deployment. Inspired by this I've rolled up the following as a proof of concept :&lt;br /&gt;&lt;br /&gt;&lt;img src="/images/overview.jpg" alt="Overview" /&gt;&lt;br /&gt;&lt;br /&gt;The top level build is just a normal instance of &lt;a href="http://cruisecontrol.sourceforge.net/"&gt;CruiseControl&lt;/a&gt; running any normal build/unit-test/deploy cycle. If you are not familiar with CruiseControl, in a nutshell it allows you to fully automate the build/test/deploy cycle with &lt;a href="http://ant.apache.org"&gt;ant&lt;/a&gt;. It can be configured to trigger builds automatically after source code is checked into the repository, and report through a variety of mechanisms on completion.&lt;br /&gt;&lt;br /&gt;CruiseControl also provides a JMX interface which is what I am using to launch the Selenium cruise builds. i.e. on completion of my test/deploy cycle I use an ant target as follows to trigger the remote Selenium builds :&lt;br /&gt;&lt;br /&gt;&amp;lt;target name="trigger_remote_selenium_instances"&amp;gt;&lt;br /&gt;        &amp;lt;get dest="tempcontents.html" src="http://testmac1:8000/invoke?operation=build&amp;amp;objectname=CruiseControl+Project%3Aname%3Dseleniumtestproject"&amp;gt;&lt;br /&gt;        &amp;lt;get dest="tempcontents.html" src="http://testlinux:8000/invoke?operation=build&amp;amp;objectname=CruiseControl+Project%3Aname%3Dseleniumtestproject"&amp;gt;&lt;br /&gt;        &amp;lt;get dest="tempcontents.html" src="http://testxp1:8000/invoke?operation=build&amp;amp;objectname=CruiseControl+Project%3Aname%3Dseleniumtestproject"&amp;gt;&lt;br /&gt;&amp;lt;/target&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Process flow&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="/images/flow.jpg" alt="Flow" /&gt;&lt;br /&gt;&lt;br /&gt;The Selenium client ant script being run from CruiseControl pulls the latest tests out of cvs and executes them. Each Selenium cruise instance can have a different execution target (set in the config.xml ant tag).&lt;br /&gt;&lt;br /&gt;Using the antcall tag in the target build its possible to generalise the script so you can perform the set of tests on multiple browsers on the client.&lt;br /&gt;&lt;br /&gt;This is a sample of the ant file I use for this :&lt;br /&gt;&lt;br /&gt;    &amp;lt;target name="init"&amp;gt;   &lt;br /&gt;        &amp;lt;echo&amp;gt;Loading properties from ${user.name}.properties&amp;lt;/echo&amp;gt;&lt;br /&gt;        &amp;lt;property file="${user.name}.properties"&amp;gt;&lt;br /&gt;        &amp;lt;property name="selenium-server-jar" value="./buildlib/selenium-server.jar"&amp;gt;&lt;br /&gt;        &amp;lt;property name="selenium-timeout" value="180"&amp;gt;&lt;br /&gt;       &lt;br /&gt;        &amp;lt;!-- application specific info --&amp;gt;&lt;br /&gt;        &amp;lt;property name="root.path" value="/Users/goul/Documents/seleniumtestproject"&amp;gt;&lt;br /&gt;        &amp;lt;!--NB base URL must not include a trailing slash --&amp;gt;           &lt;br /&gt;        &amp;lt;property name="baseURL" value="http://thetesthost.com"&amp;gt;&lt;br /&gt;       &lt;br /&gt;        &amp;lt;!--NB SUITES HAVE TO BE FULL PATHS NOT RELATIVE RELATIVE PATHS FAIL!!! --&amp;gt;&lt;br /&gt;        &amp;lt;property name="testsuite" value="${root.path}/selenium/suites/my-suite.html"&amp;gt;&lt;br /&gt;       &lt;br /&gt;        &amp;lt;!-- this will have the specific browsers appended to it as they are run --&amp;gt;&lt;br /&gt;        &amp;lt;property name="baseresult" value="../selenium/results/my-results"&amp;gt;&lt;br /&gt;    &amp;lt;/target&amp;gt;&lt;br /&gt;   &lt;br /&gt;    &amp;lt;target name="run-tests-in-all-browsers" depends="init"&amp;gt;&lt;br /&gt;        &amp;lt;!-- add each browser you want this instance to run here --&amp;gt;&lt;br /&gt;        &amp;lt;target="runSeleniumTests"&amp;gt;&lt;br /&gt;            &amp;lt;param name="testbrowser" value="*iexplore"&amp;gt;&lt;br /&gt;            &amp;lt;param name="testresult" value="${baseresult}-ie.html"&amp;gt;&lt;br /&gt;        &amp;lt;/antcall&amp;gt;&lt;br /&gt;       &lt;br /&gt;        &amp;lt;antcall target="runSeleniumTests"&amp;gt;&lt;br /&gt;            &amp;lt;param name="testbrowser" value="*firefox"&amp;gt;&lt;br /&gt;            &amp;lt;param name="testresult" value="${baseresult}-firefox.html"&amp;gt;&lt;br /&gt;        &amp;lt;/antcall&amp;gt;&lt;br /&gt;    &amp;lt;/target&amp;gt;&lt;br /&gt;   &lt;br /&gt;    &amp;lt;target name="runSeleniumTests" depends="init"&amp;gt;&lt;br /&gt;        &amp;lt;echo message="running tests with browser ${testbrowser}"&amp;gt;&lt;br /&gt;        &amp;lt;java jar="${selenium-server-jar}" fork="true" failonerror="true"&amp;gt;&lt;br /&gt;            &amp;lt;arg line="-htmlSuite &amp;quot;${testbrowser}&amp;quot;"&amp;gt;&lt;br /&gt;            &amp;lt;arg line="&amp;quot;${baseURL}&amp;quot;"&amp;gt;&lt;br /&gt;            &amp;lt;arg line="&amp;quot;${testsuite}&amp;quot;"&amp;gt;&lt;br /&gt;            &amp;lt;arg line="&amp;quot;${testresult}&amp;quot;"&amp;gt;&lt;br /&gt;            &amp;lt;arg line="-timeout ${selenium-timeout}"&amp;gt;&lt;br /&gt;        &amp;lt;/java&amp;gt;&lt;br /&gt;       &lt;br /&gt;    &amp;lt;/target&amp;gt;&lt;br /&gt;   &lt;br /&gt;    The produced result files are checked back into the main repository so that they are available to all. The standard cruise mail notification and web site links also provide this information.&lt;br /&gt;   &lt;br /&gt;    In his talk, Jason described how he was experimenting with capturing the running tests themselves as screen cams for review at a later date. I've not pursued that route for now as it seems to be pretty difficult to do in a totally cross platform way.&lt;br /&gt;   &lt;br /&gt;    I'm hoping that this will help speed up some of our regression testing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-115903405905449979?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/115903405905449979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=115903405905449979' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115903405905449979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115903405905449979'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/09/distributed-browser-testing-with.html' title='Distributed Browser Testing With Selenium and CruiseControl'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-115728202393047346</id><published>2006-09-03T10:46:00.000Z</published><updated>2006-09-03T11:17:59.386Z</updated><title type='text'>Mac Essentials</title><content type='html'>I &lt;a href="/2006/04/looks-like-ive-switched.html"&gt;switched&lt;/a&gt; back in April and I thought I should share some of the software I'm now using on a daily basis.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Non Commercial&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://smultron.sourceforge.net/"&gt;Smultron&lt;/a&gt; is a fantastic little text editor. It supports multiple open files, syntax highlighting etc etc.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.utsire.com/shrook/"&gt;Shrook&lt;/a&gt; is a nice RSS feed aggregator, with a simple well thought out GUI.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.neooffice.org/"&gt;NeoOffice&lt;/a&gt; is an Aqua port of Open Office.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.macupdate.com/info.php/id/9178"&gt;Mail Scripts&lt;/a&gt; whilst not something I use every day I'm including it here as it has some hugely useful functions. These include exports of mail in a variety of formats, linking mail and iCal for sending mail and a host of other handy tools.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Commercial&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I still use &lt;a href="http://www.parallels.com/"&gt;Parallels&lt;/a&gt; for the one piece of vpn software I cannot use under OSX.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.omnigroup.com/applications/omnigraffle/"&gt;OmniGraffle&lt;/a&gt; is bar far the best &lt;span class="headerMediumText"&gt;diagramming application I have ever used. I have saved &lt;b&gt;so&lt;/b&gt; much time using this tool, I cannot recommend it highly enough.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-115728202393047346?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/115728202393047346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=115728202393047346' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115728202393047346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115728202393047346'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/09/mac-essentials.html' title='Mac Essentials'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-115678047494810415</id><published>2006-08-28T15:00:00.001Z</published><updated>2008-12-11T13:00:19.683Z</updated><title type='text'>Simple Way To Create An Encrypted Mountable Disk On OSXSimple Way To Create An Encrypted Mountable Disk On OSX</title><content type='html'>I needed a simple encrypted partition for some my Mac laptop. After a bit of searching around, I realised that this is actually a built in feature in OSX. To create/use an encrypted partition perform the following steps :&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Applications/Utility&lt;br /&gt;&lt;br /&gt;launch &lt;b&gt;Disk Utility&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Select &lt;b&gt;New Image&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Give the image a name, size and select AES for encryption.&lt;br /&gt;&lt;br /&gt;Then set a password for the disk. Make sure you do not select the &lt;b&gt;Remember Password&lt;/b&gt; option as this means the partition can be automatically mounted.&lt;br /&gt;&lt;br /&gt;The drive image will then be created.&lt;br /&gt;&lt;br /&gt;To mount the drive select the image in finder and double click it - enter the password and the driver is then available.&lt;br /&gt;&lt;br /&gt;Simply select the eject icon to then remover the image.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This &lt;iframe src="http://rcm-uk.amazon.co.uk/e/cm?t=goulbourncom-21&amp;o=2&amp;p=8&amp;l=as1&amp;asins=B0013NE4S2&amp;md=0M5A6TN3AXP2JHJBWT02&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;would work well in this env.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-115678047494810415?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/115678047494810415/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=115678047494810415' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115678047494810415'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/115678047494810415'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/08/simple-way-to-create-encrypted_28.html' title='Simple Way To Create An Encrypted Mountable Disk On OSXSimple Way To Create An Encrypted Mountable Disk On OSX'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4142358.post-114520069086507928</id><published>2006-04-16T15:04:00.000Z</published><updated>2006-04-16T16:10:45.956Z</updated><title type='text'>RealPlayer</title><content type='html'>Trying to keep up with the football this afternoon showed up a little problem listening to RealPlayer streams on the Intel version of OS X.&lt;br /&gt;&lt;br /&gt;Bottom line is that RealPlayer is not yet a universal binary. So although it runs fine stand alone it doesn't support being embedded in a universal binary.&lt;br /&gt;&lt;br /&gt;i.e. because Safari and Firefox 1.5.0.2 are in universal format, they cannot embed plugins that are not.&lt;br /&gt;&lt;br /&gt;So the options are :&lt;br /&gt;&lt;br /&gt;a) Regress to a nont universal binary version of Firefox&lt;br /&gt;b) Use RealPlayer as both a browser and player - i.e. when you want radion/video enter http://news.bbc.co.uk/ into RealPlayer and browse using it.&lt;br /&gt;&lt;br /&gt;I've gone for b) - but I will investigate mplayer for time shifting shows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4142358-114520069086507928?l=www.goulbourn.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.goulbourn.com/feeds/114520069086507928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4142358&amp;postID=114520069086507928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/114520069086507928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4142358/posts/default/114520069086507928'/><link rel='alternate' type='text/html' href='http://www.goulbourn.com/2006/04/realplayer.html' title='RealPlayer'/><author><name>Paul Goulbourn</name><uri>http://www.blogger.com/profile/03128751854785304048</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
