• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Test First Refresh Second: Test-Driven Development in Grails
 

Test First Refresh Second: Test-Driven Development in Grails

on

  • 5,148 views

Grails provides solid support for unit testing of parts of your application that are usually very difficult to test. Learn how to enable test-first development practices using the Grails framework.

Grails provides solid support for unit testing of parts of your application that are usually very difficult to test. Learn how to enable test-first development practices using the Grails framework.

Statistics

Views

Total Views
5,148
Views on SlideShare
4,849
Embed Views
299

Actions

Likes
9
Downloads
0
Comments
2

7 Embeds 299

http://kinisoftware.lacoctelera.net 191
http://kinisoftware.com 60
http://www.slideshare.net 38
http://traenportal.jira.com 5
http://feeds.feedburner.com 2
https://traenportal.jira.com 2
http://www.lacoctelera.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Apple Keynote

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

12 of 2 previous next

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Glad to hear it! I never called super.setup() in normal JUnit tests, so the habit didn't automatically spring into existence when I started writing Grails tests. Turns out it's rather important. :)
    Are you sure you want to
    Your message goes here
    Processing…
  • Nice slideshow. I like your RTFM red slides, they got my attention, and pasting in a call to super.setup() solved my problem (doh!).
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Test-driven development has reached the status of received orthodoxy. For my part, I don’t object to the idea of a right way of thinking, but in our line of work, we should watch ourselves. There are some people critical of the idea of testing first, and we should listen to them.
  • One way to gauge the health of our community is to see what happens to people who don’t toe the line. We don’t want to burn them at the stake. We should listen to them. It’s especially easy to eschew testing in difficult environments, and some people do so. We should ask why.
  • Small pieces of code tested in isolation from each other. Typically at the class or method level. Often uses practices like stubbing and mocking to effect isolation. Runs fast, particularly if the IDE has a test runner that doesn’t require booting a new JVM or rebuilding the world.
  • Small pieces of code tested in isolation from each other. Typically at the class or method level. Often uses practices like stubbing and mocking to effect isolation. Runs fast, particularly if the IDE has a test runner that doesn’t require booting a new JVM or rebuilding the world.
  • Multiple units tested together in collaboration. Usually implies testing our code with a live database and servlet container. Want to test actual ORM, page rendering, service layer, etc. Runs slower. Not suitable for TDD. Should be run by a build server.
  • Multiple units tested together in collaboration. Usually implies testing our code with a live database and servlet container. Want to test actual ORM, page rendering, service layer, etc. Runs slower. Not suitable for TDD. Should be run by a build server.
  • Multiple units tested together in collaboration. Usually implies testing our code with a live database and servlet container. Want to test actual ORM, page rendering, service layer, etc. Runs slower. Not suitable for TDD. Should be run by a build server.
  • Testing features of the fully assembled system. Best to do in a story-driven fashion. Certainly slow, requires significant server infrastructure (compared to JUnit), should be run by a build server.
  • Testing features of the fully assembled system. Best to do in a story-driven fashion. Certainly slow, requires significant server infrastructure (compared to JUnit), should be run by a build server.
  • Testing features of the fully assembled system. Best to do in a story-driven fashion. Certainly slow, requires significant server infrastructure (compared to JUnit), should be run by a build server.
  • Our main concern tonight will be unit tests. You really can’t do TDD with integration or functional tests, because they take too long to run. There are two things that are important when considering unit tests.
  • These are code, not human procedures.
  • Each unit test should make assertions about a small, coherent chunk of code. Moreover, it should not matter in what order we run them. Each should be fully responsible for creating the state it needs to run its code under test.
  • Since they are executable, we should be able to have a computer run them very frequently.
  • Let’s talk about isolation some more. It’s easy—or can be—when you’re writing APIs in core Java. It’s hard in a web app. Why is that? (DB, servlet container, browser, HTTP loop)
  • Besides the web and database problems, we usually have problems related to integration points, since
  • Besides the web and database problems, we usually have problems related to integration points, since
  • Besides the web and database problems, we usually have problems related to integration points, since
  • Besides the web and database problems, we usually have problems related to integration points, since
  • Besides the web and database problems, we usually have problems related to integration points, since
  • The Testing plugin was made a part of core Grails as of the 1.1 release. It revolutionized the way we can test Grails apps.
  • These are extensions to GroovyTestCase, which is itself an extension to JUnit’s TestCase.
  • These four methods form the substance of the features provided by the two base testing classes. We’ll discuss their features in turn, then demonstrate some of them.
  • At runtime, the simple domain, controller, service, job, and tag library classes you write in Groovy are modified significantly at the MetaClass level. This requires the Spring container to be booted, etc., all of which takes time. These test methods make direct modifications to the MetaClass of the classes under test to mock the desired behavior in a convincing way.
  • findWhere() is coming in 1.2
  • findWhere() is coming in 1.2
  • As properties of the mocked class, and as properties of the test case class if extended from ControllerUnitTest
  • As properties of the mocked class, and as properties of the test case class if extended from ControllerUnitTest
  • Is automatically called by mockController
  • Is automatically called by mockController
  • Is automatically called by mockController
  • Is automatically called by mockController
  • Provides certain properties and method to the test case class.
  • It does important things. If you override setUp() (and you probably should), remember to call this.
  • These are all provided to the class under test automatically.
  • This is a convenience feature. It does not mock relevant domain classes.
  • Users have name, email, company title, membership status.
  • Meetings have a start time, end time, location, description, member price, and nonmember price.
  • As an
  • As an
  • It’s best to determine the shape of the testing framework and the functionality it covers, and try to write testable code on that basis. Usually that results in better factoring anyway.
  • You’ll use criteria if you’re doing anything of any complexity.
  • It’s economical to write tests this way, and enough of the framework is mocked to get the job done. You can actually write code against your domain model and controllers while testing first.

Test First Refresh Second: Test-Driven Development in Grails Test First Refresh Second: Test-Driven Development in Grails Presentation Transcript

  • Test First, Refresh Second Test-Driven Development with Tim Berglund October, 2009
  • TDD
  • Failure to Write Tests?
  • KINDS OF TESTING
  • KINDS OF TESTING UNIT TESTING
  • KINDS OF TESTING UNIT TESTING XUNIT
  • KINDS OF TESTING
  • KINDS OF TESTING INTEGRATION TESTING
  • KINDS OF TESTING INTEGRATION TESTING XUNIT EXTENSIONS
  • KINDS OF TESTING INTEGRATION TESTING XUNIT EXTENSIONS TESTNG
  • KINDS OF TESTING
  • KINDS OF TESTING FUNCTIONAL TESTING
  • KINDS OF TESTING FUNCTIONAL TESTING
  • KINDS OF TESTING FUNCTIONAL TESTING
  • UNIT TESTS
  • EXECUTABLE
  • ISOLATED
  • AUTOMATED
  • ISOLATED?
  • WEB APP ISOLATION CHALLENGES
  • WEB APP ISOLATION CHALLENGES DATABASE
  • WEB APP ISOLATION CHALLENGES DATABASE SERVLET CONTAINER
  • WEB APP ISOLATION CHALLENGES DATABASE SERVLET CONTAINER HTTP INTERACTION
  • WEB APP ISOLATION CHALLENGES DATABASE SERVLET CONTAINER HTTP INTERACTION PAGE RENDERING
  • WEB APP ISOLATION CHALLENGES DATABASE SERVLET CONTAINER HTTP INTERACTION PAGE RENDERING ENTERPRISE INTEGRATION POINTS
  • TO THE RESCUE! (especially 1.1 and later)
  • THE GOOD STUFF
  • THE GOOD STUFF GrailsUnitTestCase ControllerUnitTestCase
  • THE GOOD STUFF
  • THE GOOD STUFF mockDomain mockController mockLogging mockConfig
  • METACLASS MAGIC
  • mockDomain
  • mockDomain SUPPORTS
  • mockDomain SUPPORTS findAll() findAllByXXX() get() read() getAll() ident() exists()
  • mockDomain SUPPORTS findAll() count() findAllByXXX() list() get() validate() read() save() getAll() delete() ident() discard() exists()
  • mockDomain
  • mockDomain DOES NOT SUPPORT
  • mockDomain DOES NOT SUPPORT Criteria Builders HQL Persistent Class Inheritance findWhere() findAllWhere()
  • mockController
  • mockController SUPPORTS
  • mockController SUPPORTS log request response session params flash
  • mockController SUPPORTS log forward() request redirect() response render() session withFormat() params withForm() flash
  • mockController
  • mockController SUPPORTS
  • mockController SUPPORTS forwardArgs redirectArgs renderArgs template modelAndView
  • mockLogging
  • mockLogging ADDS MOCKED LOG PROPERTY
  • mockLogging ADDS MOCKED LOG PROPERTY SENDS OUTPUT TO SYSTEM.OUT
  • mockLogging ADDS MOCKED LOG PROPERTY SENDS OUTPUT TO SYSTEM.OUT IGNORES DEBUG AND TRACE BY DEFAULT
  • mockLogging ADDS MOCKED LOG PROPERTY SENDS OUTPUT TO SYSTEM.OUT IGNORES DEBUG AND TRACE BY DEFAULT CAN ENABLE DEBUG WITH A SWITCH
  • mockConfig
  • mockConfig REPLACES DEFAULT GRAILS CONFIG IN grailsApplication.config
  • mockConfig REPLACES DEFAULT GRAILS CONFIG IN grailsApplication.config READS FROM A STRING
  • GrailsUnitTestCase
  • GrailsUnitTestCase INTRINSIC PROPERTIES applicationContext errorsMap INTRINSIC METHODS mockFor mockDomain mockController mockTagLib mockConfig
  • GrailsUnitTestCase MUST CALL super.setUp()!
  • ControllerUnitTestCase INTRINSIC PROPERTIES
  • ControllerUnitTestCase INTRINSIC PROPERTIES mockRequest mockResponse mockSession forwardArgs redirectArgs renderArgs mockParams mockFlash
  • ControllerUnitTestCase
  • ControllerUnitTestCase AUTOMATICALLY MOCKS CONTROLLER FROM TEST CLASS NAME
  • ControllerUnitTestCase MUST CALL super.setUp()
  • LET’S USE THIS!
  • OUR APP USER GROUP MEMBERSHIP MANAGER
  • STORIES AS AN UNREGISTERED USER, I WANT TO SIGN UP ON THE SITE.
  • STORIES AS A REGISTERED USER, I WANT TO SEE UPCOMING EVENTS.
  • STORIES AS AN ADMINISTRATOR, I WANT TO HAVE FULL CRUD CAPABILITIES ON MEETINGS.
  • STORIES AS AN ADMINISTRATOR, I WANT TO SEE WHO IS ATTENDING AN EVENT.
  • STORIES AS A REGISTERED USER, I WANT TO BE ABLE TO RSVP TO AN EVENT.
  • LIVE CODING!
  • THE CONCLUSION?
  • IT WORKS!
  • THERE ARE REAL LIMITATIONS
  • INTEGRATION AND FUNCTIONAL TESTS ARE NECESSARY
  • CREDIBLE WEB APP TDD
  • THANK YOU! TIM BERGLUND AUGUST TECHNOLOGY GROUP, LLC http://www.augusttechgroup.com tim.berglund@augusttechgroup.com @tlberglund
  • PHOTO CREDITS SHIPPING CONTAINERS: HTTP://WWW.FLICKR.COM/PHOTOS/PHOTOHOME_UK/1494590209/ COMPUTER CONSOLE: HTTP://WWW.FLICKR.COM/PHOTOS/NOSTRI-IMAGO/2910549047/