Search icon
Arrow left icon
All Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletters
Free Learning
Arrow right icon
Mastering play framework for scala

You're reading from  Mastering play framework for scala

Product type Book
Published in May 2015
Publisher
ISBN-13 9781783983803
Pages 274 pages
Edition 1st Edition
Languages
Author (1):
Shiti Saxena Shiti Saxena
Profile icon Shiti Saxena

Table of Contents (21) Chapters

Mastering Play Framework for Scala
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
1. Getting Started with Play 2. Defining Actions 3. Building Routes 4. Exploring Views 5. Working with Data 6. Reactive Data Streams 7. Playing with Globals 8. WebSockets and Actors 9. Testing 10. Debugging and Logging 11. Web Services and Authentication 12. Play in Production 13. Writing Play Plugins Index

Chapter 9. Testing

Testing is the process of cross-checking the implementation of an application/process. It brings its shortcomings out into the open. It can be extremely handy when you are upgrading/downgrading one or more dependencies. Tests can be classified into various categories based on different programming practices, but in this chapter, we will only discuss two types of tests:

  • Unit tests: These are tests that check the functionality of a specific section of code

  • Functional tests: These are tests that check a specific action, mostly written to verify working code with regard to a use case or scenario

In the following sections, we will see the different ways in which we can test a Play application using Specs2 and ScalaTest.

Note

The tests using either of the Specs2 and ScalaTest libraries are similar. The major difference is in the keywords, syntax, and style. Since different developers can have different preferences, in this chapter, tests are defined using both libraries and for...

The setup for writing tests


Play is packaged with Specs2, since this is the library used internally for testing it. It provides support to test applications using Specs2 by default, that is, no additional library dependency is required.

Using ScalaTest earlier was difficult but now, Play also provides helpers for using ScalaTest. Although it is picked up from transitive dependencies, we need to add a library dependency to use the helper methods:

val appDependencies = Seq(
  "org.scalatestplus" %% "play" % "1.1.0" % "test"
)

Note

The 1.1.0 version of org.scalatestplus.play is compatible with Play 2.3.x. It is better to check the compatibility when working with another version of Play at http://www.scalatest.org/plus/play/versions.

Unit testing


Unit tests can be written as in any Scala project. For example, suppose we have a utility method isNumberInRange that takes a string and checks if it's a number in the range [0,3600]. It is defined as follows:

def isNumberInRange(x:String):Boolean = {
    val mayBeNumber = Try{x.toDouble}
    mayBeNumber match{
      case Success(n) => if(n>=0 && n<=3600) true else false
      case Failure(e) => false
    }
  }

Let's write a unit test to check this function using Specs2:

class UtilSpec extends Specification {

    "range method" should {

    "fail for Character String" in {
      Util.isNumberInRange("xyz") should beFalse
    }

    "fail for Java null" in {
      Util.isNumberInRange(null) should beFalse
    }

    "fail for Negative numbers" in {
      Util.isNumberInRange("-2") should beFalse
    }

    "pass for valid number" in {
      Util.isNumberInRange("1247") should beTrue
    }

    "pass for 0" in {
      Util.isNumberInRange("0") should beTrue...

Dissecting PlaySpecification


The tests written using Specs2 can also be written as follows:

class UtilSpec extends PlaySpecification {...}

PlaySpecification is a trait that provides the required helper methods to test a Play application using Specs2. It is defined as:

trait PlaySpecification extends Specification
    with NoTimeConversions
    with PlayRunners
    with HeaderNames
    with Status
    with HttpProtocol
    with DefaultAwaitTimeout
    with ResultExtractors
    with Writeables
    with RouteInvokers
    with FutureAwaits {
}

Let's scan through the API exposed by each of these traits to understand its significance:

  • Specification and NoTimeConversions are traits of Specs2. NoTimeConversions can be used to deactivate the time conversions.

  • PlayRunners provides helper methods to execute a block of code in a running application or server with or without specifying the browser.

  • HeaderNames and Status define constants for all the standard HTTP headers and HTTP status codes, respectively...

Unit testing a controller


We might have a simple project with a User model and UserRepo, defined as follows:

case class User(id: Option[Long], loginId: String, name: Option[String],
  contactNo: Option[String], dob: Option[Long], address: Option[String])
 
object User{
  implicit val userWrites = Json.writes[User]
}

trait UserRepo {
  def authenticate(loginId: String, password: String): Boolean

  def create(u: User, host: String, password: String): Option[Long]

  def update(u: User): Boolean

  def findByLogin(loginId: String): Option[User]

  def delete(userId: Long): Boolean

  def find(userId: Long): Option[User]

  def getAll: Seq[User]

  def updateStatus(userId: Long, isActive: Boolean): Int

  def updatePassword(userId: Long, password: String): Int
}

In this project, we need to test a getUser method of UserController—a controller that is defined to access user details, which are handled by the user model, where UserController is defined as follows:

object UserController extends Controller...

Functional testing


Let's look at some of Play's test cases to see how to use the helper methods. For example, consider the DevErrorPageSpec test, which is defined as follows:

object DevErrorPageSpec extends PlaySpecification{

  "devError.scala.html" should {

    val testExceptionSource = new play.api.PlayException.ExceptionSource("test", "making sure the link shows up") {
      ...
    }
    ….
    "show prod error page in prod mode" in {
      val fakeApplication = new FakeApplication() {
        override val mode = play.api.Mode.Prod
      }
      running(fakeApplication) {
        val result = DefaultGlobal.onError(FakeRequest(), testExceptionSource)
        Helpers.contentAsString(result) must contain("Oops, an error occurred")
      }
    }
  }
}

This test starts FakeApplication with the Prod mode and checks the response when FakeRequest encounters an exception.

FakeApplication extends an application and is defined as follows:

case class FakeApplication(config: Map[String, Any] = Map...

Summary


In this chapter, we saw how a Play application can be tested using Specs2 or ScalaTest. We have also come across the different helper methods available to simplify testing a Play application. In the unit testing section, we discussed the different approaches that can be taken while designing models and controller based on the preferred testing process using traits with defined methods or dependency injection. We also discussed the functional testing of a Play application within the context of an application with a test server and within a browser using Selenium WebDrivers.

In the next chapter, we will discuss debugging and logging in to your Play application.

lock icon The rest of the chapter is locked
You have been reading a chapter from
Mastering play framework for scala
Published in: May 2015 Publisher: ISBN-13: 9781783983803
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime}