Suche senden
Hochladen
Groovy Testing Sep2009
•
28 gefällt mir
•
8,616 views
Paul King
Folgen
Now superceded by http://www.slideshare.net/paulk_asert/make-tests-groovy
Weniger lesen
Mehr lesen
Technologie
Business
Melden
Teilen
Melden
Teilen
1 von 203
Jetzt herunterladen
Downloaden Sie, um offline zu lesen
Empfohlen
Make Your Testing Groovy
Make Your Testing Groovy
Paul King
Groovy Power Features
Groovy Power Features
Paul King
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
Atlassian
GWT-Basics
GWT-Basics
tutorialsruby
Is the current model of load testing broken ukcmg - steve thair
Is the current model of load testing broken ukcmg - steve thair
Stephen Thair
Ts 2992
Ts 2992
Bin Shao
Enterprise IPv6 Deployment
Enterprise IPv6 Deployment
Cisco Canada
OSGi-enabled Java EE applications in GlassFish
OSGi-enabled Java EE applications in GlassFish
Arun Gupta
Empfohlen
Make Your Testing Groovy
Make Your Testing Groovy
Paul King
Groovy Power Features
Groovy Power Features
Paul King
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
Atlassian
GWT-Basics
GWT-Basics
tutorialsruby
Is the current model of load testing broken ukcmg - steve thair
Is the current model of load testing broken ukcmg - steve thair
Stephen Thair
Ts 2992
Ts 2992
Bin Shao
Enterprise IPv6 Deployment
Enterprise IPv6 Deployment
Cisco Canada
OSGi-enabled Java EE applications in GlassFish
OSGi-enabled Java EE applications in GlassFish
Arun Gupta
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
Atlassian
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Arun Gupta
Weld-OSGi, injecting easiness in OSGi
Weld-OSGi, injecting easiness in OSGi
Mathieu Ancelin
Groovy Tutorial
Groovy Tutorial
Paul King
Polyglot OSGi
Polyglot OSGi
Matt Stine
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
Arun Gupta
Modern web application development with java ee 7
Modern web application development with java ee 7
Shekhar Gulati
Web Content Management System Deployment Patterns
Web Content Management System Deployment Patterns
sggottlieb
Merb The Super Bike Of Frameworks
Merb The Super Bike Of Frameworks
Rowan Hick
Compile ahead of time. It's fine?
Compile ahead of time. It's fine?
Dmitry Chuyko
JDK9 Features (Summary, 31/Jul/2015) #JJUG
JDK9 Features (Summary, 31/Jul/2015) #JJUG
Yuji Kubota
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
Atlassian
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
Webservices(or)SoapUI Interview Questions
Webservices(or)SoapUI Interview Questions
H2kInfosys
Testing in-groovy
Testing in-groovy
Franz Allan See
Groovy Testing
Groovy Testing
Davide Rossi
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
Debasish Ghosh
Testing Web Applications with GEB
Testing Web Applications with GEB
Howard Lewis Ship
Emc cla rii on fibre channel storage fundamentals
Emc cla rii on fibre channel storage fundamentals
weiguang sun
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
Алёна Глущенко
China high speed railway lines network-201407
China high speed railway lines network-201407
tjrgx
Merkel wiper auas
Merkel wiper auas
walleseals
Weitere ähnliche Inhalte
Was ist angesagt?
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
Atlassian
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Arun Gupta
Weld-OSGi, injecting easiness in OSGi
Weld-OSGi, injecting easiness in OSGi
Mathieu Ancelin
Groovy Tutorial
Groovy Tutorial
Paul King
Polyglot OSGi
Polyglot OSGi
Matt Stine
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
Arun Gupta
Modern web application development with java ee 7
Modern web application development with java ee 7
Shekhar Gulati
Web Content Management System Deployment Patterns
Web Content Management System Deployment Patterns
sggottlieb
Merb The Super Bike Of Frameworks
Merb The Super Bike Of Frameworks
Rowan Hick
Compile ahead of time. It's fine?
Compile ahead of time. It's fine?
Dmitry Chuyko
JDK9 Features (Summary, 31/Jul/2015) #JJUG
JDK9 Features (Summary, 31/Jul/2015) #JJUG
Yuji Kubota
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
Atlassian
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
HUJAK - Hrvatska udruga Java korisnika / Croatian Java User Association
Was ist angesagt?
(13)
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
JIRA Studio: Development in the Cloud - Atlassian Summit 2010
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Building HTML5 WebSocket Apps in Java at JavaOne Latin America 2012
Weld-OSGi, injecting easiness in OSGi
Weld-OSGi, injecting easiness in OSGi
Groovy Tutorial
Groovy Tutorial
Polyglot OSGi
Polyglot OSGi
Java Summit Chennai: JAX-RS 2.0
Java Summit Chennai: JAX-RS 2.0
Modern web application development with java ee 7
Modern web application development with java ee 7
Web Content Management System Deployment Patterns
Web Content Management System Deployment Patterns
Merb The Super Bike Of Frameworks
Merb The Super Bike Of Frameworks
Compile ahead of time. It's fine?
Compile ahead of time. It's fine?
JDK9 Features (Summary, 31/Jul/2015) #JJUG
JDK9 Features (Summary, 31/Jul/2015) #JJUG
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
Performance Tuning: Pulling a Rabbit From a Hat - Atlassian Summit 2010
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
JavaCro'15 - Everything a Java EE Developer needs to know about the JavaScrip...
Andere mochten auch
Webservices(or)SoapUI Interview Questions
Webservices(or)SoapUI Interview Questions
H2kInfosys
Testing in-groovy
Testing in-groovy
Franz Allan See
Groovy Testing
Groovy Testing
Davide Rossi
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
Debasish Ghosh
Testing Web Applications with GEB
Testing Web Applications with GEB
Howard Lewis Ship
Emc cla rii on fibre channel storage fundamentals
Emc cla rii on fibre channel storage fundamentals
weiguang sun
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
Алёна Глущенко
China high speed railway lines network-201407
China high speed railway lines network-201407
tjrgx
Merkel wiper auas
Merkel wiper auas
walleseals
Helping Journalists Get It Right
Helping Journalists Get It Right
Renita Coleman
Solinea Lazuli Tower Project Brief
Solinea Lazuli Tower Project Brief
sevenseaspropertycorp
02មហាគ្រោះជាតិខ្មែរ great danger-khmer-nation-official-khmerlanguage by tie...
02មហាគ្រោះជាតិខ្មែរ great danger-khmer-nation-official-khmerlanguage by tie...
Veha Thmey
Does Your Stuff Scale?
Does Your Stuff Scale?
stevenh0lmes
Obo mne
Obo mne
windof
Being Miss Geeky - WIT
Being Miss Geeky - WIT
Melinda Seckington
Report abc company draft
Report abc company draft
AiiM Education
HAKQ Profile
HAKQ Profile
smartbuddy1
Effectivnoe upravlenie personalom
Effectivnoe upravlenie personalom
Настасья Варламова
Marriott management philosophy
Marriott management philosophy
Fawad Akhtar
Andere mochten auch
(19)
Webservices(or)SoapUI Interview Questions
Webservices(or)SoapUI Interview Questions
Testing in-groovy
Testing in-groovy
Groovy Testing
Groovy Testing
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
Testing Web Applications with GEB
Testing Web Applications with GEB
Emc cla rii on fibre channel storage fundamentals
Emc cla rii on fibre channel storage fundamentals
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
1351 anglyskoe slovo_dlya_detey_i_vzroslykh
China high speed railway lines network-201407
China high speed railway lines network-201407
Merkel wiper auas
Merkel wiper auas
Helping Journalists Get It Right
Helping Journalists Get It Right
Solinea Lazuli Tower Project Brief
Solinea Lazuli Tower Project Brief
02មហាគ្រោះជាតិខ្មែរ great danger-khmer-nation-official-khmerlanguage by tie...
02មហាគ្រោះជាតិខ្មែរ great danger-khmer-nation-official-khmerlanguage by tie...
Does Your Stuff Scale?
Does Your Stuff Scale?
Obo mne
Obo mne
Being Miss Geeky - WIT
Being Miss Geeky - WIT
Report abc company draft
Report abc company draft
HAKQ Profile
HAKQ Profile
Effectivnoe upravlenie personalom
Effectivnoe upravlenie personalom
Marriott management philosophy
Marriott management philosophy
Ähnlich wie Groovy Testing Sep2009
Groovy Testing Aug2009
Groovy Testing Aug2009
guest4a266c
How To Make Your Testing More Groovy
How To Make Your Testing More Groovy
Craig Smith
groovy
groovy
Shilong Sang
Groovy.Tutorial
Groovy.Tutorial
Larry Cheng
AJUBY Open Source Application Builder
AJUBY Open Source Application Builder
ajuby
Agile Java Testing With Open Source Frameworks
Agile Java Testing With Open Source Frameworks
Viraf Karai
High-Octane Dev Teams: Three Things You Can Do To Improve Code Quality
High-Octane Dev Teams: Three Things You Can Do To Improve Code Quality
Atlassian
Pivotal Labs Open View Presentation Quality Assurance And Developer Testing
Pivotal Labs Open View Presentation Quality Assurance And Developer Testing
guestc8adce
Javascript Framework Roundup FYB
Javascript Framework Roundup FYB
nukeevry1
Unit Testing in Java
Unit Testing in Java
guy_davis
Peer Code Review: In a Nutshell and The Tantric Team: Getting Your Automated ...
Peer Code Review: In a Nutshell and The Tantric Team: Getting Your Automated ...
Atlassian
Seminar - JBoss Migration
Seminar - JBoss Migration
Xebia IT Architects
Creating Practical Security Test-Cases for Web Applications
Creating Practical Security Test-Cases for Web Applications
Rafal Los
Soa R 7 16 08 Appistry Private Clouds Etc Bob Lozano
Soa R 7 16 08 Appistry Private Clouds Etc Bob Lozano
GovCloud Network
The Maven2 Revolution
The Maven2 Revolution
elliando dias
Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)
Ivo Jansch
Writing Domain-Specific Languages in Groovy
Writing Domain-Specific Languages in Groovy
Guillaume Laforge
Perf Intro Ppt
Perf Intro Ppt
Rahul Sharma
RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009
Roland Tritsch
Model-Based Testing to Help You Enhance Your Agile Testing Process
Model-Based Testing to Help You Enhance Your Agile Testing Process
Frederic Oehl
Ähnlich wie Groovy Testing Sep2009
(20)
Groovy Testing Aug2009
Groovy Testing Aug2009
How To Make Your Testing More Groovy
How To Make Your Testing More Groovy
groovy
groovy
Groovy.Tutorial
Groovy.Tutorial
AJUBY Open Source Application Builder
AJUBY Open Source Application Builder
Agile Java Testing With Open Source Frameworks
Agile Java Testing With Open Source Frameworks
High-Octane Dev Teams: Three Things You Can Do To Improve Code Quality
High-Octane Dev Teams: Three Things You Can Do To Improve Code Quality
Pivotal Labs Open View Presentation Quality Assurance And Developer Testing
Pivotal Labs Open View Presentation Quality Assurance And Developer Testing
Javascript Framework Roundup FYB
Javascript Framework Roundup FYB
Unit Testing in Java
Unit Testing in Java
Peer Code Review: In a Nutshell and The Tantric Team: Getting Your Automated ...
Peer Code Review: In a Nutshell and The Tantric Team: Getting Your Automated ...
Seminar - JBoss Migration
Seminar - JBoss Migration
Creating Practical Security Test-Cases for Web Applications
Creating Practical Security Test-Cases for Web Applications
Soa R 7 16 08 Appistry Private Clouds Etc Bob Lozano
Soa R 7 16 08 Appistry Private Clouds Etc Bob Lozano
The Maven2 Revolution
The Maven2 Revolution
Dynamic Languages In The Enterprise (4developers march 2009)
Dynamic Languages In The Enterprise (4developers march 2009)
Writing Domain-Specific Languages in Groovy
Writing Domain-Specific Languages in Groovy
Perf Intro Ppt
Perf Intro Ppt
RESTful Services and Distributed OSGi - 04/2009
RESTful Services and Distributed OSGi - 04/2009
Model-Based Testing to Help You Enhance Your Agile Testing Process
Model-Based Testing to Help You Enhance Your Agile Testing Process
Mehr von Paul King
awesome groovy
awesome groovy
Paul King
groovy databases
groovy databases
Paul King
groovy transforms
groovy transforms
Paul King
concurrency gpars
concurrency gpars
Paul King
tictactoe groovy
tictactoe groovy
Paul King
groovy rules
groovy rules
Paul King
functional groovy
functional groovy
Paul King
Make Testing Groovy
Make Testing Groovy
Paul King
Agile Testing Practices
Agile Testing Practices
Paul King
groovy DSLs from beginner to expert
groovy DSLs from beginner to expert
Paul King
concurrency with GPars
concurrency with GPars
Paul King
groovy and concurrency
groovy and concurrency
Paul King
GroovyDSLs
GroovyDSLs
Paul King
Atlassian Groovy Plugins
Atlassian Groovy Plugins
Paul King
Dynamic Language Practices
Dynamic Language Practices
Paul King
Make Your Builds More Groovy
Make Your Builds More Groovy
Paul King
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Paul King
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Paul King
XML and Web Services with Groovy
XML and Web Services with Groovy
Paul King
Mehr von Paul King
(19)
awesome groovy
awesome groovy
groovy databases
groovy databases
groovy transforms
groovy transforms
concurrency gpars
concurrency gpars
tictactoe groovy
tictactoe groovy
groovy rules
groovy rules
functional groovy
functional groovy
Make Testing Groovy
Make Testing Groovy
Agile Testing Practices
Agile Testing Practices
groovy DSLs from beginner to expert
groovy DSLs from beginner to expert
concurrency with GPars
concurrency with GPars
groovy and concurrency
groovy and concurrency
GroovyDSLs
GroovyDSLs
Atlassian Groovy Plugins
Atlassian Groovy Plugins
Dynamic Language Practices
Dynamic Language Practices
Make Your Builds More Groovy
Make Your Builds More Groovy
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Craig Smith & Paul King Agile Tool Hacking Taking Your Agile Development ...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
Industrial Strength Groovy - Tools for the Professional Groovy Developer: Pau...
XML and Web Services with Groovy
XML and Web Services with Groovy
Kürzlich hochgeladen
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
Pixlogix Infotech
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
hans926745
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
Antenna Manufacturer Coco
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
apidays
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
V3cube
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 Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
ThousandEyes
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
wesley chun
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
Boston Institute of Analytics
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
Remote DBA Services
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
The Digital Insurer
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
Anna Loughnan Colquhoun
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
hans926745
presentation ICT roal in 21st century education
presentation ICT roal in 21st century education
jfdjdjcjdnsjd
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 2024
Rafal Los
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
Product Anonymous
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
wesley chun
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
sammart93
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
Principled Technologies
Kürzlich hochgeladen
(20)
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
presentation ICT roal in 21st century education
presentation ICT roal in 21st century education
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 2024
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
Groovy Testing Sep2009
1.
How to make
your Testing © ASERT 2006-2009 more Groovy Dr Paul King Craig Smith paulk@asert.com.au craig.smith@suncorp.com.au @paulk_asert @smithcdau ASERT, Australia Suncorp, Australia
2.
Topics
• Why Groovy for Testing? • Groovy Intro • Web Drivers • Test Runners • Non-web Drivers • Other Tools © ASERT 2006-2009 • Going beyond Focus is on using the Groovy dynamic language for primarily functional and acceptance testing with a forward looking perspective. Also considers polyglot options. The techniques and lessons learned can be applied to other kinds of testing and are also applicable to similar languages. AJUG_SEP2009 - 2
3.
Topics not covered
in detail • Coverage – But coverage options available • Mocking – But built-in support and many libraries available • CI Support © ASERT 2006-2009 – Support in Hudson, Team City, Anthill Pro to call Groovy • Code Metrics – CodeNarc and other tools available • Build Tools – Ant, Maven, GMaven, Gant, Gradle, ... AJUG_SEP2009 - 3
4.
Topics
Why Groovy for Testing? • Groovy Intro • Web Drivers – Native Groovy, HttpBuilder, HtmlUnit WebTest, Watij, Selenium, WebDriver, ... • Test Runners © ASERT 2006-2009 – Native Groovy, JUnit, TestNG, Spock, EasyB, JBehave, ... • Non-web Drivers – SOAP/REST, Database, FEST, ... • Other Tools – SoapUI, ITest2, Sahi, JMeter, Twist, ... • Going beyond – Polyglot, Model-driven, Constraint/logic languages, Concurrency AJUG_SEP2009 - 4
5.
Why Test With
Groovy? ? © ASERT 2006-2009 AJUG_SEP2009 - 5
6.
Why Test With
Groovy? • Wrong first question! • Perfect second question? X © ASERT 2006-2009 Consider first the task at hand and the organization and people fit! AJUG_SEP2009 - 6
7.
“People Fit” /
“Organization Fit” • People – Developers (familiarity with languages) – Testers (tools language familiarity) – Responsibility to create/run/maintain – BAs/SMEs (ability to read technical tests) – Consider both development and maintenance © ASERT 2006-2009 – Expected feedback from tests (JUnit/Reports) • Organization – Maturity level – Degree of automation – Tools in use – Need for adaptability AJUG_SEP2009 - 7
8.
Why Test With
Groovy? • Advantages – Easy to learn – Particularly good fit if the application you are testing is built for the JVM or your developers work with Java / JVM languages – Supports polyglot programming when needed © ASERT 2006-2009 – Easy to plug and play different testing tools – Good community & tools for professional agile • Disadvantages – Requires JVM – Less advantages if your developers using Python, .Net, PHP – Maybe your testers already know Ruby AJUG_SEP2009 - 8
9.
Scripting/Dynamic Languages
• Advantages – Lend themselves to succinct code/DSLs – Powerful – Increased Refactoring – Increased Reuse – Less prone to Brittleness © ASERT 2006-2009 – Flexibility for tool integration – Open APIs provide extensibility • Disadvantages – Can be too low level (but many options now) – Sometimes less tool support (but changing now) AJUG_SEP2009 - 9
10.
Test Characteristics
• Coverage/Traceability – Requirement coverage/traceability – Code coverage: line, branch, path, state – Transactional Tracing • Purpose – Unit, Integration, System, Customer • Manageability – Removing duplication © ASERT 2006-2009 – Managing lifecycle: shared setUp/tearDown (@Before @After) • Handling test data – Data-driven, databases, Spreadsheets, tables, keywords, random, model-driven • Large Test Volumes – Speed of feedback, performance testing • Tool evolution/longevity/cost/support/documentation – Open Source/Commercial, Critical mass/popularity • Combinability AJUG_SEP2009 - 10
11.
Key Testing Practices
• Use testing DSL’s • Look to move up the testing stack – It used to be all about the driver – Now the driver is hidden in the framework or tool stack • Apply good testing practices – Pareto analysis, bug clusters, mutation testing, test early © ASERT 2006-2009 – All pairs/equivalence partitions/orthogonal array testing – Risk-based test selection, coding for testability, use CI – Boundary value analysis, defensive programming • Plug and play testing tools – Run different drivers with different runners and different tools • Complement automated tests with exploration • Expand testing scope – Test environment readiness, test deployments AJUG_SEP2009 - 11
12.
Groovy and Testing
Tool Spectrum* Utilities Runners AllPairs, Combinations Native Groovy, JUnit, TestNG, Spock, EasyB, Polyglot languages JBehave, Cucumber, Robot Framework Logic programming Threads, Parallel / Web Database SOAP / Other Concurrency libraries Drivers Drivers REST Drivers Data-driven libraries Drivers Networking libraries WebTest DbUnit FEST © ASERT 2006-2009 XML Processing GroovyWS WebDriver DataSets Email Read/write files / JWebUnit SqlUnit XML-RPC FTP Excel / Word / CSV Reporting, Logging Tellurium groovy.sql CXF AntUnit Selenium JPA Axis2 Telnet HtmlUnit JDO JAX-WS SSH Tools Watij BigTable JAX-RS Exec iTest2, SoapUI, Twist, HttpBuilder JDBC IDEs, JMeter, Text Cyberneko editors, Recorders, Build Tools, CI * Tools/libraries/frameworks don't always neatly fall into one category – still useful conceptually AJUG_SEP2009 - 12
13.
Topics
• Why Groovy for Testing? Groovy Intro • Web Drivers – Native Groovy, HttpBuilder, HtmlUnit WebTest, Watij, Selenium, WebDriver, ... • Test Runners © ASERT 2006-2009 – Native Groovy, JUnit, TestNG, Spock, EasyB, JBehave, ... • Non-web Drivers – SOAP/REST, Database, FEST, ... • Other Tools – SoapUI, ITest2, Sahi, JMeter, Twist, ... • Going beyond – Polyglot, Model-driven, Constraint/logic languages, Concurrency AJUG_SEP2009 - 13
14.
What is Groovy?
• “Groovy is like a super version of Java. It can leverage Java's enterprise capabilities but also has cool productivity features like closures, DSL support, builders and dynamic typing.” © ASERT 2006-2009 Groovy = Java – boiler plate code + optional dynamic typing + closures + domain specific languages + builders + metaprogramming AJUG_SEP2009 - 14
15.
Groovy Goodies Overview
• Fully object oriented • Closures: reusable and assignable pieces of code • Operators can be • GPath: efficient overloaded © ASERT 2006-2009 object navigation • Multimethods • GroovyBeans • Literal declaration for • grep and switch lists (arrays), maps, ranges and regular • Templates, builder, expressions swing, Ant, markup, XML, SQL, XML-RPC, Scriptom, Grails, tests, Mocks AJUG_SEP2009 - 15
16.
Growing Acceptance …
A slow and steady start but now gaining in momentum, maturity and mindshare Making Java Groovy (soon) Now free
17.
… Growing Acceptance
… © ASERT 2006-2009 AJUG_SEP2009 - 17
18.
… Growing Acceptance
… © ASERT 2006-2009 Groovy and Grails downloads: 70-90K per month and growing AJUG_SEP2009 - 18
19.
… Growing Acceptance
… © ASERT 2006-2009 Source: http://www.micropoll.com/akira/mpresult/501697-116746 Source: http://www.grailspodcast.com/ AJUG_SEP2009 - 19
20.
… Growing Acceptance
… © ASERT 2006-2009 http://www.jroller.com/scolebourne/entry/devoxx_2008_whiteboard_votes http://www.java.net AJUG_SEP2009 - 20
21.
… Growing Acceptance
… What alternative JVM language are you using or intending to use © ASERT 2006-2009 http://www.leonardoborges.com/writings AJUG_SEP2009 - 21
22.
… Growing Acceptance
… © ASERT 2006-2009 http://it-republik.de/jaxenter/quickvote/results/1/poll/44 (translated using http://babelfish.yahoo.com) AJUG_SEP2009 - 22
23.
… Growing Acceptance ©
ASERT 2006-2009 AJUG_SEP2009 - 23
24.
The Landscape of
JVM Languages optional static types © ASERT 2006-2009 Dynamic features call for dynamic types Java bytecode calls for static types The terms “Java Virtual Machine” and “JVM” mean a Virtual Machine for the Java™ platform. AJUG_SEP2009 - 24
25.
Groovy Starter
System.out.println("Hello, World!"); // optional semicolon, println 'Hello, World!' // System.out, brackets, // main() method, class defn def name = 'Guillaume' // dynamic typing println "$name, I'll get the car." // GString String longer = """${name}, the car is in the next row.""" // multi-line string © ASERT 2006-2009 // with static typing assert 0.5 == 1/2 // BigDecimal equals() def printSize(obj) { // optional duck typing print obj?.size() // safe dereferencing } def pets = ['ant', 'bee', 'cat'] // native list syntax pets.each { pet -> // closure support assert pet < 'dog' // overloading '<' on String } // or: for (pet in pets)... AJUG_SEP2009 - 25
26.
A Better Java...
import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { This code List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { is valid String s = (String) strings.get(i); Java and if (s.length() <= length) { result.add(s); valid Groovy } } © ASERT 2006-2009 return result; } public static void main(String[] args) { List names = new ArrayList(); names.add("Ted"); names.add("Fred"); names.add("Jed"); names.add("Ned"); System.out.println(names); Based on an Erase e = new Erase(); example by List shortNames = e.removeLongerThan(names, 3); Jim Weirich System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { & Ted Leung String s = (String) shortNames.get(i); System.out.println(s); } } } AJUG_SEP2009 - 26
27.
...A Better Java...
import java.util.List; import java.util.ArrayList; class Erase { private List removeLongerThan(List strings, int length) { Do the List result = new ArrayList(); for (int i = 0; i < strings.size(); i++) { semicolons String s = (String) strings.get(i); add anything? if (s.length() <= length) { result.add(s); And shouldn‟t } } we us more © ASERT 2006-2009 } return result; modern list public static void main(String[] args) { notation? List names = new ArrayList(); names.add("Ted"); names.add("Fred"); Why not names.add("Jed"); names.add("Ned"); System.out.println(names); import common Erase e = new Erase(); libraries? List shortNames = e.removeLongerThan(names, 3); System.out.println(shortNames.size()); for (int i = 0; i < shortNames.size(); i++) { String s = (String) shortNames.get(i); System.out.println(s); } } } AJUG_SEP2009 - 27
28.
...A Better Java...
class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) } } return result } public static void main(String[] args) { © ASERT 2006-2009 List names = new ArrayList() names.add("Ted"); names.add("Fred") names.add("Jed"); names.add("Ned") System.out.println(names) Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) System.out.println(shortNames.size()) for (String s in shortNames) { System.out.println(s) } } } AJUG_SEP2009 - 28
29.
...A Better Java...
class Erase { private List removeLongerThan(List strings, int length) { List result = new ArrayList() for (String s in strings) { if (s.length() <= length) { result.add(s) Do we need } the static types? } return result Must we always } have a main public static void main(String[] args) { method and © ASERT 2006-2009 List names = new ArrayList() names.add("Ted"); names.add("Fred") class definition? names.add("Jed"); names.add("Ned") System.out.println(names) How about Erase e = new Erase() List shortNames = e.removeLongerThan(names, 3) improved System.out.println(shortNames.size()) consistency? for (String s in shortNames) { System.out.println(s) } } } AJUG_SEP2009 - 29
30.
...A Better Java...
def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) } } return result } © ASERT 2006-2009 names = new ArrayList() names.add("Ted") names.add("Fred") names.add("Jed") names.add("Ned") System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } AJUG_SEP2009 - 30
31.
...A Better Java...
def removeLongerThan(strings, length) { def result = new ArrayList() for (s in strings) { if (s.size() <= length) { result.add(s) Shouldn‟t we } } have special return result notation for lists? } And special © ASERT 2006-2009 names = new ArrayList() facilities for names.add("Ted") names.add("Fred") list processing? names.add("Jed") Is „return‟ names.add("Ned") System.out.println(names) needed at end? shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) for (s in shortNames) { System.out.println(s) } AJUG_SEP2009 - 31
32.
...A Better Java...
def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } names = ["Ted", "Fred", "Jed", "Ned"] System.out.println(names) shortNames = removeLongerThan(names, 3) System.out.println(shortNames.size()) shortNames.each{ System.out.println(s) } © ASERT 2006-2009 AJUG_SEP2009 - 32
33.
...A Better Java...
def removeLongerThan(strings, length) { strings.findAll{ it.size() <= length } } Is the method names = ["Ted", "Fred", "Jed", "Ned"] now needed? System.out.println(names) shortNames = removeLongerThan(names, 3) Easier ways to System.out.println(shortNames.size()) use common shortNames.each{ System.out.println(s) } methods? © ASERT 2006-2009 Are brackets required here? AJUG_SEP2009 - 33
34.
...A Better Java...
names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2009 AJUG_SEP2009 - 34
35.
...A Better Java
names = ["Ted", "Fred", "Jed", "Ned"] println names shortNames = names.findAll{ it.size() <= 3 } println shortNames.size() shortNames.each{ println it } © ASERT 2006-2009 ["Ted", "Fred", "Jed", "Ned"] 3 Ted Jed Ned AJUG_SEP2009 - 35
36.
Better Lists, Maps,
Ranges • Lists – Special syntax for list literals – Additional common methods (operator overloading) def list = [3, new Date(), 'Jan'] assert list + list == list * 2 • Maps © ASERT 2006-2009 – Special syntax for map literals – Additional common methods def map = [a: 1, b: 2] assert map['a'] == 1 && map.b == 2 • Ranges – Special syntax for various kinds of ranges def letters = 'a'..'z' def numbers = 0..<10 AJUG_SEP2009 - 36
37.
Closures
• Traditional mainstream languages – Data can be stored in variables, passed around, combined in structured ways to form more complex data; code stays put where it is defined • Languages supporting closures – Data and code can be stored in variables, passed © ASERT 2006-2009 around, combined in structured ways to form more complex algorithms and data doubleNum = { num -> num * 2 } println doubleNum(3) // => 6 processThenPrint = { num, closure -> num = closure(num); println "num is $num" } processThenPrint(3, doubleNum) // => num is 6 processThenPrint(10) { it / 2 } // => num is 5 AJUG_SEP2009 - 37
38.
SwingXBuilder
import groovy.swing.SwingXBuilder © ASERT 2006-2009 import static java.awt.Color.* import static java.lang.Math.* def swing = new SwingXBuilder() def frame = swing.frame(size: [300, 300]) { graph(plots: [ [GREEN, {value -> sin(value)}], [BLUE, {value -> cos(value)}], [RED, {value -> tan(value)}] ]) }.show() AJUG_SEP2009 - 38
39.
Topics
• Why Groovy for Testing? • Groovy Intro Web Drivers – Native Groovy, HttpBuilder, HtmlUnit WebTest, Watij, Selenium, WebDriver Tellurium, JWebUnit © ASERT 2006-2009 • Test Runners – Native Groovy, JUnit, TestNG, Spock, EasyB, JBehave, ... • Non-web Drivers – SOAP/REST, Database, FEST, ... • Other Tools – SoapUI, ITest2, Sahi, JMeter, Twist, ... • Going beyond – Polyglot, Model-driven, Constraint/logic languages, Concurrency AJUG_SEP2009 - 39
40.
Concept
Manual HTTP Request / Response Web Server © ASERT 2006-2009 Automated Driver Runner <webtest name="myTest"> <steps> <invoke description="get Login Page" url="login" /> <verifyTitle description="we should see the login title" text="Login Page" /> Read </steps> HTTP Request / Response </webtest> Script AJUG_SEP2009 - 40
41.
Driver Category
• Real browser invoker • Browser Emulators – Runs on platform – Can simulate multiple supported by real browsers browser – Less platform – May need multiple restrictions platforms, e.g. IE6/IE7 – Good for CI © ASERT 2006-2009 – Uses actual JavaScript – Easier to not download engine images, resources – Can be easier to use – Ability to optimise with test recorders JavaScript interactions – Automation – More extensible capabilities differ – Ability to disable across browsers JavaScript – Can typically get to all – Scope for parallelism aspects of browser AJUG_SEP2009 - 41
42.
Application under Test… ©
ASERT 2006-2009 AJUG_SEP2009 - 42
43.
…Application under Test... ©
ASERT 2006-2009 AJUG_SEP2009 - 43
44.
…Application under Test ©
ASERT 2006-2009 AJUG_SEP2009 - 44
45.
Native Groovy...
• Access URLs • Built-in XML parsing • Built-in friendly regular expression syntax • Even for advanced cases, there is friendly access to low-level things: © ASERT 2006-2009 – Sockets, Processes – Databases and other things – Files • Huge range of Java libraries – PDF – Reading, writing Excel AJUG_SEP2009 - 45
46.
...Native Groovy...
• Useful URL methods def html = new URL('http://localhost:8080').text assert html.contains('<title>Welcome to SimpBlog</title>') © ASERT 2006-2009 html.find(~'<title>(.*)</title>') { all, title -> assert title == 'Welcome to SimpBlog' } • Simple enough for GAE – For public sites – Can share test scripts easily – No setup required AJUG_SEP2009 - 46
47.
...Native Groovy...
• Built-in XML Parsing def page = new XmlSlurper().parse('http://localhost:8080/viewPost?id=1') assert page.body.h1.text().contains('Tis the season') © ASERT 2006-2009 assert page.body.h3[1].text() == 'Category: Home' assert page.body.h3[2].text() == 'Author: Bart' assert page.body.table.tr.td.p.text() == "Aren't we forgeting the true meaning of Christmas? You know, the birth of Santa." AJUG_SEP2009 - 47
48.
...Native Groovy
• Easy access to Java libraries @Grab('nekohtml:nekohtml:1.9.6.2') import org.cyberneko.html.parsers.SAXParser def parser = new XmlSlurper(new SAXParser()) def page = parser.parse('http://localhost:8080/viewPost?id=1') © ASERT 2006-2009 assert page.BODY.H1.text().contains('Tis the season') assert page.BODY.H3[1].text() == 'Category: Home' assert page.BODY.H3[2].text() == 'Author: Bart' assert page.BODY.TABLE.TR.TD.P.text() == "Aren't we forgeting the true meaning of Christmas? You know, the birth of Santa." AJUG_SEP2009 - 48
49.
HttpBuilder
• Builder for Http interactions – Flexible: bogus posts, response codes, JSON, non- HTML @Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC1') import groovyx.net.http.* import static groovyx.net.http.ContentType.URLENC © ASERT 2006-2009 def http = new HTTPBuilder('http://localhost:8080') def postBody = [title:'Bart was here (and so was HttpBuilder)', content:'Cowabunga Dude!', author:'1', category:'3'] http.post(path:'/addPost', body: postBody, requestContentType: URLENC) { resp, html -> assert resp.contentType == 'text/html' assert resp.status == 200 assert html.BODY.H1.text().matches('Post.*: Bart was here.*') assert html.BODY.H3[1].text() == 'Category: Home' assert html.BODY.H3[2].text() == 'Author: Bart' assert html.BODY.TABLE.TR.TD.P.text() == 'Cowabunga Dude!' } AJUG_SEP2009 - 49
50.
HtmlUnit
• 100% Java-based headless browser emulator – Can test any Web site: Java, .Net, PHP, Rails, ... • Open Source – Apache 2 license – Hosted at SourceForge – 7 committers (3 very active) – © ASERT 2006-2009 Very mature • Useful for: – Integration and acceptance testing – Screen scraping, deployment automation, ... • Used by other drivers: – Canoo WebTest , JWebUnit , WebDriver , JSFUnit , Celerity • Special features: – Easy ajax mode, emulation of multiple browsers AJUG_SEP2009 - 50
51.
HtmlUnit Features...
• Support for the HTTP and HTTPS protocols • Support for cookies • Ability to specify whether failing responses from the server should throw exceptions or should be returned as "error" pages • Support for submit methods POST and GET © ASERT 2006-2009 – As well as HEAD, DELETE, ... • Ability to customize the request headers being sent to the server • Support for HTML responses – Wrapper for HTML pages that provides easy access to all information contained inside them – Support for submitting forms and clicking links – Support for walking the DOM model of HTML documents AJUG_SEP2009 - 51
52.
...HtmlUnit Features
• Proxy server support • Support for basic and NTLM authentication • Excellent JavaScript support – jQuery 1.2.6: Full support – MochiKit 1.4.1: Full support – GWT 1.6.4: Full support © ASERT 2006-2009 – Sarissa 0.9.9.3: Full support – MooTools 1.2.1: Full support – Prototype 1.6.0: Very good support – Ext JS 2.2: Very good support – Dojo 1.0.2: Good support – YUI 2.3.0: Good support AJUG_SEP2009 - 52
53.
HtmlUnit: Testing New
Blog Post... @Grab('net.sourceforge.htmlunit:htmlunit:2.6') import com.gargoylesoftware.htmlunit.WebClient def client = new WebClient() def page = client.getPage('http://localhost:8080/postForm') // check page title assert 'Welcome to SimpBlog' == page.titleText © ASERT 2006-2009 // fill in blog entry and post it def form = page.getFormByName('post') form.getInputByName('title'). setValueAttribute('Bart was here (and so was HtmlUnit)') form.getSelectByName('category').getOptions().find{ it.text == 'Home' }.setSelected(true) form.getTextAreaByName('content').setText('Cowabunga Dude!') def result = form.getInputByName('btnPost').click() ... AJUG_SEP2009 - 53
54.
...HtmlUnit: Testing New
Blog Post ... // check blog post details assert result.getElementsByTagName('h1').item(0). textContent.matches('Post.*: Bart was here.*') def h3headings = result.getElementsByTagName('h3') © ASERT 2006-2009 assert h3headings.item(1).textContent == 'Category: Home' assert h3headings.item(2).textContent == 'Author: Bart' // expecting: // <table><tr><td><p>Cowabunga Dude!</p></td></tr></table> def cell = result.getByXPath('//TABLE//TR/TD')[0] def para = cell.getFirstChild() assert para.textContent == 'Cowabunga Dude!' AJUG_SEP2009 - 54
55.
Canoo WebTest
• Description – Open source tool for automated testing of web applications – Declarative approach in XML or testing DSL in Groovy – Has Test Recorder – Excellent reporting options – Ant-based under the covers <target name="login" > <testSpec name="normal" > © ASERT 2006-2009 &config; <steps> <invoke stepid="get Login Page" url="login.jsp" /> <verifytitle stepid="we should see the login title" text="Login Page" /> <setinputfield stepid="set user name" name="username" value="scott" /> <setinputfield stepid="set password" name="password" value="tiger" /> <clickbutton stepid="Click the submit button" label="let me in" /> <verifytitle stepid="Home Page follows if login ok" text="Home Page" /> </steps> </testSpec> </target> AJUG_SEP2009 - 55
56.
Canoo WebTest Features
• Strongly encourages declarative testing – Supports testing DSLs, test structuring and reuse through macrodefs and imports for XML flavor & methods and closures for Groovy flavor • Extensive support for HTML pages – Including JavaScript • Also supports other MIME types © ASERT 2006-2009 – Generically as binary streams – Special support for PDF, Excel, Emails • Ant heritage provides easy IDE/CI hooks • Excellent Documentation • Excellent Community • Eats own dog food – high quality codebase AJUG_SEP2009 - 56
57.
Canoo WebTest Steps... ©
ASERT 2006-2009 AJUG_SEP2009 - 57
58.
...Canoo WebTest Steps... ©
ASERT 2006-2009 AJUG_SEP2009 - 58
59.
...Canoo WebTest Steps... ©
ASERT 2006-2009 AJUG_SEP2009 - 59
60.
...Canoo WebTest Steps ©
ASERT 2006-2009 AJUG_SEP2009 - 60
61.
WebTest: Testing New
Blog Post... <webtest name="Testing Posting a new Blog Entry"> <invoke url="http://localhost:8080/" description="Home Page"/> <verifyTitle text="Welcome to SimpBlog"/> <group description="Post New Blog Entry"> <clickLink label="New Blog Entry"/> © ASERT 2006-2009 <setInputField name="title" value="Bart was here (and so was WebTest)"/> <setSelectField name="category" text="School"/> <setInputField name="content" value="Cowabunga Dude!"/> <clickButton name="btnPost"/> </group> ... AJUG_SEP2009 - 61
62.
...WebTest: Testing New
Blog Post... ... <group description="Check Blog Post"> <verifyElementText type="h1" regex="true" text="Post.*: Bart was here.*"/> <verifyXPath xpath="//h3[2]/text()" text="Category: School"/> © ASERT 2006-2009 <verifyXPath xpath="//h3[3]/text()" text="Author: Bart"/> <verifyElementText type="p" text="Cowabunga Dude!"/> </group> <groovy> println "Test run at: ${new Date()}" </groovy> </webtest> AJUG_SEP2009 - 62
63.
...WebTest: Testing New
Blog Post... ant.webtest(name: 'Test SimpBlog') { invoke url: "http://localhost:8080/", description: "Home Page" verifyTitle text: "Welcome to SimpBlog" group description: "Post New Blog Entry", { clickLink label: "New Blog Entry" setInputField name: "title", value: "Bart was here (and so was WebTest with Groovy)" setSelectField name: "category", text: "School" © ASERT 2006-2009 setInputField name: "content", value: "Cowabunga Dude!" clickButton name: "btnPost" } group description: "Check Blog Post", { verifyElementText type: "h1", regex: "true", text: "Post.*: Bart was here.*" verifyXPath xpath: "//h3[2]/text()", text: "Category: School" verifyXPath xpath: "//h3[3]/text()", text: "Author: Bart" verifyElementText type: "p", text: "Cowabunga Dude!" } } AJUG_SEP2009 - 63
64.
...WebTest: Testing New
Blog Post... © ASERT 2006-2009 AJUG_SEP2009 - 64
65.
...WebTest: Testing New
Blog Post © ASERT 2006-2009 AJUG_SEP2009 - 65
66.
Firefox Recorder © ASERT
2006-2009 AJUG_SEP2009 - 66
67.
Watij
• Description – Java API that provides control and automation of Internet Explorer – Supports actions like navigating, clicking links, filling out forms, etc. – Also supports more complex actions like file © ASERT 2006-2009 downloading and uploading, popup windows and dialogs, and screen captures • Special Features – Ability to work with IE interactively – Can attach to an existing browser session – Special browser commands, e.g. ie.fullScreen(true) – Handles child browsers and popup dialogs AJUG_SEP2009 - 67
68.
Watij Features
• Finders – tag(String tagName) – attribute(String name, String value) – index(int index) – text(String text) – name(String value) – value(String value) © ASERT 2006-2009 – caption(String value) – id(String value) – title(String value) – alt(String value) – src(String value) – action(String value) – method(String value) – url(String value) – href(String value) – xpath(String expression) AJUG_SEP2009 - 68
69.
Watij: Testing New
Blog Post... import watij.runtime.ie.IE import static watij.finders.SymbolFactory.* import static watij.finders.FinderFactory.* def ie = new IE() ie.start('http://localhost:8080/postForm') // check page title © ASERT 2006-2009 assert ie.title() == 'Welcome to SimpBlog' // fill in query form and submit it ie.textField(name, 'title'). set('Bart was here (and so was Watij)') ie.textField(name, 'content').set('Cowabunga dude!') ie.selectList(name, "category"). option(text, "Home").select() ie.button(name, 'btnPost').click() ... AJUG_SEP2009 - 69
70.
...Watij: Testing New
Blog Post... ... // check entered post is being displayed assert ie.htmlElement(tag, 'H1').text(). matches('Post.*: Bart was here.*') def h3headers = ie.htmlElements(tag, 'H3') © ASERT 2006-2009 assert h3headers.get(1).text() == 'Category: Home' assert h3headers.get(2).text() == 'Author: Bart' // try a more advanced finder // content is at: //TABLE/TBODY/TR/TD/P def row = ie.htmlElement(xpath('//TABLE/TBODY/TR')) assert row.cell(0).htmlElement(tag, 'P').text() == 'Cowabunga dude!' ie.close() AJUG_SEP2009 - 70
71.
...Watij: Testing New
Blog Post © ASERT 2006-2009 AJUG_SEP2009 - 71
72.
Selenium...
• Description – Tools to help automate testing for web-based applications – Support for © ASERT 2006-2009 running tests on multiple browser platforms • Components – Selenium Core – Selenium IDE Selenium RC Our focus – Selenium Grid Source: http://seleniumhq.org/projects/remote-control/ AJUG_SEP2009 - 72
73.
...Selenium © ASERT 2006-2009
Source: http://seleniumhq.org/docs/01_introducing_selenium.html AJUG_SEP2009 - 73
74.
Selenium: Testing New
Blog Post... import com.thoughtworks.selenium.DefaultSelenium import org.openqa.selenium.server.SeleniumServer // start auxiliary server def server = new SeleniumServer() server.start() // uncomment one of below //def browser = "*iexplore" © ASERT 2006-2009 //def browser = "*firefox3" // if Firefox already in your path //def browser = "*firefox3 C:/Program Files/Mozilla Firefox/firefox.exe" def browser = "*firefox3 C:/Program Files (x86)/Mozilla Firefox/firefox.exe" def selenium = new DefaultSelenium("localhost", 4444, browser, "http://localhost:8080") selenium.start() ... AJUG_SEP2009 - 74
75.
...Selenium: Testing New
Blog Post ... // post blog selenium.open "/postForm" selenium.type "title", "Bart was here (and so was Selenium)" selenium.select "category", "Home" selenium.type "content", "Cowabunga Dude!" selenium.click "btnPost" © ASERT 2006-2009 selenium.waitForPageToLoad "5000" // checks assert selenium.isTextPresent('regex:Post.*: Bart was here') assert selenium.isElementPresent('//h3[text()="Author: Bart"]') assert selenium.isElementPresent('//h3[text()="Category: Home"]') assert selenium.isElementPresent( '//table//tr/td/p[text()="Cowabunga Dude!"]') selenium.stop() server.stop() AJUG_SEP2009 - 75
76.
Selenium IDE...
Features: • Easy record and playback © ASERT 2006-2009 • Intelligent field selection will use IDs, names, or XPath as needed • Autocomplete for all common Selenium commands • Walk through tests • Debug and set breakpoints • Save tests as HTML, Ruby scripts, or any other format • Support for Selenium user- extensions.js file • Option to automatically assert the title of every page AJUG_SEP2009 - 76
77.
...Selenium IDE © ASERT
2006-2009 more info: http://limcheekin.blogspot.com/2009/07/behavior-driven-development-generating.html AJUG_SEP2009 - 77
78.
Selenium Other Tools... ©
ASERT 2006-2009 AJUG_SEP2009 - 78
79.
...Selenium Other Tools... ©
ASERT 2006-2009 AJUG_SEP2009 - 79
80.
...Selenium Other Tools ©
ASERT 2006-2009 Source: http://selenium-grid.seleniumhq.org/how_it_works.html AJUG_SEP2009 - 80
81.
WebDriver
• Description – Simple API to drive both real browsers • for testing javascript heavy apps – and a pure 'in memory' emulator solution • for faster testing of simpler apps • uses HtmlUnit under the covers in emulator mode © ASERT 2006-2009 – Represents next generation of Selenium RC • though merging into Selenium may happen under the covers if you are a Selenium user – Roadmap has plans to leverage some advanced Selenium like features • RemoteWebDriver • FarmedWebDriver (think Selenium Grid) AJUG_SEP2009 - 81
82.
WebDriver: Testing New
Blog Post... import org.openqa.selenium.By import org.openqa.selenium.htmlunit.HtmlUnitDriver def driver = new HtmlUnitDriver() driver.get('http://localhost:8080/postForm') assert driver.title == 'Welcome to SimpBlog' // fill in query form and submit it © ASERT 2006-2009 driver.findElement(By.name('title')). sendKeys('Bart was here (and so was WebDriver)') driver.findElement(By.name('content')). sendKeys('Cowabunga dude!') def select = driver.findElement(By.name('category')) select.findElements(By.tagName("option")).find{ it.text == 'Home' }.setSelected() driver.findElement(By.name('btnPost')).click() ... AJUG_SEP2009 - 82
83.
...WebDriver: Testing New
Blog Post ... assert driver.findElement(By.tagName("h1")).text. matches('Post.*: Bart was here.*') def h3headers = driver.findElements(By.tagName("h3")) assert h3headers[1].text == 'Category: Home' © ASERT 2006-2009 assert h3headers[2].text == 'Author: Bart' // try a more advanced finder // content is at: //TABLE/TBODY/TR/TD/P def row = driver.findElement(By.xpath("//table/tbody/tr")) def col = row.findElement(By.tagName("td")) def para = col.findElement(By.tagName("p")) assert para.text == 'Cowabunga dude!' AJUG_SEP2009 - 83
84.
Tellurium
• Description – built on top of Selenium but tries to solve several shortcomings – "record and reply" style, difficult to refactor and maintain, so instead define UI components declaratively then write tests in terms of UI © ASERT 2006-2009 – Provides many predefined UI objects for you to use directly, such as Button, CheckBox, InputBox, Selector, TextBox, and Table but also ability to write your own custom UI objects – Supports advanced locating mechanisms: composite locator, "group locating" – Supports testing DSL – Supports data-driven tests AJUG_SEP2009 - 84
85.
Architecture © ASERT 2006-2009
Source: http://code.google.com/p/aost/wiki/Introduction AJUG_SEP2009 - 85
86.
Tellurium Example
• Selenium: selenium.type("//input[@title='Google Search']", input) selenium.click("//input[@name='btnG' and @type='submit']") • Tellurium UI: ui.Container(uid: "google_start_page", © ASERT 2006-2009 clocator: [tag: "td"], group: "true") { InputBox(uid: "searchbox", clocator: [title: "Google Search"]) SubmitButton(uid: "googlesearch", clocator: [name: "btnG", value: "Google Search"]) } • Tellurium DSL Test: type "google_start_page.searchbox", input click "google_start_page.googlesearch" AJUG_SEP2009 - 86
87.
Tellurium: Testing New
Blog Post... ui.UrlLink(uid: "create_new_post", clocator: [tag:'a', text: "New Blog Entry"]) ui.Form(uid: "blogform", clocator: [tag: 'form', name:'post'], group: "true") { InputBox(uid: "title", clocator: [name: "title"]) InputBox(uid: "content", clocator: [tag:'textarea', name: "content"]) Selector(uid: "category", clocator: [name: "category"]) Selector(uid: "author", clocator: [name: "author"]) © ASERT 2006-2009 SubmitButton(uid: "post_button", clocator: [name: 'btnPost', value: "Create Post"]) } ui.TextBox(uid: 'main_header', clocator: [tag: 'h1']) ui.TextBox(uid: 'category_header', clocator: [tag: 'h3', position: '2']) ui.TextBox(uid: 'author_header', clocator: [tag: 'h3', position: '3']) ui.Container(uid: 'table', clocator: [tag: 'table']) { ui.TextBox(uid: 'content_para', locator: '//tr/td/p') } AJUG_SEP2009 - 87
88.
...Tellurium: Testing New
Blog Post openUrl "http://localhost:8080/" click "create_new_post" waitForPageToLoad 5000 assert title == 'Welcome to SimpBlog' // post blog type "blogform.title", "Bart was here (and so was Tellurium)" selectByLabel "blogform.category", "Home" © ASERT 2006-2009 selectByLabel "blogform.author", "Bart" type "blogform.content", "Cowabunga Dude!" click "blogform.post_button" waitForPageToLoad 5000 // check contents assert getText('main_header').matches('Post.*: Bart was here.*') assert getText('category_header') == 'Category: Home' assert getText('author_header') == 'Author: Bart' assert getText('table.content_para') == 'Cowabunga Dude!' shutDown AJUG_SEP2009 - 88
89.
TrUMP IDE © ASERT
2006-2009 AJUG_SEP2009 - 89
90.
JWebUnit...
• Description – Java-based testing framework for web applications – Intention is to provide a high-level "driver" Java API – Wraps existing testing frameworks such as HtmlUnit and Selenium with a unified, simple testing interface – Support includes navigation via links, form entry and © ASERT 2006-2009 submission, validation of table contents, and other verification steps – Includes some runner capabilities – Useful in that it allows you to switch between different lower level drivers without re-writing your tests AJUG_SEP2009 - 90
91.
...JWebUnit © ASERT 2006-2009
Source: http://jwebunit.sourceforge.net/ AJUG_SEP2009 - 91
92.
JWebUnit: Testing New
Blog Post import net.sourceforge.jwebunit.junit.* class TestSimpBlog extends WebTestCase { void setUp() { setBaseUrl("http://localhost:8080") } void testPostBlog() { beginAt "/postForm" assertTitleEquals "Welcome to SimpBlog" setTextField "title", "Bart was here (and so was JWebUnit)" © ASERT 2006-2009 setTextField "content", "Cowabunga Dude!" selectOption "category", "Home" clickButtonWithText "Create Post" assert getElementByXPath('//H1').textContent. matches('Post.*: Bart was here.*') def h3headings = getElementsByXPath('//H3') assert h3headings[1].textContent == "Category: Home" assert h3headings[2].textContent == "Author: Bart" def cell = getElementByXPath('//TABLE//TR/TD') assert cell.children[0].textContent == 'Cowabunga Dude!' } } AJUG_SEP2009 - 92
93.
Topics
• Why Groovy for Testing? • Groovy Intro • Web Drivers – Native Groovy, HttpBuilder, HtmlUnit WebTest, Watij, Selenium, WebDriver, ... Test Runners © ASERT 2006-2009 – Native Groovy, JUnit, TestNG, Spock, EasyB, JBehave, Cucumber, Robot Framework, FitNesse/Slim • Non-web Drivers – SOAP/REST, Database, FEST, ... • Other Tools – SoapUI, ITest2, Sahi, JMeter, Twist, ... • Going beyond – Polyglot, Model-driven, Constraint/logic languages, Concurrency AJUG_SEP2009 - 93
94.
Native Groovy
• Groovy has a friendly ‘==‘ • Built-in assert • Scripts are low ceremony • By utilising @Grab are easy to share • Many in-built testing capabilities are © ASERT 2006-2009 accessible even from scripts • Easy to version control or treat like operating system scripts • Out of the box detection of JUnit and TestNG tests AJUG_SEP2009 - 94
95.
Built-in JUnit 3...
• Groovy distributions up to 1.6.X include JUnit 3 • Automatically invokes text runner • Example uses HtmlUnit driver class TestSimpBlogJUnit extends TestCase { def page void setUp() { © ASERT 2006-2009 page = new WebClient().getPage('http://localhost:8080/postForm') assert 'Welcome to SimpBlog' == page.titleText } void testBartWasHere() { // fill in blog entry and post it def form = page.getFormByName('post') form.getInputByName('title').setValueAttribute('Bart was here (and form.getSelectByName('category').getOptions().find { it.text == 'H form.getTextAreaByName('content').setText('Cowabunga Dude!') def result = form.getInputByName('btnPost').click() ... AJUG_SEP2009 - 95
96.
...Built-in JUnit 3...
... def form = page.getFormByName('post') form.getInputByName('title').setValueAttribute( 'Bart was here (and so was HtmlUnit)') form.getSelectByName('category').getOptions().find { it.text == 'Home' }.setSelected(true) form.getTextAreaByName('content').setText('Cowabunga Dude!') def result = form.getInputByName('btnPost').click() // check blog post details © ASERT 2006-2009 assert result.getElementsByTagName('h1').item(0). textContent.matches('Post.*: Bart was here.*') def h3headings = result.getElementsByTagName('h3') assert h3headings.item(1).textContent == 'Category: Home' assert h3headings.item(2).textContent == 'Author: Bart' // expecting: <table><tr><td><p>Cowabunga Dude!</p></td></tr></tab def cell = result.getByXPath('//TABLE//TR/TD')[0] def para = cell.getFirstChild() assert para.textContent == 'Cowabunga Dude!' } } AJUG_SEP2009 - 96
97.
...Built-in JUnit 3 ©
ASERT 2006-2009 AJUG_SEP2009 - 97
98.
GroovyTestCase Tests
• Like JUnit but with some enhancements – Additional assert methods – fewer imports – clean shouldFail syntax class TestSimpBlogGUnit extends GroovyTestCase { © ASERT 2006-2009 def page void setUp() { // ... } void testBartWasHere() { // ... ... AJUG_SEP2009 - 98
99.
JUnit 4.X
• Groovy distributions from 1.7 include JUnit 4 • Automatically invokes text runner if needed • Example uses HtmlUnit driver (not shown) import org.junit.* class TestSimpBlogJUnit4 { © ASERT 2006-2009 def page @Before void setUp() { // ... } @Test void bartWasHere() { // ... AJUG_SEP2009 - 99
100.
JUnit 4.X Parameterized
Tests @RunWith(Parameterized) class TestSimpBlogJUnit4DD { def page, author, title, category, content TestSimpBlogJUnit4DD(author, title, category, content) { this.author = author this.title = title © ASERT 2006-2009 this.category = category this.content = content } @Parameters static data() { return [ ['Bart', 'Title 1', 'Home', 'Content 1'], ['Homer', 'Title 2', 'Work', 'Content 2'], ['Marge', 'Title 3', 'Food', 'Content 3'] ].collect{ it as String[] } } ... AJUG_SEP2009 - 100
101.
TestNG
• Groovy automatically invokes text runner if run as a script • Example shows grouping, driver not shown import org.testng.annotations.* class TestSimpBlogTestNG { © ASERT 2006-2009 def page @BeforeClass void setUp() { // ... } @Test(groups = [ "slow" ]) void bartWasHere() { // ... AJUG_SEP2009 - 101
102.
TestNG Data Driven
import org.testng.annotations.* class TestSimpBlogTestNGDD { // ... @DataProvider(name='SimpBlogDataProvider') Object[][] data() { © ASERT 2006-2009 return [ ['Bart', 'Title 1', 'Home', 'Content 1'], ['Homer', 'Title 2', 'Work', 'Content 2'], ['Marge', 'Title 3', 'Food', 'Content 3'] ].collect{ it as Object[] } as Object[] } @Test(dataProvider = "SimpBlogDataProvider") void bartWasHere(author, title, category, content) { // ... AJUG_SEP2009 - 102
103.
Spock Testing Framework... ©
ASERT 2006-2009 AJUG_SEP2009 - 103
104.
...Spock Testing Framework
• Testing framework for Java and Groovy • Highly expressive specification language – No assertion API – No record & replay @Speck mocking API @RunWith(Sputnik) – No class PublisherSubscriberSpeck { superfluous def "events are received by all subscribers"() { © ASERT 2006-2009 annotations def pub = new Publisher() – Meaningful def sub1 = Mock(Subscriber) assert error def sub2 = Mock(Subscriber) messages pub.subscribers << sub1 << sub2 when: pub.send("event") then: – Extensible 1 * sub1.receive("event") – Compatible 1 * sub2.receive("event") with JUnit } reportingwise } AJUG_SEP2009 - 104
105.
Spock Example...
import com.gargoylesoftware.htmlunit.WebClient import spock.lang.* import org.junit.runner.RunWith @Speck () @RunWith (Sputnik) class TestSimpBlogSpock { def page, subheadings, para, form, result @Unroll("When #author posts a #category blog with content '#content' it shoul © ASERT 2006-2009 def "when creating a new blog entry"() { given: page = new WebClient().getPage('http://localhost:8080/postForm') form = page.getFormByName('post') when: form.getInputByName('title').setValueAttribute("$author was here (and so form.getSelectByName('category').getOptions().find { it.text == category form.getSelectByName('author').getOptions().find { it.text == author }.se form.getTextAreaByName('content').setText(content) result = form.getInputByName('btnPost').click() subheadings = result.getElementsByTagName('h3') para = result.getByXPath('//TABLE//TR/TD/P')[0] ... AJUG_SEP2009 - 105
106.
...Spock Example
... then: page.titleText == 'Welcome to SimpBlog' result.getElementsByTagName('h1').item(0).textContent.matches("Post.*: $auth subheadings.item(1).textContent == "Category: $category" subheadings.item(2).textContent == "Author: $author" and: // Optional use of 'and:' para.textContent == content © ASERT 2006-2009 where: author << ['Bart', 'Homer', 'Lisa'] category << ['Home', 'Work', 'Food'] content << ['foo', 'bar', 'baz'] } } AJUG_SEP2009 - 106
107.
EasyB
• Description: BDD, Rspec-like testing library narrative 'segment flown', { as_a 'frequent flyer' i_want 'to accrue rewards points for every segment I fly' so_that 'I can receive free flights for my dedication to the airline' } scenario 'segment flown', { given 'a frequent flyer with a rewards balance of 1500 points' © ASERT 2006-2009 when 'that flyer completes a segment worth 500 points' then 'that flyer has a new rewards balance of 2000 points' } scenario 'segment flown', { given 'a frequent flyer with a rewards balance of 1500 points', { flyer = new FrequentFlyer(1500) } when 'that flyer completes a segment worth 500 points', { flyer.fly(new Segment(500)) } then 'that flyer has a new rewards balance of 2000 points', { flyer.pointsBalance.shouldBe 2000 } } AJUG_SEP2009 - 107
108.
EasyB Example ...
• When run will be marked as pending – perfect for ATDD scenario "Bart posts a new blog entry", { given "we are on the create blog entry page" when "I have entered 'Bart was here' as the title" and "I have entered 'Cowabunga Dude!' into the content" and "I have selected 'Home' as the category" © ASERT 2006-2009 and "I have selected 'Bart' as the author" and "I click the 'Create Post' button" then "I expect the entry to be posted" } AJUG_SEP2009 - 108
109.
...EasyB Example...
description "Post Blog Entry Feature" narrative "for feature", { as_a "Blogger" i_want "to be able to post a blog" so_that "I can keep others informed" } before "posting blog", { given "we are on the create blog entry page", { © ASERT 2006-2009 webClient = new com.gargoylesoftware.htmlunit.WebClient() page = webClient.getPage('http://localhost:8080/postForm') } } scenario "Bart was here blog", { when "I have entered 'Bart was here' as the title", { form = page.getFormByName('post') form.getInputByName('title').setValueAttribute( 'Bart was here (and so was EasyB)') } ... AJUG_SEP2009 - 109
110.
...EasyB Example...
... and "I have entered 'Cowabunga Dude!' into the content", { form.getTextAreaByName('content').setText('Cowabunga Dude!') } and "I have selected 'Home' as the category", { form.getSelectByName('category').getOptions().find { it.text == 'Home' }.setSelected( } and "I click the 'Create Post' button", { result = form.getInputByName('btnPost').click() } © ASERT 2006-2009 then "I expect the entry to be posted", { // check blog post details assert result.getElementsByTagName('h1').item(0).textContent.matches('Post.*: Bart wa def h3headings = result.getElementsByTagName('h3') assert h3headings.item(1).textContent == 'Category: Home' // traditional style h3headings.item(2).textContent.shouldBe 'Author: Bart' // BDD style // expecting: <table><tr><td><p>Cowabunga Dude!</p></td></tr></table> def cell = result.getByXPath('//TABLE//TR/TD')[0] def para = cell.firstChild assert para.textContent == 'Cowabunga Dude!' // para.shouldHave textContent: 'Cowabunga Dude!' } } AJUG_SEP2009 - 110
111.
...EasyB Example... © ASERT
2006-2009 AJUG_SEP2009 - 111
112.
...EasyB Example
2 scenarios (including 1 pending) executed successfully. Story: simp blog initial scenario Bart posts a new blog entry [PENDING] given we are on the create blog entry page when I have entered 'Bart was here' as the title when I have entered 'Cowabunga Dude!' into the content [PENDING] when I have selected 'Home' as the category [PENDING] when I have selected 'Bart' as the author [PENDING] when I click the 'Create Post' button [PENDING] then I expect the entry to be posted [PENDING] Story: simp blog easyb is preparing to process 2 file(s) © ASERT 2006-2009 Post Blog Entry Feature Running simp blog initial story (SimpBlogInitialStory.groovy) for feature Scenarios run: 1, Failures: 0, Pending: 1, Time elapsed: 1.049 sec As a Blogger Running simp blog story (SimpBlogStory.groovy) I want to be able to post a blog Scenarios run: 1, Failures: 0, Pending: 0, Time elapsed: 1.356 sec So that I can keep others informed given we are on the create blog entry page 2 total behaviors ran (including 1 pending behavior) with no failures easyb execution passed scenario Bart was here blog when I have entered 'Bart was here' as the title when I have entered 'Cowabunga Dude!' into the content when I have selected 'Home' as the category when I click the 'Create Post' button then I expect the entry to be posted AJUG_SEP2009 - 112
113.
Cucumber
# language: en • Description Feature: Addition In order to avoid silly mistakes – Loose coupling As a math idiot between text spec I want to be told the sum of two numbers and step defns Scenario Outline: Add two numbers Given I have entered <input_1> into the calculator And I have entered <input_2> into the calculator When I press <button> Then the stored result should be <output> Examples: © ASERT 2006-2009 | input_1 | input_2 | button | output | | 20 | 30 | add | 50 | | 2 | 5 | add | 7 | | 0 | 40 | add | 40 | # language: en Feature: Division In order to avoid silly mistakes Cashiers must be able to calculate a fraction Scenario: Regular numbers Given I have entered 3 into the calculator And I have entered 2 into the calculator When I press divide Then the stored result should be 1.5 AJUG_SEP2009 - 113
Jetzt herunterladen