SlideShare ist ein Scribd-Unternehmen logo
1 von 54
Downloaden Sie, um offline zu lesen
Groovier Selenium
                                Denver JUG 8/13/2008
                                    Frederic Jean
                                  fred@fredjean.net
                                frederic.jean@sun.com



Wednesday, August 13, 2008                              1
who am i


Wednesday, August 13, 2008              2
Topics
                             (Really) Quick intro to Selenium
                             Groovy Metaprogramming through
                             progressive refactorings of a single,
                             simple yet verbose Java Selenium RC
                             Driver example.
                             A few sundry items


Wednesday, August 13, 2008                                           3
Selenium

                             UI testing tool
                             Runs in browser
                             Well suited for Ajax applications




Wednesday, August 13, 2008                                       4
Selenium IDE

                             Firefox plugin
                             Simplifies writing and testing Selenese
                             test case
                             Can record and play back Selenese tests



Wednesday, August 13, 2008                                             5
Selenese
                             HTML Tables
                              Action
                              Target
                              Value
                             Intepreted by Selenium Core
                             Actions match JavaScript functions

Wednesday, August 13, 2008                                        6
Example
                                         BlogTest

                             open                   /

                    clickAndWait            link=Adoption

                                     Out of my mind... : category
                       assertTitle
                                              adoption



Wednesday, August 13, 2008                                          7
Selenese Locators

                             Allows an action to target a specific
                             DOM element on the page
                             <type>=<locator>




Wednesday, August 13, 2008                                          8
Selenese Locators
                             Locator Type               Description
                                             The name of an input element on a
                                name
                                                              form
                                              The id associated with an element
                                  id
                                                            on a page
                                            The text contained within an anchor
                                 link
                                                         element (<a/>)
                                                A JavaScript expression that
                                 dom
                                                      returns an element
                                             An XPath expression pointing to an
                                xpath
                                                      element on the page

Wednesday, August 13, 2008                                                        9
Sample Test


Wednesday, August 13, 2008                 10
Selenese TestSuites

                             Groups and organizes individual
                             Selenese tests
                             Can be run through ant




Wednesday, August 13, 2008                                     11
Selenium RC

                             Runs as a process on a system
                             Listens to requests on a specific port
                             Has drivers for different languages




Wednesday, August 13, 2008                                           12
Selenium RC Drivers
                             Drives the Selenium RC Ser ver
                             programatically
                             Allows integration with xUnit
                             frameworks
                             Flow control and conditionals
                             Java driver provides a SeleneseTestCase
                             class

Wednesday, August 13, 2008                                             13
Generating Java Test


Wednesday, August 13, 2008             14
Generated Java
    package com.example.tests;

    import com.thoughtworks.selenium.*;
    import java.util.regex.Pattern;

    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   15
Generated Java
                                  Where
    package com.example.tests;

    import com.thoughtworks.selenium.*;
                                          is it used?
    import java.util.regex.Pattern;

    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   16
Generated Java
    package com.example.tests;

    import com.thoughtworks.selenium.*;  Need to rename class.
    import java.util.regex.Pattern;

    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   17
Generated Java from
                                     Must inherit
                                                          SeleneseTestCase
    package com.example.tests;

    import com.thoughtworks.selenium.*;
    import java.util.regex.Pattern;

    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   18
Generated Java
    package com.example.tests;

    import com.thoughtworks.selenium.*;
    import java.util.regex.Pattern;


                                        Should rename method
    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   19
Generated Java
    package com.example.tests;


                                    selenium.this
    import com.thoughtworks.selenium.*;
    import java.util.regex.Pattern;

                                   selenium.that
    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {

       }                      selenium.thisandthat
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);

       public void testNew() throws Exception {
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   20
Generated Java
    package com.example.tests;

    import com.thoughtworks.selenium.*;
    import java.util.regex.Pattern;

    public class NewTest extends SeleneseTestCase {
       public void setUp() throws Exception {
          setUp(quot;http://fredjean.net/quot;, quot;*chromequot;);
       }
       public void testNew() throws Exception {    Where did
                                             waitForTextPresent go?
          selenium.open(quot;/quot;);
          selenium.click(quot;link=Adoptionquot;);
          selenium.waitForPageToLoad(quot;30000quot;);
          assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle());
          selenium.click(quot;link=We Are Out!quot;);
          for (int second = 0;; second++) {
             if (second >= 60) fail(quot;timeoutquot;);
             try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {}
             Thread.sleep(1000);
          }

               assertTrue(selenium.isTextPresent(quot;Trackbacksquot;));
          }
    }



Wednesday, August 13, 2008                                                                   21
Generated Java

                             Good start
                             Needs some work to be useful
                             Certainly faster than coding by hand
                             Noisy



Wednesday, August 13, 2008                                          22
Groovy
           package com.example.tests

           import com.thoughtworks.selenium.*

           class NewGroovyTest extends SeleneseTestCase {
               void setUp() {
                   setUp quot;http://fredjean.net/quot;, quot;*chromequot;
               }
               void testNew() {
                   selenium.open quot;/quot;
                   selenium.click quot;link=Adoptionquot;
                   selenium.waitForPageToLoad quot;30000quot;
                   assert quot;Out of my mind... : category adoptionquot; == selenium.title
                   selenium.click quot;link=We Are Out!quot;
                   for (second in 0..60) {
                       if (second == 60) fail quot;timeoutquot;
                       if (selenium.isTextPresent(quot;Commentsquot;)) break;
                       sleep(1000)
                   }

                             assert selenium.isTextPresent(quot;Trackbacksquot;)
                   }
           }



Wednesday, August 13, 2008                                                            23
Groovy

                             Less noisy than Java
                             Still repetitive
                             waitForTextPresent is still missing




Wednesday, August 13, 2008                                         24
Metaprogramming


                      Writing of computer programs that write or
                      manipulate other programs (or themselves) as
                                      their data.




                 http://en.wikipedia.org/wiki/Metaprogramming
Wednesday, August 13, 2008                                           25
Metaprogramming

                             Increases code expressiveness
                             Allows SMEs to understand the code
                              Domain Specific Languages




Wednesday, August 13, 2008                                        26
Meta Object Protocol
                             Establishes the rules behind method
                             calling in Groovy
                             Provides the hooks to modify your
                             program's behavior
                              invokeMethod
                              propertyMissing
                              methodMissing

Wednesday, August 13, 2008                                         27
Metaclass

                             All Groovy objects have one
                             Can be defined for Java objects
                             Per class vs per instance
                             Allows developers to quot;mutatequot; a class



Wednesday, August 13, 2008                                           28
Delegation
                             For ward method calls to another object
                             Tedious to do in Java
                              Extend delegate
                              Manually code delegation code
                             Almost trivial in Groovy
                              ExpandoMetaClass

Wednesday, August 13, 2008                                             29
Groovy Delegation
                             /**
                               * Called when a method cannot be found in the class
                               * or the meta class for an object or class.
                               * @param name The name of the missing method
                               * @param args The arguments for the method
                               */
                             void methodMissing(String name, args) {
                                  selenium.quot;$namequot;(* args)
                             }

                             /**
                               * Called when a property cannot be found in the class
                               * or the meta class associated with a class or object.
                               * @param name The name of the property
                               */
                             void propertyMissing(String name) {
                                  selenium.quot;$namequot;
                             }




Wednesday, August 13, 2008                                                              30
Goodbye Repetition
                             void testDelegation() {
                                 open quot;/quot;
                                 click quot;link=Adoptionquot;
                                 waitForPageToLoad quot;30000quot;
                                 assert quot;Out of my mind... : category adoptionquot; == title
                                 click quot;link=We Are Out!quot;
                                 for (second in 0..60) {
                                     if (second == 60) fail quot;timeoutquot;
                                     if (isTextPresent(quot;Commentsquot;)) break;
                                     sleep(1000)
                                 }

                                 assert isTextPresent(quot;Trackbacksquot;)
                             }




Wednesday, August 13, 2008                                                                 31
Performance Hit




Wednesday, August 13, 2008                     32
Performance Hit




Wednesday, August 13, 2008                     33
Intercept, Cache, Invoke

       /**
         * Called when a method cannot be found in the class
         * or the meta class for an object or class.
         * @param name The name of the missing method
         * @param args The arguments for the method
         */
       void methodMissing(String name, args) {
            NewGroovyTest.metaClass.quot;$namequot; = { Object varArgs ->
                delegate.selenium.metaClass.invokeMethod(delegate.selenium, name, varArgs)
            }
            selenium.quot;$namequot;(* args)
       }




Wednesday, August 13, 2008                                                               34
Performance Hit




Wednesday, August 13, 2008                     35
Groovy Delegation

                             Results in cleaner test code
                             Almost trivial to implement in Groovy
                             Performance hit can be mitigated




Wednesday, August 13, 2008                                           36
waitForTextPresent?
                             void testDelegation() {
                                 open quot;/quot;
                                 click quot;link=Adoptionquot;
                                 waitForPageToLoad quot;30000quot;
                                 assert quot;Out of my mind... : category adoptionquot; == title
                                 click quot;link=We Are Out!quot;
                                 for (second in 0..60) {
                                     if (second == 60) fail quot;timeoutquot;
                                     if (isTextPresent(quot;Commentsquot;)) break;
                                     sleep(1000)
                                 }

                                 assert isTextPresent(quot;Trackbacksquot;)
                             }




Wednesday, August 13, 2008                                                                 37
waitForTextPresent?
                             void testDelegation() {
                                 open quot;/quot;                  Replaces waitFor...
                                 click quot;link=Adoptionquot;
                                 waitForPageToLoad quot;30000quot;   with a loop
                                 assert quot;Out of my mind... : category adoptionquot; == title
                                 click quot;link=We Are Out!quot;
                                 for (second in 0..60) {
                                     if (second == 60) fail quot;timeoutquot;
                                     if (isTextPresent(quot;Commentsquot;)) break;
                                     sleep(1000)
                                 }

                                 assert isTextPresent(quot;Trackbacksquot;)
                             }




Wednesday, August 13, 2008                                                                 38
waitForTextPresent?
                             void testDelegation() {
                                 open quot;/quot;
                                 click quot;link=Adoptionquot;
                                 waitForPageToLoad quot;30000quot;
                                 assert quot;Out of my mind... : category adoptionquot; == title
                                 click quot;link=We Are Out!quot;
                                 for (second in 0..60) {
                                                             How about
                                     if (second == 60) fail quot;timeoutquot;

                                                         assertTextPresent?
                                     if (isTextPresent(quot;Commentsquot;)) break;
                                     sleep(1000)
                                 }

                                 assert isTextPresent(quot;Trackbacksquot;)
                             }




Wednesday, August 13, 2008                                                                 39
waitForTextPresent?

                             Selenese generates waitFor, verify, and
                             assert methods
                             Java driver doesn't provide them
                             Java -> Explicitly typed language
                             JavaScript -> What's a type?


Wednesday, August 13, 2008                                             40
Wait a minute...

                             JavaScript is a dynamic language...
                             Groovy is a dynamic language...
                             Why not synthesize these methods in
                             Groovy?



Wednesday, August 13, 2008                                         41
Synthetic Methods

                             Methods that don't really exist
                             Grails finder methods
                              Person.findByFirstNameAndAge(...)




Wednesday, August 13, 2008                                        42
Steps to Take

                             Identify synthetic methods
                             Implement behavior
                             Locate actual getter method




Wednesday, August 13, 2008                                 43
Identifying Methods
                             def methodMissing(String name, args) {
                                 switch (name) {
                                     case ~/waitForNot.*/: return waitForNot(name, args)
                                     case ~/waitFor.*/: return waitFor(name, args)
                                     case ~/assertNot.*/:
                                         assertNot(name, args)
                                         break
                                     case ~/assert.*/:
                                         assertThat(name, args)
                                         break
                                     case ~/verifyNot.*/:
                                         return verifyNot(name, args)
                                     case ~/verify.*/:
                                         return verifyThat(name, args)
                                     default:
                                         return createAndCallMethod(name, args)
                                 }
                             }




Wednesday, August 13, 2008                                                                 44
Implement Behavior
                private waitFor(name, args) {
                    // Make the bold assumption that the time out is the first param.
                    def timeout = args[0]
                    if (timeout instanceof Integer) {
                        args = args[1..args.length - 1].toArray()
                    } else {
                        timeout = 60000
                    }
                    def methodName = getMethodName(quot;waitForquot;, name);
                    for (i in 0..(timeout / 1000)) {
                        if (quot;$methodNamequot;(* args)) {
                             return true;
                        }
                        sleep(1000)
                    }
                    fail(quot;Timeout occured in $name for $argsquot;)
                }




Wednesday, August 13, 2008                                                              45
Locating Getter

                def getMethodName(prefix, name) {
                    [quot;isquot;, quot;getquot;].collect {
                        name.replaceFirst(prefix, it)
                    }.find {
                        delegate.selenium.metaClass.respondsTo(delegate.selenium, it)
                    }
                }




Wednesday, August 13, 2008                                                              46
Loop Begone!

                             void testDelegation() {
                                 open quot;/quot;
                                 click quot;link=Adoptionquot;
                                 waitForPageToLoad quot;30000quot;
                                 assert quot;Out of my mind... : category adoptionquot; == title
                                 click quot;link=We Are Out!quot;
                                 waitForTextPresent quot;Commentsquot;
                                 assertTextPresent quot;Trackbacksquot;
                             }




Wednesday, August 13, 2008                                                                 47
Refactor!
                             Move methods to super class
                              methodMissing
                              propertyMissing
                              Supporting methods
                             Group Groovy tests in one suite


Wednesday, August 13, 2008                                     48
GroovierSelenium
                             Extends SeleneseTestCase with
                             methodMissing
                             Allows Groovy users to write tests that
                             almost look like Selenese
                             http://groovierselenium.googlecode.com
                             Licensed under ASLv2.0


Wednesday, August 13, 2008                                             49
Near Future

                             JUnit 4.5 test runners
                              GroovierSeleniumRunner
                              GroovySuiteRunner
                             @Selenium annotation



Wednesday, August 13, 2008                             50
NetBeans & Groovy

                             Grails and Groovy Plugin integrated
                             with NetBeans 6.5
                             Adds Groovy Support to Java Projects




Wednesday, August 13, 2008                                          51
Looking Back
                             Talked about Selenium
                             Leveraging Groovy metaprogramming
                              Delegating to another object
                              Creating synthetic methods
                             GroovierSelenium
                             NetBeans

Wednesday, August 13, 2008                                       52
Book


                             Programming Groovy (Venkat S.)




Wednesday, August 13, 2008                                    53
Links

                             http://groovy.codehaus.org
                             http://groovierselenium.googlecode.com
                             http://www.pragprog.com/titles/vslg/
                             programming-groovy



Wednesday, August 13, 2008                                            54

Weitere ähnliche Inhalte

Ähnlich wie Groovier Selenium (Djug)

Automated Web Testing Using Selenium
Automated Web Testing Using SeleniumAutomated Web Testing Using Selenium
Automated Web Testing Using SeleniumWeifeng Zhang
 
Creating a Web of Data with Restlet
Creating a Web of Data with RestletCreating a Web of Data with Restlet
Creating a Web of Data with Restletguest7d0e11
 
JSUG - Java FX by Christoph Pickl
JSUG - Java FX by Christoph PicklJSUG - Java FX by Christoph Pickl
JSUG - Java FX by Christoph PicklChristoph Pickl
 
Testing Java Web Apps With Selenium
Testing Java Web Apps With SeleniumTesting Java Web Apps With Selenium
Testing Java Web Apps With SeleniumMarakana Inc.
 
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with MagentoMagento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with MagentoMagentoImagine
 
Boston selenium meetup: Selenium 2
Boston selenium meetup: Selenium 2Boston selenium meetup: Selenium 2
Boston selenium meetup: Selenium 2epall
 
Introduction to Selenium
Introduction to SeleniumIntroduction to Selenium
Introduction to Seleniumrohitnayak
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Appschrisb206 chrisb206
 
Testing Android
Testing AndroidTesting Android
Testing AndroidMarc Chung
 
DevLabs Alliance Top 50 Selenium Interview Questions for SDET
DevLabs Alliance Top 50 Selenium Interview Questions for SDETDevLabs Alliance Top 50 Selenium Interview Questions for SDET
DevLabs Alliance Top 50 Selenium Interview Questions for SDETDevLabs Alliance
 
前端網頁自動測試
前端網頁自動測試 前端網頁自動測試
前端網頁自動測試 政億 林
 
Turbo Charged Test Suites
Turbo Charged Test SuitesTurbo Charged Test Suites
Turbo Charged Test SuitesCurtis Poe
 
An introduction to OSGi
An introduction to OSGi An introduction to OSGi
An introduction to OSGi Andrea Chiodoni
 
Selenium Testing with TestingBot.com
Selenium Testing with TestingBot.comSelenium Testing with TestingBot.com
Selenium Testing with TestingBot.comtestingbot
 
Basics of Selenium IDE,Core, Remote Control
Basics of Selenium IDE,Core, Remote ControlBasics of Selenium IDE,Core, Remote Control
Basics of Selenium IDE,Core, Remote Controlusha kannappan
 

Ähnlich wie Groovier Selenium (Djug) (20)

Automated Web Testing Using Selenium
Automated Web Testing Using SeleniumAutomated Web Testing Using Selenium
Automated Web Testing Using Selenium
 
Creating a Web of Data with Restlet
Creating a Web of Data with RestletCreating a Web of Data with Restlet
Creating a Web of Data with Restlet
 
Groke
GrokeGroke
Groke
 
JSUG - Java FX by Christoph Pickl
JSUG - Java FX by Christoph PicklJSUG - Java FX by Christoph Pickl
JSUG - Java FX by Christoph Pickl
 
Selenium
SeleniumSelenium
Selenium
 
Testing Java Web Apps With Selenium
Testing Java Web Apps With SeleniumTesting Java Web Apps With Selenium
Testing Java Web Apps With Selenium
 
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with MagentoMagento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
 
Boston selenium meetup: Selenium 2
Boston selenium meetup: Selenium 2Boston selenium meetup: Selenium 2
Boston selenium meetup: Selenium 2
 
Introduction to Selenium
Introduction to SeleniumIntroduction to Selenium
Introduction to Selenium
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-AppsSelenium-Browser-Based-Automated-Testing-for-Grails-Apps
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
 
Testing Android
Testing AndroidTesting Android
Testing Android
 
DevLabs Alliance Top 50 Selenium Interview Questions for SDET
DevLabs Alliance Top 50 Selenium Interview Questions for SDETDevLabs Alliance Top 50 Selenium Interview Questions for SDET
DevLabs Alliance Top 50 Selenium Interview Questions for SDET
 
前端網頁自動測試
前端網頁自動測試 前端網頁自動測試
前端網頁自動測試
 
Turbo Charged Test Suites
Turbo Charged Test SuitesTurbo Charged Test Suites
Turbo Charged Test Suites
 
Selenium Primer
Selenium PrimerSelenium Primer
Selenium Primer
 
Testing In Java
Testing In JavaTesting In Java
Testing In Java
 
Testing In Java4278
Testing In Java4278Testing In Java4278
Testing In Java4278
 
An introduction to OSGi
An introduction to OSGi An introduction to OSGi
An introduction to OSGi
 
Selenium Testing with TestingBot.com
Selenium Testing with TestingBot.comSelenium Testing with TestingBot.com
Selenium Testing with TestingBot.com
 
Basics of Selenium IDE,Core, Remote Control
Basics of Selenium IDE,Core, Remote ControlBasics of Selenium IDE,Core, Remote Control
Basics of Selenium IDE,Core, Remote Control
 

Kürzlich hochgeladen

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 

Kürzlich hochgeladen (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 

Groovier Selenium (Djug)

  • 1. Groovier Selenium Denver JUG 8/13/2008 Frederic Jean fred@fredjean.net frederic.jean@sun.com Wednesday, August 13, 2008 1
  • 2. who am i Wednesday, August 13, 2008 2
  • 3. Topics (Really) Quick intro to Selenium Groovy Metaprogramming through progressive refactorings of a single, simple yet verbose Java Selenium RC Driver example. A few sundry items Wednesday, August 13, 2008 3
  • 4. Selenium UI testing tool Runs in browser Well suited for Ajax applications Wednesday, August 13, 2008 4
  • 5. Selenium IDE Firefox plugin Simplifies writing and testing Selenese test case Can record and play back Selenese tests Wednesday, August 13, 2008 5
  • 6. Selenese HTML Tables Action Target Value Intepreted by Selenium Core Actions match JavaScript functions Wednesday, August 13, 2008 6
  • 7. Example BlogTest open / clickAndWait link=Adoption Out of my mind... : category assertTitle adoption Wednesday, August 13, 2008 7
  • 8. Selenese Locators Allows an action to target a specific DOM element on the page <type>=<locator> Wednesday, August 13, 2008 8
  • 9. Selenese Locators Locator Type Description The name of an input element on a name form The id associated with an element id on a page The text contained within an anchor link element (<a/>) A JavaScript expression that dom returns an element An XPath expression pointing to an xpath element on the page Wednesday, August 13, 2008 9
  • 11. Selenese TestSuites Groups and organizes individual Selenese tests Can be run through ant Wednesday, August 13, 2008 11
  • 12. Selenium RC Runs as a process on a system Listens to requests on a specific port Has drivers for different languages Wednesday, August 13, 2008 12
  • 13. Selenium RC Drivers Drives the Selenium RC Ser ver programatically Allows integration with xUnit frameworks Flow control and conditionals Java driver provides a SeleneseTestCase class Wednesday, August 13, 2008 13
  • 14. Generating Java Test Wednesday, August 13, 2008 14
  • 15. Generated Java package com.example.tests; import com.thoughtworks.selenium.*; import java.util.regex.Pattern; public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 15
  • 16. Generated Java Where package com.example.tests; import com.thoughtworks.selenium.*; is it used? import java.util.regex.Pattern; public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 16
  • 17. Generated Java package com.example.tests; import com.thoughtworks.selenium.*; Need to rename class. import java.util.regex.Pattern; public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 17
  • 18. Generated Java from Must inherit SeleneseTestCase package com.example.tests; import com.thoughtworks.selenium.*; import java.util.regex.Pattern; public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 18
  • 19. Generated Java package com.example.tests; import com.thoughtworks.selenium.*; import java.util.regex.Pattern; Should rename method public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 19
  • 20. Generated Java package com.example.tests; selenium.this import com.thoughtworks.selenium.*; import java.util.regex.Pattern; selenium.that public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { } selenium.thisandthat setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); public void testNew() throws Exception { selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 20
  • 21. Generated Java package com.example.tests; import com.thoughtworks.selenium.*; import java.util.regex.Pattern; public class NewTest extends SeleneseTestCase { public void setUp() throws Exception { setUp(quot;http://fredjean.net/quot;, quot;*chromequot;); } public void testNew() throws Exception { Where did waitForTextPresent go? selenium.open(quot;/quot;); selenium.click(quot;link=Adoptionquot;); selenium.waitForPageToLoad(quot;30000quot;); assertEquals(quot;Out of my mind... : category adoptionquot;, selenium.getTitle()); selenium.click(quot;link=We Are Out!quot;); for (int second = 0;; second++) { if (second >= 60) fail(quot;timeoutquot;); try { if (selenium.isTextPresent(quot;Commentsquot;)) break; } catch (Exception e) {} Thread.sleep(1000); } assertTrue(selenium.isTextPresent(quot;Trackbacksquot;)); } } Wednesday, August 13, 2008 21
  • 22. Generated Java Good start Needs some work to be useful Certainly faster than coding by hand Noisy Wednesday, August 13, 2008 22
  • 23. Groovy package com.example.tests import com.thoughtworks.selenium.* class NewGroovyTest extends SeleneseTestCase { void setUp() { setUp quot;http://fredjean.net/quot;, quot;*chromequot; } void testNew() { selenium.open quot;/quot; selenium.click quot;link=Adoptionquot; selenium.waitForPageToLoad quot;30000quot; assert quot;Out of my mind... : category adoptionquot; == selenium.title selenium.click quot;link=We Are Out!quot; for (second in 0..60) { if (second == 60) fail quot;timeoutquot; if (selenium.isTextPresent(quot;Commentsquot;)) break; sleep(1000) } assert selenium.isTextPresent(quot;Trackbacksquot;) } } Wednesday, August 13, 2008 23
  • 24. Groovy Less noisy than Java Still repetitive waitForTextPresent is still missing Wednesday, August 13, 2008 24
  • 25. Metaprogramming Writing of computer programs that write or manipulate other programs (or themselves) as their data. http://en.wikipedia.org/wiki/Metaprogramming Wednesday, August 13, 2008 25
  • 26. Metaprogramming Increases code expressiveness Allows SMEs to understand the code Domain Specific Languages Wednesday, August 13, 2008 26
  • 27. Meta Object Protocol Establishes the rules behind method calling in Groovy Provides the hooks to modify your program's behavior invokeMethod propertyMissing methodMissing Wednesday, August 13, 2008 27
  • 28. Metaclass All Groovy objects have one Can be defined for Java objects Per class vs per instance Allows developers to quot;mutatequot; a class Wednesday, August 13, 2008 28
  • 29. Delegation For ward method calls to another object Tedious to do in Java Extend delegate Manually code delegation code Almost trivial in Groovy ExpandoMetaClass Wednesday, August 13, 2008 29
  • 30. Groovy Delegation /** * Called when a method cannot be found in the class * or the meta class for an object or class. * @param name The name of the missing method * @param args The arguments for the method */ void methodMissing(String name, args) { selenium.quot;$namequot;(* args) } /** * Called when a property cannot be found in the class * or the meta class associated with a class or object. * @param name The name of the property */ void propertyMissing(String name) { selenium.quot;$namequot; } Wednesday, August 13, 2008 30
  • 31. Goodbye Repetition void testDelegation() { open quot;/quot; click quot;link=Adoptionquot; waitForPageToLoad quot;30000quot; assert quot;Out of my mind... : category adoptionquot; == title click quot;link=We Are Out!quot; for (second in 0..60) { if (second == 60) fail quot;timeoutquot; if (isTextPresent(quot;Commentsquot;)) break; sleep(1000) } assert isTextPresent(quot;Trackbacksquot;) } Wednesday, August 13, 2008 31
  • 34. Intercept, Cache, Invoke /** * Called when a method cannot be found in the class * or the meta class for an object or class. * @param name The name of the missing method * @param args The arguments for the method */ void methodMissing(String name, args) { NewGroovyTest.metaClass.quot;$namequot; = { Object varArgs -> delegate.selenium.metaClass.invokeMethod(delegate.selenium, name, varArgs) } selenium.quot;$namequot;(* args) } Wednesday, August 13, 2008 34
  • 36. Groovy Delegation Results in cleaner test code Almost trivial to implement in Groovy Performance hit can be mitigated Wednesday, August 13, 2008 36
  • 37. waitForTextPresent? void testDelegation() { open quot;/quot; click quot;link=Adoptionquot; waitForPageToLoad quot;30000quot; assert quot;Out of my mind... : category adoptionquot; == title click quot;link=We Are Out!quot; for (second in 0..60) { if (second == 60) fail quot;timeoutquot; if (isTextPresent(quot;Commentsquot;)) break; sleep(1000) } assert isTextPresent(quot;Trackbacksquot;) } Wednesday, August 13, 2008 37
  • 38. waitForTextPresent? void testDelegation() { open quot;/quot; Replaces waitFor... click quot;link=Adoptionquot; waitForPageToLoad quot;30000quot; with a loop assert quot;Out of my mind... : category adoptionquot; == title click quot;link=We Are Out!quot; for (second in 0..60) { if (second == 60) fail quot;timeoutquot; if (isTextPresent(quot;Commentsquot;)) break; sleep(1000) } assert isTextPresent(quot;Trackbacksquot;) } Wednesday, August 13, 2008 38
  • 39. waitForTextPresent? void testDelegation() { open quot;/quot; click quot;link=Adoptionquot; waitForPageToLoad quot;30000quot; assert quot;Out of my mind... : category adoptionquot; == title click quot;link=We Are Out!quot; for (second in 0..60) { How about if (second == 60) fail quot;timeoutquot; assertTextPresent? if (isTextPresent(quot;Commentsquot;)) break; sleep(1000) } assert isTextPresent(quot;Trackbacksquot;) } Wednesday, August 13, 2008 39
  • 40. waitForTextPresent? Selenese generates waitFor, verify, and assert methods Java driver doesn't provide them Java -> Explicitly typed language JavaScript -> What's a type? Wednesday, August 13, 2008 40
  • 41. Wait a minute... JavaScript is a dynamic language... Groovy is a dynamic language... Why not synthesize these methods in Groovy? Wednesday, August 13, 2008 41
  • 42. Synthetic Methods Methods that don't really exist Grails finder methods Person.findByFirstNameAndAge(...) Wednesday, August 13, 2008 42
  • 43. Steps to Take Identify synthetic methods Implement behavior Locate actual getter method Wednesday, August 13, 2008 43
  • 44. Identifying Methods def methodMissing(String name, args) { switch (name) { case ~/waitForNot.*/: return waitForNot(name, args) case ~/waitFor.*/: return waitFor(name, args) case ~/assertNot.*/: assertNot(name, args) break case ~/assert.*/: assertThat(name, args) break case ~/verifyNot.*/: return verifyNot(name, args) case ~/verify.*/: return verifyThat(name, args) default: return createAndCallMethod(name, args) } } Wednesday, August 13, 2008 44
  • 45. Implement Behavior private waitFor(name, args) { // Make the bold assumption that the time out is the first param. def timeout = args[0] if (timeout instanceof Integer) { args = args[1..args.length - 1].toArray() } else { timeout = 60000 } def methodName = getMethodName(quot;waitForquot;, name); for (i in 0..(timeout / 1000)) { if (quot;$methodNamequot;(* args)) { return true; } sleep(1000) } fail(quot;Timeout occured in $name for $argsquot;) } Wednesday, August 13, 2008 45
  • 46. Locating Getter def getMethodName(prefix, name) { [quot;isquot;, quot;getquot;].collect { name.replaceFirst(prefix, it) }.find { delegate.selenium.metaClass.respondsTo(delegate.selenium, it) } } Wednesday, August 13, 2008 46
  • 47. Loop Begone! void testDelegation() { open quot;/quot; click quot;link=Adoptionquot; waitForPageToLoad quot;30000quot; assert quot;Out of my mind... : category adoptionquot; == title click quot;link=We Are Out!quot; waitForTextPresent quot;Commentsquot; assertTextPresent quot;Trackbacksquot; } Wednesday, August 13, 2008 47
  • 48. Refactor! Move methods to super class methodMissing propertyMissing Supporting methods Group Groovy tests in one suite Wednesday, August 13, 2008 48
  • 49. GroovierSelenium Extends SeleneseTestCase with methodMissing Allows Groovy users to write tests that almost look like Selenese http://groovierselenium.googlecode.com Licensed under ASLv2.0 Wednesday, August 13, 2008 49
  • 50. Near Future JUnit 4.5 test runners GroovierSeleniumRunner GroovySuiteRunner @Selenium annotation Wednesday, August 13, 2008 50
  • 51. NetBeans & Groovy Grails and Groovy Plugin integrated with NetBeans 6.5 Adds Groovy Support to Java Projects Wednesday, August 13, 2008 51
  • 52. Looking Back Talked about Selenium Leveraging Groovy metaprogramming Delegating to another object Creating synthetic methods GroovierSelenium NetBeans Wednesday, August 13, 2008 52
  • 53. Book Programming Groovy (Venkat S.) Wednesday, August 13, 2008 53
  • 54. Links http://groovy.codehaus.org http://groovierselenium.googlecode.com http://www.pragprog.com/titles/vslg/ programming-groovy Wednesday, August 13, 2008 54