4

I've never been 100% happy with the way I test Play applications. I've settled on an approach that I've been using for a while but it feels a bit hacky and that I'm missing something simple.

I use SQLite and have a single database configuration called default that I override in my test conf file:

application.conf

slick.dbs.default {
  profile = "slick.jdbc.SQLiteProfile$"
  db.driver = "org.sqlite.JDBC"
  db.url = "jdbc:sqlite:defaultDB.sqlite"
}

application.test.conf

include "application.conf"

play = {
  evolutions.enabled = false
}

slick.dbs.default {
  profile = "slick.jdbc.SQLiteProfile$"
  db.driver = "org.sqlite.JDBC"
  db.url = "jdbc:sqlite:memory;DB_CLOSE_DELAY=-1"
}

As you can see from my test configuration I like using an in-memory database for testing. I like using in-memory db's for testing for a few reasons

  1. I find it easier to manage test data in SQL files
  2. The database is automatically dumped after the tests have finished
  3. It's easy to move to another dev machine

I have 2 sets of evolution scripts. One for the dev/prod database stored under evolutions/default/<n>.sql and another set for the test database stored under evolutions/test/<n>.sql.

In my tests I use the Injecting trait to inject the database into the test suite and run the test evolutions, like this:

[TestName]Spec.scala

class MySpec extends PlaySpec with BeforeAndAfterAll with GuiceOneAppPerSuite with Injecting  {
  import ThisClassLoaderEvolutionsReader.evolutions

  override def beforeAll(): Unit = {
    super.beforeAll()

    val db = inject[DBApi].database("default")
    Evolutions.applyEvolutions(db, SimpleEvolutionsReader.forDefault(evolutions("test") :_*))
  }

  override def afterAll(): Unit = {
    super.afterAll()

    val db = inject[DBApi].database("default")
    Evolutions.cleanupEvolutions(db)
  }

  "My Test" should {
    "do something useful" in {
      ...
    }
  }

}

Things I don't like about this approach:

  1. I store my test data in evolution scripts, it works quite well but it seems wrong.
  2. I need to maintain 2 sets of evolution scripts.
  3. In order to run tests I need an Application so that I can inject the database. That seems too "heavy".

Does my approach seem sensible? Is there a generally agreed upon method for handling tests in Play?

Oli
  • 1,112
  • 1
  • 10
  • 25

0 Answers0