PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/doc/new-manual/src/docs/asciidoc/110-testing.adoc

http://github.com/geb/geb
AsciiDoc | 198 lines | 132 code | 66 blank | 0 comment | 0 complexity | b539a8df86ea13777f90f1f91c0a98ab MD5 | raw file
Possible License(s): Apache-2.0
  1. [[testing]]
  2. = Testing
  3. Geb provides first class support for functional web testing via integration with popular testing frameworks such as {spock}, {junit}, {testng} and {cucumber-jvm}.
  4. == Spock, JUnit & TestNG
  5. The Spock, JUnit and TestNG integrations work fundamentally the same way. They provide subclasses that setup a {browser-api} instance that all method calls and property accesses/references resolve against via Groovy's `methodMissing` and `propertyMissing` mechanism.
  6. ____
  7. Recall that the browser instance also forwards any method calls or property accesses/references that it can't handle to its current page object, which helps to remove a lot of noise from the test.
  8. ____
  9. Consider the following Spock spec
  10. ----
  11. import geb.spock.GebSpec
  12. class FunctionalSpec extends GebSpec {
  13. def "go to login"() {
  14. when:
  15. go "/login"
  16. then:
  17. title == "Login Screen"
  18. }
  19. }
  20. ----
  21. Which is equivalent to
  22. ----
  23. import geb.spock.GebSpec
  24. class FunctionalSpec extends GebSpec {
  25. def "go to login"() {
  26. when:
  27. browser.go "/login"
  28. then:
  29. browser.page.title == "Login Screen"
  30. }
  31. }
  32. ----
  33. === Configuration
  34. The browser instance is created by the testing integration. The link:configuration.html[configuration mechanism] allows you to control aspects such as the driver implementation and base URL.
  35. === Reporting
  36. The Spock, JUnit and TestNG integrations also ship a superclass (the name of the class for each integration module is provided below) that automatically takes reports at the end of test methods with the label end. They also set the link:reporting.html#the_report_group[report group] to the name of the test class (substituting . for /).
  37. The link:api/geb/Browser.html#report(java.lang.String)[`report(String label)`] browser method is replaced with a specialised version. This method works the same as the browser method, but adds counters and the current test method name as prefixes to the given label.
  38. ----
  39. package my.tests
  40. import geb.spock.GebReportingSpec
  41. class FunctionalSpec extends GebReporting {
  42. def "login"() {
  43. when:
  44. go "login"
  45. username = "me"
  46. report "login screen" // take a report of the login screen
  47. login().click()
  48. then:
  49. title == "Logged in!"
  50. }
  51. }
  52. ----
  53. Assuming a configured `reportsDir` of `reports/geb` and the default reporters (i.e. link:api/geb/report/ScreenshotReporter.html[`ScreenshotReporter`] and link:api/geb/report/PageSourceReporter.html[`PageSourceReporter`]), we would find the following files:
  54. * `reports/geb/my/tests/FunctionalSpec/1-1-login-login screen.html`
  55. * `reports/geb/my/tests/FunctionalSpec/1-1-login-login screen.png`
  56. * `reports/geb/my/tests/FunctionalSpec/1-2-login-end.html`
  57. * `reports/geb/my/tests/FunctionalSpec/1-2-login-end.png`
  58. The report file name format is:
  59. ----
  60. «test method number»-«report number in test method»-«test method name»-«label».«extension»
  61. ----
  62. Reporting is an extremely useful feature and can help you diagnose test failures much easier. Wherever possible, favour the use of the auto-reporting base classes.
  63. [[cookie-management-in-tests]]
  64. === Cookie management
  65. The Spock, JUnit and TestNG integrations will automatically clear the browser's cookies at the end of each test method. For JUnit 3 this happens in the `tearDown()` method in `geb.junit3.GebTest`, for JUnit 4 it happens in an `@After` method in `geb.junit4.GebTest` and for TestNG it happens in an `@AfterMethod` method in `geb.testng.GebTest`.
  66. The `geb.spock.GebSpec` class will clear the cookies in the `cleanup()` method unless the spec is `@Stepwise`, in which case they are cleared in `cleanupSpec()` (meaning that all feature methods in a stepwise spec share the same browser state).
  67. This auto-clearing of cookies can be link:configuration.html#auto_clearing_cookies[disabled via configuration].
  68. === JAR and class names
  69. The following table illustrates the specific JARs and class names for Spock and JUnit.
  70. |===
  71. |Framework |JAR |Base Class |Reporting Base Class
  72. |Spock |http://mvnrepository.com/artifact/{geb-group}/geb-spock[geb-spock] |api/geb/spock/GebSpec.html[geb.spock.GebSpec] |api/geb/spock/GebReportingSpec.html[geb.spock.GebReportingSpec]
  73. |JUnit 4 |http://mvnrepository.com/artifact/{geb-group}/geb-junit4[geb-junit4] |api/geb/junit4/GebTest.html[geb.junit4.GebTest] |api/geb/junit4/GebReportingTest.html[geb.junit4.GebReportingTest]
  74. |JUnit 3 |http://mvnrepository.com/artifact/{geb-group}/geb-junit3[geb-junit3] |api/geb/junit3/GebTest.html[geb.junit3.GebTest] |api/geb/junit3/GebReportingTest.html[geb.junit3.GebReportingTest]
  75. |TestNG |http://mvnrepository.com/artifact/{geb-group}/geb-testng[geb-testng] |api/geb/testng/GebTest.html[geb.testng.GebTest] |api/geb/testng/GebReportingTest.html[geb.testng.GebReportingTest]
  76. |===
  77. === Example projects
  78. The following projects can be used as starting references:
  79. * https://github.com/geb/geb-example-gradle
  80. === Configuration
  81. Configuration is done in the `given` block of a scenario or story. Here you can optionally set 3 properties; `driver`, `baseUrl` and `browser`.
  82. You can set the `driver` property to the driver instance that you want to implicitly created browser instance to use. However, using the link:configuration.html#driver_implementation[configuration mechanism for driver implementation] is preferred.
  83. You can set the `baseUrl` property to the base URL that you want to implicitly created browser instance to use. However, using the link:configuration.html#base_url[configuration mechanism for base url] is preferred.
  84. For fine-grained control, you can create your own {browser-api} instance and assign it to the `browser` property. Otherwise, an implicit browser object is created using `driver` and/or `baseUrl` if they were explicitly set (otherwise the configuration mechanism is used.)
  85. == Cucumber (Cucumber-JVM)
  86. It is possible to both:
  87. * Write your own [Cucumber-JVM][cucumber-jvm] steps that manipulate Geb
  88. * Use a library of pre-built steps that drives Geb to do many common tasks
  89. === Writing your own steps
  90. Use Geb's link:binding.html[binding management features] to bind a browser in before / after hooks, often in a file named `env.groovy`:
  91. ----
  92. def bindingUpdater
  93. Before() { scenario ->
  94. bindingUpdater = new BindingUpdater(binding, new Browser())
  95. bindingUpdater.initialize()
  96. }
  97. After() { scenario ->
  98. bindingUpdater.remove()
  99. }
  100. ----
  101. Then normal Geb commands and objects are available in your Cucumber steps:
  102. ----
  103. import static cucumber.api.groovy.EN.*
  104. Given(~/I am on the DuckDuckGo search page/) { ->
  105. to DuckDuckGoHomePage
  106. waitFor { at(DuckDuckGoHomePage) }
  107. }
  108. When(~/I search for "(.*)"/) { String query ->
  109. page.search.value(query)
  110. page.searchButton.click()
  111. }
  112. Then(~/I can see some results/) { ->
  113. assert at(DuckDuckGoResultsPage)
  114. }
  115. Then(~/the first link should be "(.*)"/) { String text ->
  116. waitFor { page.results }
  117. assert page.resultLink(0).text()?.contains(text)
  118. }
  119. ----
  120. === Using pre-built steps
  121. The [`geb-cucumber`][geb-cucumber] project has a set of pre-built cucumber steps that drive Geb. So for example a feature with steps similar to the above would look like:
  122. ----
  123. When I go to the duck duck go home page
  124. And I enter "cucumber-jvm github" into the search field
  125. And I click the search button
  126. Then the results table 1st row link matches /cucumber\/cucumber-jvm · GitHub.*/
  127. ----
  128. See [`geb-cucumber`][geb-cucumber] for more examples.
  129. `geb-cucumber` also does Geb binding automatically, so if it is picked up you don't need to do it yourself as above.
  130. === Example project
  131. The following project has examples of both writing your own steps and using `geb-cucumber`:
  132. * https://github.com/geb/geb-example-cucumber-jvm