PageRenderTime 37ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

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

http://github.com/geb/geb
AsciiDoc | 189 lines | 131 code | 58 blank | 0 comment | 0 complexity | a4a40e654ca510d32660d1199cdcf122 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. == Spock, JUnit & TestNG
  6. The Spock, JUnit and TestNG integrations work fundamentally the same way.
  7. They provide superclasses that setup a `{browser-api}` instance that all method calls and property accesses/references resolve against via Groovy's `methodMissing` and `propertyMissing` mechanism.
  8. These superclasses are just a thin layer on top of `{geb-test-manager-api}` and utilize an AST transformation registered using `{dynamically-dispatches-to-browser-api}` annotation to implement dynamic method and property dispatching onto the instance of `{browser-api}`.
  9. If the provided superclasses are inconvenient to use, or you wish to use a testing framework for which an integration is not provided out of the box then it's highly recommended to use `{geb-test-manager-api}` together with `{dynamically-dispatches-to-browser-api}` when implementing your custom integration.
  10. Taking a look at the code of the superclasses providing the built-in support for test frameworks is a good starting point when undertaking implementation of a custom integration.
  11. [TIP]
  12. ====
  13. 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.
  14. ====
  15. Consider the following Spock spec
  16. [source,groovy]
  17. ----
  18. include::{snippets-dir}/testing/FunctionalSpec.groovy[tag=concise,indent=0]
  19. ----
  20. Which is equivalent to
  21. [source,groovy]
  22. ----
  23. include::{snippets-dir}/testing/FunctionalSpec.groovy[tag=verbose,indent=0]
  24. ----
  25. === Configuration
  26. The browser instance is created by the testing integrations via use of `{geb-test-manager-api}`. The <<configuration, configuration mechanism>> allows you to control aspects such as the driver implementation and base URL.
  27. [[testing-reporting]]
  28. === Reporting
  29. 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 with the label failure if a test fails.
  30. They also set the <<report-group, report group>> to the name of the test class (substituting . with /).
  31. The `{browser-report-method-api}` browser method is replaced with a specialised version.
  32. This method works the same as the browser method, but adds counters and the current test method name as prefixes to the given label.
  33. [source,groovy]
  34. ----
  35. include::{snippets-dir}/testing/ReportingFunctionalSpec.groovy[tag=example,indent=0]
  36. ----
  37. <1> Take a report of the login screen.
  38. Assuming a configured `reportsDir` of `reports/geb` and the default reporters (i.e. `{screenshot-reporter-api}` and `{page-source-reporter-api}`), we would find the following files:
  39. * `reports/geb/my/tests/LoginSpec/001-001-login-login screen.html`
  40. * `reports/geb/my/tests/LoginSpec/001-001-login-login screen.png`
  41. If the assertion on the title fails then the following files would be generated as well:
  42. * `reports/geb/my/tests/LoginSpec/001-002-login-failure.html`
  43. * `reports/geb/my/tests/LoginSpec/001-002-login-failure.png`
  44. The report file name format is:
  45. ----
  46. «test method number»-«report number in test method»-«test method name»-«label».«extension»
  47. ----
  48. Reporting is an extremely useful feature and can help you diagnose test failures much easier.
  49. Wherever possible, favour the use of the auto-reporting base classes.
  50. [[cookie-management-in-tests]]
  51. === Cookie management
  52. `{geb-test-manager-api}` and thus also the Spock, JUnit and TestNG built-in integrations will automatically clear the browser's cookies for the current domain at the end of each test method.
  53. This happens when `GebTestManager.afterTest()` is called unless `GebTestManager.resetBrowserAfterEachTestPredicate` evaluates to `false` like it does for `@Stepwise` Spock specifications - in such case cookie clearing happens in `GebTestManager.afterTestClass()` (meaning that all feature methods in a stepwise spec share the same browser state).
  54. This auto-clearing of cookies can be <<auto-clearing-cookies-configuration, disabled via configuration>>.
  55. If you need to clear cookies in multiple domains you will need to manually track the urls and call `{browser-clear-cookies-urls-api}`.
  56. [[web-storage-management-in-tests]]
  57. === Web storage management
  58. `{geb-test-manager-api}` and thus also the Spock, JUnit and TestNG built-in integrations can be <<auto-clearing-web-storage-configuration, configured>> to automatically clear the browser's web storage, that is both local and session storage, for the current domain at the end of each test method.
  59. This happens when `GebTestManager.afterTest()` is called unless `GebTestManager.resetBrowserAfterEachTestPredicate` evaluates to `false` like it does for `@Stepwise` Spock specifications - in such case cookie clearing happens in `GebTestManager.afterTestClass()` (meaning that all feature methods in a stepwise spec share the same browser state).
  60. === Restarting the browser mid-test
  61. Should you ever wish to restart the browser mid-test you have to be aware that there are two layers of caching of the driver instance within Geb's testing support.
  62. Firstly the lazy initialised `Browser` instance stored as a field in the `{geb-test-manager-api}` instance held by base classes providing support for various test frameworks holds a reference to a `WebDriver` instance - you will therefore need to call `resetBrowser()` method from the base class or directly on the `{geb-test-manager-api}` instance to clear that field.
  63. Secondly, Geb caches `WebDriver` instances by default as described in the section about <<implicit-driver-lifecycle, implicit driver lifecycle>>. To clear the cache and quit the browser you will need to call `{clear-browser-cache-and-quit-api}`.
  64. Therefore, you can use the following code within a test to restart the browser:
  65. [source,groovy]
  66. ----
  67. include::{snippets-dir}/testing/BrowserRestartSpec.groovy[tag=restart,indent=0]
  68. ----
  69. === JAR and class names
  70. The following table illustrates the specific JARs and class names for various test frameworks that Geb integrates with.
  71. |===
  72. |Framework |JAR |Base Class |Reporting Base Class
  73. |Spock |http://mvnrepository.com/artifact/{geb-group}/geb-spock[geb-spock] |link:api/geb/spock/GebSpec.html[`geb.spock.GebSpec`] |link:api/geb/spock/GebReportingSpec.html[`geb.spock.GebReportingSpec`]
  74. |JUnit 4 |http://mvnrepository.com/artifact/{geb-group}/geb-junit4[geb-junit4] |link:api/geb/junit4/GebTest.html[`geb.junit4.GebTest`] |link:api/geb/junit4/GebReportingTest.html[`geb.junit4.GebReportingTest`]
  75. |JUnit 5 |http://mvnrepository.com/artifact/{geb-group}/geb-junit5[geb-junit5] |link:api/geb/junit5/GebTest.html[`geb.junit5.GebTest`] |link:api/geb/junit5/GebReportingTest.html[`geb.junit5.GebReportingTest`]
  76. |TestNG |http://mvnrepository.com/artifact/{geb-group}/geb-testng[geb-testng] |link:api/geb/testng/GebTest.html[`geb.testng.GebTest`] |link:api/geb/testng/GebReportingTest.html[`geb.testng.GebReportingTest`]
  77. |===
  78. === Example projects
  79. The following projects can be used as starting references:
  80. * link:https://github.com/geb/geb-example-gradle[geb-example-gradle]
  81. [[cucumber-jvm]]
  82. == Cucumber (Cucumber-JVM)
  83. It is possible to both:
  84. * Write your own {cucumber-jvm} steps that manipulate Geb
  85. * Use a library of pre-built steps that drives Geb to do many common tasks
  86. === Writing your own steps
  87. Use Geb's <<binding, binding management features>> to bind a browser in before / after hooks, often in a file named `env.groovy`:
  88. [source,groovy]
  89. ----
  90. def bindingUpdater
  91. Before() { scenario ->
  92. bindingUpdater = new BindingUpdater(binding, new Browser())
  93. bindingUpdater.initialize()
  94. }
  95. After() { scenario ->
  96. bindingUpdater.remove()
  97. }
  98. ----
  99. Then normal Geb commands and objects are available in your Cucumber steps:
  100. [source,groovy]
  101. ----
  102. import static cucumber.api.groovy.EN.*
  103. Given(~/I am on the DuckDuckGo search page/) { ->
  104. to DuckDuckGoHomePage
  105. waitFor { at(DuckDuckGoHomePage) }
  106. }
  107. When(~/I search for "(.*)"/) { String query ->
  108. page.search.value(query)
  109. page.searchButton.click()
  110. }
  111. Then(~/I can see some results/) { ->
  112. assert at(DuckDuckGoResultsPage)
  113. }
  114. Then(~/the first link should be "(.*)"/) { String text ->
  115. waitFor { page.results }
  116. assert page.resultLink(0).text()?.contains(text)
  117. }
  118. ----
  119. === Using pre-built steps
  120. The {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:
  121. ----
  122. When I go to the duck duck go home page
  123. And I enter "cucumber-jvm github" into the search field
  124. And I click the search button
  125. Then the results table 1st row link matches /cucumber\/cucumber-jvm · GitHub.*/
  126. ----
  127. See {geb-cucumber} for more examples.
  128. geb-cucumber also does Geb binding automatically, so if it is picked up you don't need to do it yourself as above.
  129. === Example project
  130. The following project has examples of both writing your own steps and using geb-cucumber:
  131. * link:https://github.com/geb/geb-example-cucumber-jvm[geb-example-cucumber-jvm]