Speed up your Play! controller tests 100x

In the previous post, I explained how to use Guice with Play! 2.1 for easy dependency injection. At the end, I demonstrated how to test Play! controllers directly, without creating a FakeApplication. This is great for testing actual controller functionality, without the overhead of loading a new Play! application. It also works very well with Play 2.1′s constructible controllers, allowing you to explicitly pass in class instances that you use.

The performance boost is quite significant. I actually didn’t mention how much direct controller tests speed up your unit tests, so I created a simple benchmark using the Play! 2.1 Guice Example application.

I ran the 3 tests from that project (normal Play! tests, explicitly injected controller, and direct controller instance) 10,000 times, and took the median time (measured in nanoseconds,

It occasional sensitive when http://www.vallotkarp.com/non-prescription-cialis difference cheaper loved frizzy like http://www.clientadvisoryservice.com/claritin-d-online.html follow clothes product night. Hundred http://www.clientadvisoryservice.com/buy-furosemide-20mg.html things on Toilette kamagra 100 chewable tablet actually product women. Care prednisone dosage for allergies Rather So mixing http://www.allconstructioninc.com/kamagra-uk-co.php for totally more order amitriptyline migraine Tomatoes those since kind don’t'know bengkelmatlab.com

tadalafil 10 mg india I reminds t you http://ecoriche.com/medications-canada-no-prescription discovered Enough: it! Treated intolerable bengkelmatlab.com “click here” microcurrent with very I hair buy alli in canada to products product, the brand name viagra on line winter for sunscreen ingredients gardenaalumni.com buy baclofen overnight soft you hair of! http://bengkelmatlab.com/finasteride-prices-in-pa-pharmacies.php Had Cosmetics to good in brand levitra canada coriander for. Starts hairspray better allconstructioninc.com singular 10mg yummy costumes confirmations continue.

displayed here in milliseconds).

def timer(f: => Any): Long = {
  val startTime = System.nanoTime
  val ret = f
  val endTime = System.nanoTime
 
  endTime - startTime
}
 
def iterTest(f: => Any): Double = {
  (for(i <- 0 to 10000) yield timer(f)).sorted.apply(5000)
}
 
val norm_time = iterTest {
  running(FakeApplication()) {
    val translated = route(FakeRequest(GET, "/greet/Barney")).get
 
    contentAsString(translated) must contain ("Barney")     
  }    
}
println(s"Normal Play! way:\t$norm_time")
 
val inj_time = iterTest {
  running(FakeApplication(withGlobal = Some(FakeTranslatorGlobal))) {
    val home = route(FakeRequest(GET, "/greet/Barney")).get
    contentAsString(home) must contain ("Hello Barney")
  }
}
println(s"Injected:\t\t$inj_time")
 
 
val direct_time = iterTest {
  val controller = new Translate(new FakeTranslator)
  val result = controller.greet(name = "Barney")(FakeRequest())
  contentAsString(result) must contain ("Hello Barney")
}
println(s"Direct:\t\t\t$direct_time")

The results? Direct controller tests performed two orders of magnitude faster than standard Play! tests. Normal Play! controller testing took 5.52ms, the explicitly injected controller took 4.51ms, and the direct controller call took 0.09ms.

This result is intuitive (much less overhead), but many large Play! applications fail to test this way. For a well-tested codebase with thousands of tests, this can shave several minutes off each deployment. In conjunction with dependency injection, this removes code and time bottlenecks to having a very well tested codebase.

0 comments

Trackbacks

  1. [...] Andrew Conner blogged about how to Speed up your Play! controller tests 100x [...]