SlideShare a Scribd company logo
Grails 1.1 TestingTech Talk @ 2PathsJuly 17, 2009By Dave Koo©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
AgendaUnit TestingIntegration TestingFunctional TestingPutting It All Together©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing - Overviewunit tests enable testing small bits of code in isolationGrails does NOT inject any surrounding infrastructure (ie. no dynamic GORM methods, database, Spring resources, bootstrap, ServletContext, etc)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing - Benefitsfind problems sooner -> you can test your code before all it's dependencies are created/availableenables safer refactoring (of individual classes)faster to run than integration & functional teststhere isn't a big speed gap early in the project (PLAID: unit ~ 10s, integration ~ 30)but it grows as the system gets biggermakes TDD less painful -> breaks problem into smaller piecesprovides form of API documentation & spec©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing - Drawbacksmore code to maintain & debug -> often as buggy as code under test (if written by same person :)sometimes you have to mock a LOT of stuff before you can write your little testdoesn't catch bugs at the integration or UI layers -> can create false sense of security©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – GrailsUnitTestCaseOverviewextends GroovyTestCase to add Grails-specific mocking and make testing more convenient for Grails usersmocking is test-specific and doesn't leak from one test to anotheravoids having to do a lot of MetaClass hacking (and forgetting to teardown your metaclass hacking :)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – GrailsUnitTestCasemethodsmockFor(class, loose = false)mockDomain(class, testInstances[ ])mockForConstraintsTests(class, testInstances[ ])mockLogging(class, enableDebug = false)Code samples: http://grails.org/doc/1.1.1/guide/9.%20Testing.html#9.1%20Unit%20Testing©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – GrailsUnitTestCasemockFor(class, loose = false)generic mocker for mocking methods of any classreturns a control object (not the actual mock)loose - false == strict mocking (sequence of expected method calls matters), true == loose (sequence doesn't matter)methods - you can mock instance or static methodsdemands - your expectations of the mockrange - number of times a method is expected to be called (default === 1)closure - mock implementation of the methodstrictControl.createMock() - returns an actual mock objectstrictControl.verify() - verifies that all demands were actually met©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – GrailsUnitTestCasemockDomain(class, testInstances[ ])mocks all methods (instance, static & dynamic) on a domain classtestInstances- a list of domain class instances which replaces and acts as the "database”you can call save(), findBy*(), validate(), etc on an instance of a mocked domain classinheritance can be tricky!assume you have ParentClass, ChildA, ChildBif you mock ParentClass and pass a collection of instances containing ChildA and/or ChildB objects to the MockDomain() method, you must ensure that you have already mocked each type of ChildX class in the instance collection. This is needed even if you NEVER call a dynamic method on any child class (such as ChildClass.list()).always mock a child class BEFORE mocking its parent, otherwise you may get "Method Not Found" exceptions when calling dynamic methods on the childnew addition to Grailsstill some bugs / missing featurescheck Grails' JIRA & mailing lists if experiencing wierdbehaviour©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – GrailsUnitTestCaseother methods…mockForConstraintsTests(class, testInstances[ ])Stripped-down version of mockDomain that allows for assertions to validate domain class constraintsTakes the pain out of testing domain class constraintsmockLogging(class, enableDebug = false)Adds a mock "log" property to a class. Any messages passed to the mock logger are echoed to the console.©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – ControllerUnitTestCaseextends GrailsUnitTestCase to add mocks for:all dynamic properties & methods Grails injects into controllers (render, redirect, model, etc)all HTTP objects available to controllers (request, response, session, params, flash, etc)command object (if needed)provides an implicit "controller" property which contains all the above mocks (no need to def the controller yourself in your test class)don't forget to mock your Domain objects as needed if the controller action you call expects a database©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Unit Testing – Other Unit TestsTagLibUnitTestCaseextends GrailsUnitTestCase to add mocks for dynamic properties & methods a TagLibexpectsdbUnitextends jUnit to allow you to test that your DB is in the expected stateprevents subsequent tests from failing due to a previous test leaving the database "dirty"©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Integration Testing - Overviewused to test that an entire module or sub-system consisting of multiple classes is working correctly (in isolation)one level below a functional test as integration tests do not test the entire stackGrails injects all the surrounding infrastructure such as data sources & Spring beanspretty straightforward to implement since there's generally no mocking involvedwhere to use integration tests??? we'll come back to this in a few mins :)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Integration Testing - Benefitstests the real interactions between individual piecesfinds more complex bugs that unit tests can't findfaster to run than functional tests (usually)makes large-scale refactoring saferfind bugs sooner -> doesn't require other system modules to be built©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Integration Testing - Drawbacksperhaps overused by lazy testers who don't feel like mocking :)requires more code to be written than unit testsdoesn't find system-level or inter-module bugsvalue is debatable if you have good functional tests & good unit tests.©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing - Overviewused to test functionality from an end user's perspective across all layers of the system©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing - Benefitsfinds complex system-level and inter-module bugsfinds UI bugscan be written by non-techies (depends on tool used)provides "done when" acceptance criteria for the customerprovides a form of user documentationmakes large-scale refactoring safer©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing - Drawbacksvery slow to execute HTTP level testsoften more cumbersome to write than other types of testsoften brittle and can require a lot of maintenance (especially if tied to UI)Usually hard to write until UI is available (and stable)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing - ToolsCanooWebTest& Grails Functional TestingBoth wrap HtmlUnit which provides a Java API that mocks a web browserCanooWebTestwrapper for WebTest's XML syntaxand therefore constrained by the underlying XML syntaxGrails Functional Testingpure-groovy solutionmore flexible, but newer & therefore fewer features than WebTest©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing - WebTesttest organization & re-usegrouping steps with ant.groupcalling methods from other testsGroovy stepnotation uses 3 double-quotes as Groovy code delimeter (“””)accessing HtmlUnit for fine-grained test controlparameter passing between app context & WebTest contextAJAX testing w/ sleep()©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing – WebTestgrouping steps with ant.groupif your test has dozens of steps, it gets hard to read the reportgrouping steps with ant.group rolls them up to 1 line in the test report, which can be easily expanded/collapsed:ant.group(description: “verify bank account info”) {    invoke “someController/someAction”verifyText “some text”verifyText “more text”}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing – WebTestcalling methods from other testsInstead of copying & pasting the same methods from one test to another, you can call a method in another test by passing it your AntBuilder instance (ant) as a param. This ensures the test steps are executed using the calling test’s AntBuilder.====== in CallingTestClass() ====def otherTestClass = new OtherTestClass()otherTestClass.someMethod(ant)====== in OtherTestClass() =====def someMethod(AntBuilderab) {ab.invoke“someController/someAction”ab.verifyText“some text”}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing – WebTestGroovy stepIf you need to execute arbitrary Groovy code in your test, use WebTest’sgroovy step.Keep in mind that this groovy step won’t have access to any Groovy variables defined in your test (such as method params)…it only has access to the properties in the AntBuilder context.So you need to pass any needed params to the AntBuilder before entering your groovy step. Then you can retrieve them from the AntBuilder from within your step.The following example involves:Storing Groovy variables into AntBuilder propertiesRetrieving AntBuilder properties for use in the Groovy stepCalling some HtmlUnit methods which aren’t available in WebTest for fine-grained test controlPausing the test for 2 seconds (very useful with AJAX tests to give the server time to respond©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Functional Testing – WebTestGroovy steptest method with Groovy step to test AJAX autocomplete form input:def setAJAXInputField(elementId, elementValue, AntBuilderab) {ab.storeProperty(property: 'elementId', value: elementId)ab.storeProperty(property: 'elementValue', value: elementValue)ab.groovy ""”    def elementId = step.webtestProperties.elementId	    def elementValue = step.webtestProperties.elementValue    def document = step.context.currentResponse.documentElementdef element = document.getHtmlElementById(elementId)element.focus()element.type(elementValue) Thread.sleep(2000)“””}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Putting It All Together - Running teststest-app -> all teststest-app -unit -> all unit teststest-app -integration -> all integration teststest-app -unit AnnualReportAssignmentHandler-> 2 unit tests & all integration teststest-app AnnualReportAssignmentHandlerWorkflowManagerService-> 2 unit tests & 1 integration testrun-webtest-> runs all tests using new server instancerun-webtest -nostart-> runs all tests using existing Tomcat instance (much faster!!!)run-webtestClassNameTestName-> run TestName using existing Tomcat instance©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
Putting It All Together - SummaryUnit testing -  taglibs, controllers, services, domain classes (including contraints), other delegates & "helpers", even your data (dbUnit)Integration testingnow that Grails 1.1 supports unit testing of controllers with ControllerUnitTestCase, that seems to be the preferred way of testing them (rather than using integration tests).This makes sense since controllers should not be doing the heavy lifting in a Grails app.The same holds true for TagLib testing with TagLibUnitTestCase.this leaves Services as the most valuable thing to cover with integration tests (but only after you’ve written unit tests for them )Functional testing - smoke tests, acceptance tests, regression testsManual testing by humans - look & feel, anything not covered above©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09

More Related Content

What's hot (20)

PDF
Unit testing on embedded target with C++Test
Engineering Software Lab
 
PDF
Oh so you test? - A guide to testing on Android from Unit to Mutation
Paul Blundell
 
PPTX
Cpp unit
mudabbirwarsi
 
PDF
Unit Testing
Scott Leberknight
 
PPT
Unit testing with java
Dinuka Malalanayake
 
PPT
Qtp-training A presentation for beginers
Dhavamani Prakash
 
PDF
ScalaUA - distage: Staged Dependency Injection
7mind
 
ODP
Mastering Mock Objects - Advanced Unit Testing for Java
Denilson Nastacio
 
PPT
JMockit
Angad Rajput
 
PDF
Sample Chapter of Practical Unit Testing with TestNG and Mockito
Tomek Kaczanowski
 
DOCX
QTP Interview Questions and answers
Rita Singh
 
PPT
Automated Regression Testing for Embedded Systems in Action
AANDTech
 
PPT
Qtp 9.5 Tutorials by www.onsoftwaretest.com
onsoftwaretest
 
PPT
AAA Automated Testing
Francesco Carucci
 
PPTX
Applying TDD to Legacy Code
Alexander Goida
 
ODT
Testing in-python-and-pytest-framework
Arulalan T
 
PDF
Unit Testing - The Whys, Whens and Hows
atesgoral
 
PDF
Unit testing best practices
nickokiss
 
PPT
Google mock training
Thierry Gayet
 
PPT
RPG Program for Unit Testing RPG
Greg.Helton
 
Unit testing on embedded target with C++Test
Engineering Software Lab
 
Oh so you test? - A guide to testing on Android from Unit to Mutation
Paul Blundell
 
Cpp unit
mudabbirwarsi
 
Unit Testing
Scott Leberknight
 
Unit testing with java
Dinuka Malalanayake
 
Qtp-training A presentation for beginers
Dhavamani Prakash
 
ScalaUA - distage: Staged Dependency Injection
7mind
 
Mastering Mock Objects - Advanced Unit Testing for Java
Denilson Nastacio
 
JMockit
Angad Rajput
 
Sample Chapter of Practical Unit Testing with TestNG and Mockito
Tomek Kaczanowski
 
QTP Interview Questions and answers
Rita Singh
 
Automated Regression Testing for Embedded Systems in Action
AANDTech
 
Qtp 9.5 Tutorials by www.onsoftwaretest.com
onsoftwaretest
 
AAA Automated Testing
Francesco Carucci
 
Applying TDD to Legacy Code
Alexander Goida
 
Testing in-python-and-pytest-framework
Arulalan T
 
Unit Testing - The Whys, Whens and Hows
atesgoral
 
Unit testing best practices
nickokiss
 
Google mock training
Thierry Gayet
 
RPG Program for Unit Testing RPG
Greg.Helton
 

Similar to Grails 1.1 Testing - Unit, Integration & Functional (20)

PPT
Monitoring using Prometheus and Grafana
Arvind Kumar G.S
 
PDF
Unit testing - A&BP CC
JWORKS powered by Ordina
 
PDF
[xp2013] Narrow Down What to Test
Zsolt Fabok
 
PPT
Mockito with a hint of PowerMock
Ying Zhang
 
PDF
Lesson 2
Andrii Trybynenko
 
PPT
Beyond Unit Testing
Steve Loughran
 
PPT
Performance testing and j meter
Purna Chandar
 
PPTX
Test driven development in .Net - 2010 + Eclipse
UTC Fire & Security
 
PPTX
Joomla! Testing - J!DD Germany 2016
Yves Hoppe
 
PDF
Pragmatic Java Test Automation
Dmitry Buzdin
 
ODP
Grails unit testing
pleeps
 
PPT
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
chrisb206 chrisb206
 
PPTX
presentation des google mock dans un contexte de tdd
Thierry Gayet
 
PDF
Testing Your Application On Google App Engine
IndicThreads
 
PDF
Testing your application on Google App Engine
Inphina Technologies
 
PDF
Integration tests: use the containers, Luke!
Roberto Franchini
 
PPTX
Appium TestNG Framework and Multi-Device Automation Execution
pCloudy
 
PDF
Building Maintainable Android Apps (DroidCon NYC 2014)
Kevin Schultz
 
PPT
Test strategy for web development
alice yang
 
PPT
JavaScript Unit Testing
Christian Johansen
 
Monitoring using Prometheus and Grafana
Arvind Kumar G.S
 
Unit testing - A&BP CC
JWORKS powered by Ordina
 
[xp2013] Narrow Down What to Test
Zsolt Fabok
 
Mockito with a hint of PowerMock
Ying Zhang
 
Beyond Unit Testing
Steve Loughran
 
Performance testing and j meter
Purna Chandar
 
Test driven development in .Net - 2010 + Eclipse
UTC Fire & Security
 
Joomla! Testing - J!DD Germany 2016
Yves Hoppe
 
Pragmatic Java Test Automation
Dmitry Buzdin
 
Grails unit testing
pleeps
 
Selenium-Browser-Based-Automated-Testing-for-Grails-Apps
chrisb206 chrisb206
 
presentation des google mock dans un contexte de tdd
Thierry Gayet
 
Testing Your Application On Google App Engine
IndicThreads
 
Testing your application on Google App Engine
Inphina Technologies
 
Integration tests: use the containers, Luke!
Roberto Franchini
 
Appium TestNG Framework and Multi-Device Automation Execution
pCloudy
 
Building Maintainable Android Apps (DroidCon NYC 2014)
Kevin Schultz
 
Test strategy for web development
alice yang
 
JavaScript Unit Testing
Christian Johansen
 
Ad

Recently uploaded (20)

PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PPTX
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PDF
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Complete JavaScript Notes: From Basics to Advanced Concepts.pdf
haydendavispro
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
WooCommerce Workshop: Bring Your Laptop
Laura Hartwig
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
The Builder’s Playbook - 2025 State of AI Report.pdf
jeroen339954
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
July Patch Tuesday
Ivanti
 
Chris Elwell Woburn, MA - Passionate About IT Innovation
Chris Elwell Woburn, MA
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
Ad

Grails 1.1 Testing - Unit, Integration & Functional

  • 1. Grails 1.1 TestingTech Talk @ 2PathsJuly 17, 2009By Dave Koo©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 2. AgendaUnit TestingIntegration TestingFunctional TestingPutting It All Together©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 3. Unit Testing - Overviewunit tests enable testing small bits of code in isolationGrails does NOT inject any surrounding infrastructure (ie. no dynamic GORM methods, database, Spring resources, bootstrap, ServletContext, etc)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 4. Unit Testing - Benefitsfind problems sooner -> you can test your code before all it's dependencies are created/availableenables safer refactoring (of individual classes)faster to run than integration & functional teststhere isn't a big speed gap early in the project (PLAID: unit ~ 10s, integration ~ 30)but it grows as the system gets biggermakes TDD less painful -> breaks problem into smaller piecesprovides form of API documentation & spec©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 5. Unit Testing - Drawbacksmore code to maintain & debug -> often as buggy as code under test (if written by same person :)sometimes you have to mock a LOT of stuff before you can write your little testdoesn't catch bugs at the integration or UI layers -> can create false sense of security©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 6. Unit Testing – GrailsUnitTestCaseOverviewextends GroovyTestCase to add Grails-specific mocking and make testing more convenient for Grails usersmocking is test-specific and doesn't leak from one test to anotheravoids having to do a lot of MetaClass hacking (and forgetting to teardown your metaclass hacking :)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 7. Unit Testing – GrailsUnitTestCasemethodsmockFor(class, loose = false)mockDomain(class, testInstances[ ])mockForConstraintsTests(class, testInstances[ ])mockLogging(class, enableDebug = false)Code samples: http://grails.org/doc/1.1.1/guide/9.%20Testing.html#9.1%20Unit%20Testing©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 8. Unit Testing – GrailsUnitTestCasemockFor(class, loose = false)generic mocker for mocking methods of any classreturns a control object (not the actual mock)loose - false == strict mocking (sequence of expected method calls matters), true == loose (sequence doesn't matter)methods - you can mock instance or static methodsdemands - your expectations of the mockrange - number of times a method is expected to be called (default === 1)closure - mock implementation of the methodstrictControl.createMock() - returns an actual mock objectstrictControl.verify() - verifies that all demands were actually met©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 9. Unit Testing – GrailsUnitTestCasemockDomain(class, testInstances[ ])mocks all methods (instance, static & dynamic) on a domain classtestInstances- a list of domain class instances which replaces and acts as the "database”you can call save(), findBy*(), validate(), etc on an instance of a mocked domain classinheritance can be tricky!assume you have ParentClass, ChildA, ChildBif you mock ParentClass and pass a collection of instances containing ChildA and/or ChildB objects to the MockDomain() method, you must ensure that you have already mocked each type of ChildX class in the instance collection. This is needed even if you NEVER call a dynamic method on any child class (such as ChildClass.list()).always mock a child class BEFORE mocking its parent, otherwise you may get "Method Not Found" exceptions when calling dynamic methods on the childnew addition to Grailsstill some bugs / missing featurescheck Grails' JIRA & mailing lists if experiencing wierdbehaviour©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 10. Unit Testing – GrailsUnitTestCaseother methods…mockForConstraintsTests(class, testInstances[ ])Stripped-down version of mockDomain that allows for assertions to validate domain class constraintsTakes the pain out of testing domain class constraintsmockLogging(class, enableDebug = false)Adds a mock "log" property to a class. Any messages passed to the mock logger are echoed to the console.©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 11. Unit Testing – ControllerUnitTestCaseextends GrailsUnitTestCase to add mocks for:all dynamic properties & methods Grails injects into controllers (render, redirect, model, etc)all HTTP objects available to controllers (request, response, session, params, flash, etc)command object (if needed)provides an implicit "controller" property which contains all the above mocks (no need to def the controller yourself in your test class)don't forget to mock your Domain objects as needed if the controller action you call expects a database©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 12. Unit Testing – Other Unit TestsTagLibUnitTestCaseextends GrailsUnitTestCase to add mocks for dynamic properties & methods a TagLibexpectsdbUnitextends jUnit to allow you to test that your DB is in the expected stateprevents subsequent tests from failing due to a previous test leaving the database "dirty"©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 13. Integration Testing - Overviewused to test that an entire module or sub-system consisting of multiple classes is working correctly (in isolation)one level below a functional test as integration tests do not test the entire stackGrails injects all the surrounding infrastructure such as data sources & Spring beanspretty straightforward to implement since there's generally no mocking involvedwhere to use integration tests??? we'll come back to this in a few mins :)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 14. Integration Testing - Benefitstests the real interactions between individual piecesfinds more complex bugs that unit tests can't findfaster to run than functional tests (usually)makes large-scale refactoring saferfind bugs sooner -> doesn't require other system modules to be built©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 15. Integration Testing - Drawbacksperhaps overused by lazy testers who don't feel like mocking :)requires more code to be written than unit testsdoesn't find system-level or inter-module bugsvalue is debatable if you have good functional tests & good unit tests.©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 16. Functional Testing - Overviewused to test functionality from an end user's perspective across all layers of the system©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 17. Functional Testing - Benefitsfinds complex system-level and inter-module bugsfinds UI bugscan be written by non-techies (depends on tool used)provides "done when" acceptance criteria for the customerprovides a form of user documentationmakes large-scale refactoring safer©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 18. Functional Testing - Drawbacksvery slow to execute HTTP level testsoften more cumbersome to write than other types of testsoften brittle and can require a lot of maintenance (especially if tied to UI)Usually hard to write until UI is available (and stable)©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 19. Functional Testing - ToolsCanooWebTest& Grails Functional TestingBoth wrap HtmlUnit which provides a Java API that mocks a web browserCanooWebTestwrapper for WebTest's XML syntaxand therefore constrained by the underlying XML syntaxGrails Functional Testingpure-groovy solutionmore flexible, but newer & therefore fewer features than WebTest©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 20. Functional Testing - WebTesttest organization & re-usegrouping steps with ant.groupcalling methods from other testsGroovy stepnotation uses 3 double-quotes as Groovy code delimeter (“””)accessing HtmlUnit for fine-grained test controlparameter passing between app context & WebTest contextAJAX testing w/ sleep()©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 21. Functional Testing – WebTestgrouping steps with ant.groupif your test has dozens of steps, it gets hard to read the reportgrouping steps with ant.group rolls them up to 1 line in the test report, which can be easily expanded/collapsed:ant.group(description: “verify bank account info”) { invoke “someController/someAction”verifyText “some text”verifyText “more text”}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 22. Functional Testing – WebTestcalling methods from other testsInstead of copying & pasting the same methods from one test to another, you can call a method in another test by passing it your AntBuilder instance (ant) as a param. This ensures the test steps are executed using the calling test’s AntBuilder.====== in CallingTestClass() ====def otherTestClass = new OtherTestClass()otherTestClass.someMethod(ant)====== in OtherTestClass() =====def someMethod(AntBuilderab) {ab.invoke“someController/someAction”ab.verifyText“some text”}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 23. Functional Testing – WebTestGroovy stepIf you need to execute arbitrary Groovy code in your test, use WebTest’sgroovy step.Keep in mind that this groovy step won’t have access to any Groovy variables defined in your test (such as method params)…it only has access to the properties in the AntBuilder context.So you need to pass any needed params to the AntBuilder before entering your groovy step. Then you can retrieve them from the AntBuilder from within your step.The following example involves:Storing Groovy variables into AntBuilder propertiesRetrieving AntBuilder properties for use in the Groovy stepCalling some HtmlUnit methods which aren’t available in WebTest for fine-grained test controlPausing the test for 2 seconds (very useful with AJAX tests to give the server time to respond©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 24. Functional Testing – WebTestGroovy steptest method with Groovy step to test AJAX autocomplete form input:def setAJAXInputField(elementId, elementValue, AntBuilderab) {ab.storeProperty(property: 'elementId', value: elementId)ab.storeProperty(property: 'elementValue', value: elementValue)ab.groovy ""” def elementId = step.webtestProperties.elementId def elementValue = step.webtestProperties.elementValue def document = step.context.currentResponse.documentElementdef element = document.getHtmlElementById(elementId)element.focus()element.type(elementValue) Thread.sleep(2000)“””}©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 25. Putting It All Together - Running teststest-app -> all teststest-app -unit -> all unit teststest-app -integration -> all integration teststest-app -unit AnnualReportAssignmentHandler-> 2 unit tests & all integration teststest-app AnnualReportAssignmentHandlerWorkflowManagerService-> 2 unit tests & 1 integration testrun-webtest-> runs all tests using new server instancerun-webtest -nostart-> runs all tests using existing Tomcat instance (much faster!!!)run-webtestClassNameTestName-> run TestName using existing Tomcat instance©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09
  • 26. Putting It All Together - SummaryUnit testing - taglibs, controllers, services, domain classes (including contraints), other delegates & "helpers", even your data (dbUnit)Integration testingnow that Grails 1.1 supports unit testing of controllers with ControllerUnitTestCase, that seems to be the preferred way of testing them (rather than using integration tests).This makes sense since controllers should not be doing the heavy lifting in a Grails app.The same holds true for TagLib testing with TagLibUnitTestCase.this leaves Services as the most valuable thing to cover with integration tests (but only after you’ve written unit tests for them )Functional testing - smoke tests, acceptance tests, regression testsManual testing by humans - look & feel, anything not covered above©2009 - 2Paths Solutions Ltd. (www.2paths.com)7/17/09