Scala in test automation
Scala programming language provides a good mix between functional and object-oriented programming. It is used in projects, where pure functions and functional paradigms are crucial.
But how Selenium tests look like in Scala?
ScalaTest
The most widespread testing framework in Scala is ScalaTest. It provides a lot of functionality for writing unit and integration tests.
Implementation
As for the experiment, we will write a couple of UI tests for the current blog.
In order to implement the first basic tests you can follow the steps:
- Add necessary libraries to build.sbt
libraryDependencies += "org.scalatestplus" %% "selenium-3-141" % "3.2.7.0" % "test"
libraryDependencies += "org.scalatest" %% "scalatest-flatspec" % "3.2.7" % "test"
libraryDependencies += "org.scalatest" %% "scalatest-shouldmatchers" % "3.2.7" % "test"
libraryDependencies += "com.google.guava" % "guava" % "30.1.1-jre"
- Add pages objects. In our case, it will be all main pages for the blog: Home Page, Contact Page, About Page.
class HomePage(implicit val driver: ChromeDriver) extends Page {
val url = "https://alexromanov.github.io/"
val homePageLink: String = "//a[@href=\"/\"]"
val aboutPageLink: String = "//a[@href=\"/about/\"]"
val contactPageLink: String = "//a[@href=\"/contact/\"]"
}
If you want to have an access to "go to page" functionality in tests, you can extend your page class from Page trait and add URL variable.
- Add class with tests
class BlogTest extends AnyFlatSpec with BeforeAndAfterAll with Matchers with Eventually with WebBrowser {
implicit val webDriver: ChromeDriver = {
System.setProperty("webdriver.chrome.driver", "C:\\tools\\chromedriver_win32\\chromedriver.exe")
new ChromeDriver()
}
"User" should "be able to view latest blog post" in {
val homePage = new HomePage
go to homePage
val posts = findAll(CssSelectorQuery("div.post-preview")).toList
posts should have size 5
val latestPost = posts.head
latestPost.text should not be empty
}
"User" should "be able to open Contact Page" in {
val homePage = new HomePage
go to homePage
homePage.url should equal (currentUrl)
click on xpath(homePage.contactPageLink)
eventually {
currentUrl != homePage.url
}
val contactPage = new ContactPage
contactPage.url should equal (currentUrl)
}
"User" should "be able to send message to author" in {
val contactPage = new ContactPage
go to contactPage
contactPage.url should be (currentUrl)
textField(contactPage.nameField).value = "Reader"
click on id(contactPage.emailField)
enter("reader@mail.com")
click on id(contactPage.phoneField)
enter( "123456789")
textArea(contactPage.messageField).value = "Hello Author"
click on cssSelector(contactPage.sendButton)
}
override def afterAll(): Unit = {
quit()
}
}
For tests we use AnyFlatSpec and Should Matchers. It allows us to write assertions in a readable format with the Should keyword.
ScalaTest-Selenium provides a very nice wrapper against WebDriver. You just need to add WebBrowser trait. As a result, you will have methods such as "click on id()", "enter()", "close()", etc.
It also defines Webdriver instance as implicit value - so you don't need to pass driver whenever it is used (in tests or pages).
For adding an additional before and after logic we need to add the BeforeAndAfterAll trait and override desired methods. In our case, the afterAll() method is overridden - it will quit the driver after tests are finished.
Conclusion
As you can see, UI tests in Scala are very close to human-readable format with using Should matches and scalatest-selenium traits.
ScalaTest-Selenium provides a nice wrapper of WebDriver, but it is not extensible at first sight. Maybe, it will require a complete framework re-write.
But for simple UI tests, it is more than enough.
In the next articles, we will see even more interesting use cases of using Scala in test automation (also with Selenium)
Full code samples can be found at src/test/scala/ui package in code samples.
Top comments (0)