Tuesday, January 31, 2006

Agile 2006 tutorial proposal submitted

Encouraged by the large number of people who signed up for our PyCon tutorial (and from whom we're still waiting for feedback on the outline), Titus and I just submitted a tutorial proposal for the Agile 2006 conference. While similar to the PyCon tutorial, it has some more emphasis on general agile development and testing techniques as opposed to Python-specific tools. Here is the proposal, in case you're interested. We'll find out by March 30 if it was accepted or not.

=== Presentation title ===

"Agile Web Development and Testing"

=== Author names and contact info ===

Grig Gheorghiu

Email: grig at gheorghiu.net

Web site: agiletesting.blogspot.com

C. Titus Brown

Email: titus at caltech.edu

Web site: www.advogato.org/person/titus

=== Topic ===


We will present a Python Web application that we developed together as an "agile team", using agile development and testing approaches, techniques and tools. The value of the tutorial will consist on one hand in detailing the agile development and testing methods and techniques
we used, and on the other hand in demonstrating specific tools that we used for our development and testing. The main focus of our tutorial will be on automated testing techniques.

The tutorial will cover:

* unit testing and code coverage
* functional/acceptance testing
* Web application testing
* continuous integration and automated smoke testing
* "agile documentation", i.e. using tests as documentation
* issue tracking and agile project management (user stories, tracking iteration and project velocity, burndown charts)

The specific application we will present is a personal mail search and annotation engine that is deployed as a Web application. Users can retrieve mailboxes via the local file system, POP, IMAP or HTTP, then they can browse, search and annotate (i.e. interactively comment on) specific messages.

Although the application was programmed in Python, the techniques and tools we used are in their vast majority applicable to applications written in any programming language.

=== Audience ===

The tutorial is aimed at developers and testers interested in techniques and tools that can help them increase their agility and their testing coverage. A familiarity with agile development concepts is useful, but not required, since will be going through some introductory
agile concepts at the start of the tutorial. Developers and testers of all levels of proficiency, from beginners to experienced practitioners, should find something to take away from the tutorial.

=== Duration ===

180 minutes

=== Benefits ===


The most important benefit that attendees will take away from the tutorial will be an exposure to development and testing tools that they will be able to use immediately in their own applications.

The main focus of the tutorial will consist in presenting tools and techniques for automated testing.

One of our goals in developing the application was to approach testing from as many angles as possible. As such, we will present the notion of "holistic testing", which means making sure that your tests cover all layers of the application:
* unit testing for individual methods/functions/classes
* functional/acceptance testing at the back-end/business logic layer (using Fit/FitNesse)
* functional/acceptance testing at the GUI layer (using twill and Selenium)

We will devote ample time in the tutorial to testing tools that are especially useful for Web applications. Examples of such tools are twill and Selenium. We will also demonstrate how to write acceptance tools at the business logic layer in FitNesse.

An important part of our tutorial will consist in "lessons learned" that we will mention throughout our presentation. Some examples:
* apply the "tracer bullet" development technique by putting together an end-to-end prototype of the application
* as you work through the prototype, enter all of the random thoughts about future features/stories into the tracker or into the milestones
* remote pair programming works really well; it's amazing how much difference a second brain and a second set of eyeballs make, both in keeping each of us accountable to the other, and in increasing the overall quality of the code
* a great way to learn or understand code written by somebody else is to write unit tests for it
* acceptance tests at the business logic/back-end layer (written for example in Fit/FitNesse) proves to be extremely resilient in the presence of code changes; acceptance tests at the GUI layer proves to be more fragile and needed frequent changes to keep up with changes in the UI
* it pays to revisit unit tests, maybe as part of writing "agile documentation" (i.e. using the unit tests themselves as documentation); you can find yourself discovering bugs that weren't caught by your initial unit tests
* a tool such as Trac proves to be very useful for an agile approach to development and testing. Trac combines:
* a Wiki -- which allows easy editing/jotting down of ideas and encourages brainstorming
* a defect tracking system -- which simplifies keeping track of not only bugs, but also tasks and enhancements
* a source browser -- which makes it easy to see all the SVN changesets
* a roadmap -- where you define milestones that are tied into the tracker
* a timeline -- which is a constantly-updated, RSS-ified chronological image of all the important events that happened in the project: code checkins, ticket changes, wiki changes, milestones
* Trac can be used as an agile project management tool by defining:
* iterations as milestones
* user stories as tickets of type "enhancement"
* stories split into tasks, which are tickets of type "task"
* Trac offers a nice "tickets per milestone" view which allows you to see your progress in completing tasks/stories associated with a particular iteration/milestone

=== Content Outline ===

1.5 hours:

* Introduction, who we are, outline of agile approach & test types
* Application demo, architecture, design principles
* Agile project management and issue tracking with Trac
* Continuous integration, smoke testing
* Agile documentation
* Unit testing, code coverage analysis
* Behavior-based acceptance testing via logging with TextTest

BREAK

1.5 hours:

* Acceptance testing with FitNesse
* Automated Web browsing and functional testing with twill
* Web application GUI testing with Selenium (we will also
demonstrate testing Ajax-specific functionality)
* Wrap-up, summary, cheering, Q&A

=== Process or format ===


The vast majority of the tutorial will consist of a live demo of the application and of the tools we used in developing and testing it. We will also have some slides with introductory material on agile concepts and techniques, but the core of our presentation will be hands-on and interactive.

=== Presenter bio ===

Grig Gheorghiu

Grig Gheorghiu has worked for the last 13 years as a programmer, research lab manager, system/network/security architect, and most recently as a software test engineer. Grig is a member of the Agile Alliance and of the xpsocal user group.

Articles:
* Article on Selenium in Oct. 2005 issue of "Better Software" magazine
* Article on "Agile testing with Python test frameworks" in Agile Times e-zine, vol. 7

Talks/presentations:
* Southern California Code Camp 2006 presentation on "Agile testing with Python test frameworks"
* StarWest 2005 Lightning Talk on Web application testing with Selenium
* PyCon 2005 presentation on "Agile testing with Python test frameworks"
* PyCon 2005 Lightning Talk on FitNesse and Selenium
* Regular posting of articles/tutorials/howtos on personal blog

Open Source projects:
* Cheesecake (tool which computes quality index for Python packages)
* pyUnitPerf (port of Mike Clark's jUnitPerf "continuous performance unit testing" tool to Python)

C. Titus Brown

Articles:
* substantial record of scientific publications in Digital Life, climatology, bioinformatics, and biology;
* article on "Bioinformatics in Python" in PyZine.

Talks/presentations:
* PyCon 2002 presentation on PyWX
* Regular postings of articles/tutorials/howtos on personal blog


Software projects:
* Lead architect and developer on multiple OSS projects, including:
* Cartwheel and FamilyRelationsII (bioinformatics GUI/Web site/processing pipeline);
* twill (Web testing tool);
* paircomp and motility libraries for bioinformatics searches;

Both presenters are organizers of the Southern California Python Interest Group, aka SoCal Piggies, and they have given numerous presentations at the monthly group meetings. Please visit the group's home page for details.

=== History of tutorial ===


A variant of this tutorial, with an increased focus on Python-specific techniques, will be presented at PyCon 2006, Dallas, on 02/23/06. The PyCon tutorial proposal proved to be very popular with the people registering for the conference. The organizers attracted a record registration of 41 participants before participation was cut off by PyCon.

Friday, January 27, 2006

Are unit tests free when TDD-ing?

Interesting post from Cory Foy, who quotes William Petri. More ammo for people who are trying to convince their colleagues/bosses/etc. that you don't waste, but on the contrary you gain time when you do TDD -- or TED (Test Enhanced Development) as I dubbed a variant of it: write some code, write unit tests for that code, then write more code, then more unit tests, etc.; note that the person writing the initial code can be different from the person writing the initial unit tests.

W.A., the one and only

...that would be Mozart, whose 250th anniversary is today. Mozart trivia for today: he was baptized as "Johannes Chrysostomus Wolfgangus Theophilus". I guess Amadeus sounded better than Theophilus, while conveying the same idea. In any case, as they say, if Mozart didn't exist, he should have been invented -- he's up at the top in my Classical Music Hall of Fame. I like a quote from an article in today's L.A. Times: "As pianist Artur Schnabel observed, Mozart is too easy for children and too difficult for artists."

Tuesday, January 24, 2006

Useful tools for writing Selenium tests

I've been writing a lot of Selenium tests lately and I've been using some tools that I find extremely useful for composing table-style tests. Let me start by saying that writing GUI-based tests for Web apps is no fun, no matter what your testing tool is. You need to navigate through pages, fill and submit forms, and verify that certain elements are present on the pages. Doing all this manually can quickly become tedious and kill whatever joy you may find in testing.

If you're writing Selenium tests, these activities are, if not fun, at least tolerable due to the existence of the Selenium Recorder ("the Selenium Recorder -- can't imagine life as a Web app tester without it" seems like a good line for a commercial :-)

The Selenium Recorder (which I'll refer to as SelRec from now on) is a Firefox extension that you launch via the Tools menu. It intercepts Web browsing actions such as opening a URL, clicking on a link, entering text in a field form, selecting a drop-down menu item, submitting a form, etc., and it records them in HTML format, ready to be copied and pasted into your Selenium test files. What I find most remarkable about this is that I don't need to worry about identifying HTML elements in order to find a suitable Selenium locator such as an XPath expression, or a DOM expression. For example, SelRec is smart enough to identify links using the simplest locator expression that uniquely identifies a link. If the name of the link is unique, SelRec will use it. If several links have the same name, SelRec will automatically use an XPath expression that uniquely identifies each link.

SelRec can also help with certain Selenium assertion commands. For example, if you highlight the text on a Web page and right-click, you'll see a menu item called "Append Selenium command" which allows you to add one of the following 2 commands to your test table:
  • verifyTextPresent|highlighted text|
  • verifyTitle|title of the current Web page|
You can also append "open|current URL|" to your test table via the "Append Selenium command" menu.

I would guess that most of the testing you're doing with Selenium consists in opening URLs, clicking on various page elements, submitting forms and asserting that some text is present on a Web page or that a Web page has a certain title. Since all these actions and verifications are supported by SelRec out of the box, your life as a tester suddenly becomes a bit easier.

One problem with the "verifyTextPresent" command is that it doesn't support regular expressions. Many times you do need to verify that a specific chunk of text on your page conforms to a regular expression. For this, you need the "verifyText" command, which takes as its first argument the locator of the HTML element whose text you need to verify. This is when things become a bit hairy: you somehow need to identify that element. You can always try to do it in your head by eye-balling the HTML source of the page and trying to come up with the right XPath expression. But fortunately there's an easier way.

At this point, I'm glad to be able to point you to another sanity-saving tool: XPath Checker, which is also a Firefox extension. After installing it, you highlight any text on a Web page, right-click and choose "View XPath". A Firefox window will pop up with an entry field containing an XPath expression, as identified by the tool, and with the text matching that expression. This window allows you to interactively change the XPath expression and see the text that it matches. It's great for playing with and learning XPath (BTW, here is a great XPath tutorial).

Together, the Selenium Recorder and the XPath Checker tools will allow you to easily write the vast majority of your Selenium tests. For more advanced functionality, I refer you to the many Selenium user extensions contributed by people active in the Selenium community. For some nifty Ajax testing (if I may say so myself), see also this blog post of mine.

Note that XPath expressions don't work that well in Internet Explorer. If browser compatibility is high on your list, then you probably need to identify HTML elements via their DOM locations. For that, you can use the DOM Locator extension which ships with Firefox, but you can also peek at the XPath expression generated by the XPath Checker and try to come up with the equivalent DOM expression. Camino, a Mac-specific browser, doesn't seem to have this problem, so you can very easily write your Selenium tests using Firefox with its extensions, then run them in Camino (Titus and I did just that when testing our PyCon tutorial app).

To wrap this thing up, here's an example of using the SelRec and the XPath Checker. Let's assume you want to test some of the search functionality of amazon.com. Note that you can't do this with table-mode Selenium unless you work for amazon.com, because you need to deploy your tests on the amazon.com Web app servers. But for the sake of this example, I just want to illustrate how to use the tools when testing a complex Web site.

Here's a test table that was generated with the Selenium Recorder and that I edited with Mozilla Composer in order to add my own verifyText commands, for which I used XPath expressions that were generated with the XPath Checker:

Amazon Test
open http://www.amazon.com
verifyTitle Amazon.com: Online Shopping for Electronics, Apparel, Computers, Books, DVDs & more
type field-keywords python
clickAndWait //input[@type='image' and @alt='Go']
verifyTitle Amazon.com: All Products Search Results: python
verifyText //*[@id='Td:0']/table/tbody/tr/td/table/tbody/tr/td[2]/table/tbody/tr[1] Learning Python, Second Edition by Mark Lutz and David Ascher (Paperback - Dec 2003)
click link=Learning Python, Second Edition
verifyTitle Amazon.com: Learning Python, Second Edition: Books: Mark Lutz,David Ascher
verifyText /html/body/table[2]/tbody/tr/td[2]/div[2] regexp:Buy this book with .* by Alex Martelli today!
verifyText /html/body/table[2]/tbody/tr/td[2]/table[2]/tbody/tr/td/div/ul[1]/li[4] ISBN: 0596002815

The Selenium Recorder can help even when adding your own verifyText commands. Here's how I did it:
  • I highlighted the text I wanted to verify on the Web page under test, then I right-clicked and I chose "Append Selenium command" -> verifyTextPresent "highlighted text"
  • I saved the file generated by SelRec, then I opened it in Mozilla Composer
  • The last row in the file was something like |verifyTextPresent|some text||
  • I edited the row and I replaced "verifyTextPresent" with "verifyText", then I did a cut and paste of "some text" from the second to the third cell
  • I highlighted again the text on the Web page under test, I right-clicked and I chose "View XPath", then I copied the XPath expression generated by the XPath Checker in the second cell of the table row
  • The row now looks something like |verifyText|//some/xpath[2]/expression|some text|
  • At this point, if you need to make sure that "some text" matches a regular expression, you can start the third cell with "regexp:" followed by the regular expression (for example, in the table above, I used the somewhat-contrived "regexp:Buy this book with .* by Alex Martelli today!")
Hope this all helps. I'll soon add post another entry on dealing with frames and pop-up windows in Selenium.

Updates

  • Patrick Lightbody, the maintainer of openqa.org, where Selenium is hosted, reminded me that the Selenium Recorder project is now called the Selenium IDE and is hosted at OpenQA. There is no release of the Selenium IDE yet, but you'll find out when it will be available, I promise :-)
  • Speaking of the upcoming release for the Selenium Recorder/IDE, one feature I'd like to see added is the capability of adding verifyText commands, with the XPath expression corresponding to the highlighted text -- an unification of the XPath Checker functionality with the current verifyText functionality in SelRec
  • Luke Closs points out that he wrote a tool that allows him to write Selenium tests in simple wiki-like tables, then it will convert them into HTML and auto-create a TestSuite.html for him; you can find more info about Luke's Perl-based tool at awesnob.com/selutils.
  • An anonymous commenter points out XPather as another Firefox extension that's superior in his/her opinion to the XPath Checker extension

PyCon tutorial outline feedback

For people who registered for the "Agile Development and Testing in Python" tutorial that Titus Brown and I will present at PyCon06, we put together a Wiki page with the current outline of the tutorial. If you will be attending the tutorial, please feel free to edit the page and add comments/suggestions on stuff that you would like to see covered at the tutorial.

Sunday, January 22, 2006

SoCal Code Camp presentation

The SoCal Code Camp event took place yesterday and today. I presented an updated version of my PyCon '05 talk, "Agile Testing with Python Test Frameworks". When I submitted my talk proposal, back in October '05, I had no idea the Code Camp will be so much Microsoft-centric. At the time, it seemed like a get-together of coders of all kinds. However, it seems that a lot of Microsoft user groups got involved in the organization, with the inevitable result that it felt like a Microsoft-sponsored event (which it might have been, for all I know). To be fair, the schedule did include a number of Java talks, but it did feel like the overall tone was of the "ode to Micro$oft" type.

Anyway, my talk attracted no less than 5 people! Pretty amazing, isn't it? Joking aside, as the common wisdom goes, if only one person took something away from it, even then it means my goal was met, etc., etc. I did have time to demo Selenium, so I hope that people took that away at least. The other bright side, as I look at it, is that Python got represented at the conference. The only other non-Java, non-.NET language represented was Ruby, with one session on Ruby 101 and the other one on the inevitable Ruby on Rails.

I did enjoy the free "geek dinner" sponsored by a few Microsoft-affiliated companies, where I ran into a couple of fellow xpsocal members, Paul Hodgetts and Paul Moore, who also presented a session on TDD using Java and Eclipse. The dinner sported live rock music, an idea that apparently originated with Das Blonde herself (if you don't know the name, then you haven't been to many Microsoft events/conferences; me neither -- but you and I are in stark minority compared to the people at that dinner...)

Anyway, maybe next year the organizers will split the conference into a Java track, a .NET track, and a "off-the-wall as far as Java/.Net programmers are concerned" track, where my presentation clearly belonged.

Wednesday, January 18, 2006

Ambition and the 25% rule

I finished reading "Ambition", a book by the sociologist Gilbert Brim. One thing I took away from the book is that we humans seem to be most happy when we're faced with what Brim calls "manageable difficulties" -- challenges that are neither too easy (because then we become bored), nor too hard (because then we become discouraged/depressed). Brim says that humans are driven towards mastery and achievement in whatever field they set their eyes, or minds, or souls on. We are an ambitious kind, always striving to do better, not only in ordinary careers, but also when we meditate or when we walk on spiritual paths, supposedly getting away from it all. In all cases we will try to do our best to achieve mastery.

Brim cites the "25% rule", discovered by another sociologist whose name I forget. The rule states that no matter what level of income we achieve, we instantly shoot for 25% more. Brim says that he suspects this rule holds true not only when it comes to money, but also when it comes to fame, spirituality, etc. And when/if we get that 25% increase, we feel a brief moment of happiness ("brief" is the operative word here), then we roll our sleeves and keep working for that elusive moment when we'll finally have made it or achieved it.

I tend to agree with Brim. It seems to me that the best we can do is use our innate ambition to achieve something meaningful not only to us, but also to others. And maybe we should try to enjoy and prolong those too-brief periods of happiness :-) For us computer geeks, this possibly translates into working as teams on Open Source projects and enjoying the process more than the end product.

You can read some excerpts from Brim's book here.

Testing Commentary (and thus Ajax) with Selenium

I've been working on adding Selenium tests to the application that Titus and I will be presenting at our PyCon tutorial in February. Titus included Ian Bicking's Commentary functionality into our app, and of course the challenge was how to test this stuff. If you visit the live Commentary page and double-click anywhere on the page, a form magically pops up (Ajax stuff, of course) and allows you to enter and save a comment. The challenge of course was how to fire the mouse doubleclick event in Selenium. After a lot of pain, mostly involving searching through the messages posted to the selenium-dev and selenium-users lists at OpenQA.org, I came up with a solution. It's not pretty, but it does the job well enough.

I can't show you a live demo yet, but here's what I did to get it to work.

I extended the selenium-api.js and selenium-browserbot.js files and added functions dealing with mouse doubleclick events. This basically added a new dblclick command to the "Selenese" API. Here, a huge help was the "Key and Mouse events" post on the OpenQA JIRA issue tracker, and its associated code (kudos to FJH for writing it).

I added the following lines to selenium-api.js:

Selenium.prototype.doDblclick = function(locator) {
var element = this.page().findElement(locator);
this.page().dblclickElement(element);
};
I added the following lines to selenium-browserbot.js (if you need to support IE, you need to add a corresponding IEPageBot function):
MozillaPageBot.prototype.dblclickElement = function(element) {

triggerEvent(element, 'focus', false);

// Trigger the mouse event.
triggerMouseEvent(element, 'dblclick', true);

if (this.windowClosed()) {
return;
}

triggerEvent(element, 'blur', false);
};

At this point, I was able to put together a Selenium test table in order to test the functionality of opening a commentary form via double-clicking, filling the username, email and commentary fields, clicking the Save button, and finally verifying that the text of the commentary appears on the page. I chose //blockquote as the element locator to fire the doubleclick on, but I could just as easily have chosen any element on the page under test via its XPath location (speaking about XPath, here's a good tutorial).

Here are the relevant rows of the test table:

dblclick //blockquote
pause 2000
store javascript{Math.round(1000*Math.random())} var
type username user${var}
type email user${var}@example.com
type comment hello there from user${var}
click //form//button[1]
pause 2000
assertTextPresent hello there from user${var}


The "pause" commands were necessary to wait for the page to be updated via the Commentary Ajax calls. I could have used the waitForCondition user extension contributed by Dan Fabulich, but I took the easy way out for now. I do intend to rewrite the test so that it uses waitForCondition, because the pause command is not reliable enough. On some slower machines, it took much longer for the Commentary form to be saved.

Bottom line: Selenium passed the test of testing an Ajax application with flying colors! If you have Ajax code that depends on other key or mouse events, take a look at the code and the corresponding Selenium table test posted by FJH.

Wednesday, January 11, 2006

Running Selenium in Python Driven Mode

Update August 2007

For people who are stumbling on this blog post via searches: this post is outdated. There is no Python Driven Mode' in Selenium anymore. Instead, you should use Selenium RC, which offers the same capabilities and much more.

Original post:

I blogged about this before, but here it is again, in a shorter and hopefully easier to understand format. This post was prompted by questions on the selenium-users at openqa.org mailing list on how to run Selenium in Driven Mode using Python. By Driven Mode, people generally understand scripting Selenium commands as opposed to writing them in HTML tables. Scripting offers obvious advantages, such as real programming language constructs and idioms.

Here is a step-by-step HOWTO on running Selenium in Driven Mode using Python. I just tried on a Windows XP computer (see this blog post of mine for details on running it on *nix):

1. Download and install Twisted version 1.3 (this is important, because things have been known not to work so well with Twisted 2.x). Old versions of Twisted, including 1.3, can be downloaded from here. I used Twisted 1.3 for Python 2.4.

2. Check out the Selenium source code:

svn co http://svn.openqa.org/svn/selenium/trunk selenium

3. Let's assume you checked out the code in C:\proj\selenium. You need to copy the contents of C:\proj\selenium\code\javascript (the contents, not that directory itself) into the C:\proj\selenium\code\python\twisted\src\selenium\selenium_driver directory.

4. Open a DOS command prompt and cd into C:\proj\selenium\code\python\twisted\src\selenium, then run:

python selenium_server.py

You should see something like this printed at the console (if you don't have PyCrypto already installed):

C:\proj\selenium\code\python\twisted\src\selenium>python selenium_server.py
C:\Python24\lib\site-packages\twisted\protocols\dns.py:61: RuntimeWarning: PyCrypto not available - proceeding with non-cryptographically secure random source 1
Starting up Selenium Server...

To verify that the Twisted-based Selenium server is up and running, open this URL in a browser: http://localhost:8080/selenium-driver/SeleneseRunner.html

You should see the Selenium Functional Test Runner page at this point.

5. Open another DOS command prompt and cd into C:\proj\selenium\code\python\twisted\src\selenium, then run:

python google-test-xmlrpc.py

At this point, a browser window will be automatically opened, the browser will connect to the SeleneseRunner.html page and will execute the test commands specified in the google-test-xmlrpc.py script. You should see the bottom frame of the SeleneseRunner.html page open the Google home page, then enter a search phrase and run the search. Here is what it looks like in my case (click on the image to see a larger image):



Also, the google-test-xmlrpc script printed this on the console:

OK
PASSED
OK
PASSED
OK
PASSED
Actual value 'Selenium ThoughtWorks - Google Search' did not match 'Google Search: Selenium ThoughtWorks'
test complete

So you can see that the one of the test commands -- app.verifyTitle('Google Search: Selenium ThoughtWorks') -- actually fails, because Google changed the way they construct the title for search result pages.

Note that you can drive Selenium from any language that offers XML-RPC client libraries. If you look in the twisted\src\examples directory, you'll notice that besides the Python client script, a Ruby script and a Perl script are also included. You can just as easily write Java code to do the same thing.

That's about it. Let me know if you have problems following these steps. Leave a comment on this blog or write to the selenium-users at openqa.org mailing list.

Tuesday, January 10, 2006

PyFit finally at the CheeseShop

John Roth, the PyFit developer/maintainer, finally uploaded the latest version of PyFit to the CheeseShop. PyFit is the Python port of the FIT framework initially created by Ward Cunningham. PyFit also integrates with the FitNesse framework, so you get the best of both worlds. I wrote a series of PyFit/FitNesse tutorials which you can read here.

I'm currently writing PyFit functional/acceptance tests for the application that Titus and I will present at our PyCon tutorial. Writing acceptance tests as Wiki pages peppered with test tables is a very effective way of both documenting the desired behavior of the software and testing it at the same time. The FitNesse tests serve as an alternative GUI into the application. They test it at the "business logic" layer, which means that they are much more robust in the presence of GUI changes. See this post of mine for some thoughts on running FitNesse vs. Selenium tests. For a great series of articles on Agile Requirements and Fit-syle testing, see this post from James Shore.

Wednesday, January 04, 2006

Selenium at OpenQA

I blogged about this before, but I want to respond to a call to arms on the selenium-users mailing list that was asking people to link to the new home for the Selenium project: OpenQA.

Some useful links:
BTW, Happy New Year 2006 everybody!