如何使用 ScalaTest 编写验收测试?

发布于 2024-11-19 18:10:34 字数 141 浏览 2 评论 0原文

ScalaTest 有非常好的文档,但它们很短并且没有给出示例 验收测试。

如何使用 ScalaTest 为 Web 应用程序编写验收测试?

ScalaTest has very good documentation but they are short and do not give an example of
acceptance test.

How can I write acceptance test using ScalaTest for a web application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

蹲墙角沉默 2024-11-26 18:10:34

使用 Selenium 2 可以让你取得一些进展。我将 Selenium 2 WebDriver 与发现的 Selenium DSL 的变体结合使用 此处

最初,我更改了 DSL,以便更容易从 REPL 运行(见下文)。然而,构建此类测试的更大挑战之一是它们很快就会失效,然后成为维护的噩梦。

后来,我开始为应用程序中的每个页面创建一个包装类,并通过便捷的操作将要发送到该页面的事件映射到底层的 WebDriver 调用。这样,每当底层页面发生变化时,我只需要更改我的页面包装器,而不是更改整个脚本。这样,我的测试脚本现在以各个页面包装器上的调用来表示,其中每次调用都会返回一个反映 UI 新状态的页面包装器。看起来效果很好。

我倾向于使用 FirefoxDriver 构建测试,然后在将测试转移到我们的 QA 环境之前检查 HtmlUnit 驱动程序是否给出了可比较的结果。如果成立,那么我使用 HtmlUnit 驱动程序运行测试。

这是我对 Selenium DSL 的原始修改:

/**
 * Copied from [[http://comments.gmane.org/gmane.comp.web.lift/44563]], adjusting it to no longer be a trait that you need to mix in,
 * but an object that you can import, to ease scripting.
 *
 * With this object's method imported, you can do things like:
 *
 * {{"#whatever"}}: Select the element with ID "whatever"
 * {{".whatever"}}: Select the element with class "whatever"
 * {{"%//td/em"}}: Select the "em" element inside a "td" tag
 * {{":em"}}: Select the "em" element
 * {{"=whatever"}}: Select the element with the given link text
 */
object SeleniumDsl {

  private def finder(c: Char): String => By = s => c match {
    case '#' => By id s
    case '.' => By className s
    case '
 => By cssSelector s
    case '%' => By xpath s
    case ':' => By name s
    case '=' => By linkText s
    case '~' => By partialLinkText s
    case _ => By tagName c + s
  }

  implicit def str2by(s: String): By = finder(s.charAt(0))(s.substring(1))

  implicit def by2El[T](t: T)(implicit conversion: (T) => By, driver: WebDriver): WebElement = driver / (conversion(t))

  implicit def el2Sel[T <% WebElement](el: T): Select = new Select(el)

  class Searchable(sc: SearchContext) {
    def /[T <% By](b: T): WebElement = sc.findElement(b)

    def /?[T <% By](b: T): Box[WebElement] = tryo(sc.findElement(b))

    def /+[T <% By](b: T): Seq[WebElement] = sc.findElements(b)
  }

  implicit def scDsl[T <% SearchContext](sc: T): Searchable = new Searchable(sc)

}

Using Selenium 2 gets you some mileage. I'm using Selenium 2 WebDriver in combination with a variation of the Selenium DSL found here.

Originally, I changed the DSL in order to make it a little easier to run in from the REPL (see down below). However, one of the bigger challenges of building tests like these is that they quickly get invalidated, and then become a nightmare to maintain.

Later on, I started creating a wrapper class for every page in the application, with convenience operations mapping the event to be sent to that page to the underlying WebDriver invocations. That way, whenever the underling page is changing, I just need to change my page wrapper, rather than changing the entire script. With that, my test scripts are now expressed in terms of invocations on the individual page wrappers, where every invocation returns a page wrapper reflecting the new state of the UI. Seems to work out quite well.

I tend to build my tests with the FirefoxDriver and then before rolling the test to our QA environment check if the HtmlUnit driver is giving comparable results. If that holds, then I run the test using the HtmlUnit driver.

This was my original modification to the Selenium DSL:

/**
 * Copied from [[http://comments.gmane.org/gmane.comp.web.lift/44563]], adjusting it to no longer be a trait that you need to mix in,
 * but an object that you can import, to ease scripting.
 *
 * With this object's method imported, you can do things like:
 *
 * {{"#whatever"}}: Select the element with ID "whatever"
 * {{".whatever"}}: Select the element with class "whatever"
 * {{"%//td/em"}}: Select the "em" element inside a "td" tag
 * {{":em"}}: Select the "em" element
 * {{"=whatever"}}: Select the element with the given link text
 */
object SeleniumDsl {

  private def finder(c: Char): String => By = s => c match {
    case '#' => By id s
    case '.' => By className s
    case '
 => By cssSelector s
    case '%' => By xpath s
    case ':' => By name s
    case '=' => By linkText s
    case '~' => By partialLinkText s
    case _ => By tagName c + s
  }

  implicit def str2by(s: String): By = finder(s.charAt(0))(s.substring(1))

  implicit def by2El[T](t: T)(implicit conversion: (T) => By, driver: WebDriver): WebElement = driver / (conversion(t))

  implicit def el2Sel[T <% WebElement](el: T): Select = new Select(el)

  class Searchable(sc: SearchContext) {
    def /[T <% By](b: T): WebElement = sc.findElement(b)

    def /?[T <% By](b: T): Box[WebElement] = tryo(sc.findElement(b))

    def /+[T <% By](b: T): Seq[WebElement] = sc.findElements(b)
  }

  implicit def scDsl[T <% SearchContext](sc: T): Searchable = new Searchable(sc)

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文