EzDevInfo.com

specs2

Software Specifications for Scala specs2.org

Parallel execution of tests

I've noticed that SBT is running my specs2 tests in parallel. This seems good, except one of my tests involves reading and writing from a file and hence fails unpredictably, e.g. see below.

Are there any better options than

  1. setting all tests to run in serial,
  2. using separate file names and tear-downs for each test?
class WriteAndReadSpec extends Specification{
  val file = new File("testFiles/tmp.txt")

  "WriteAndRead" should {
    "work once" in {
      new FileWriter(file, false).append("Foo").close
      Source.fromFile(file).getLines().toList(0) must_== "Foo"
    }
    "work twice" in {
      new FileWriter(file, false).append("Bar").close
      Source.fromFile(file).getLines().toList(0) must_== "Bar"
    }
  }

  trait TearDown extends After {
    def after = if(file.exists) file.delete
  }
}

Source: (StackOverflow)

running multiple tests within the same FakeApplication() in play 2.0 scala

I am trying to learn the unit tests in Play scala, but I am running into some issues. I am trying to run several tests on my models layer like this:

"User Model" should {
    "be created and retrieved by username" in {
        running(FakeApplication()) {
            val newUser = User(username = "weezybizzle",password = "password")
            User.save(newUser)
            User.findOneByUsername("weezybizzle") must beSome
        }
    }
    "another test" in {
        running(FakeApplication()) {
            // more tests involving adding and removing users
        }
    }
}

However when doing things this way, I fail to connect to the database on the second unit test, saying that the connection is closed. I tried to solve this by enclosing all the code in a block that runs on the same fake application, but that didn't work either.

  running(FakeApplication()) {
    "be created and retrieved by username" in {
        val newUser = User(username = "weezybizzle",password = "password")
        User.save(newUser)
        User.findOneByUsername("weezybizzle") must beSome
    }
    "another test" in {
        // more tests involving adding and removing users
    }
  }

Source: (StackOverflow)

Advertisements

Play! framework: customize which tests are run

I have a Play! 2 for Scala application, and I am using Specs2 for tests. I can run all tests with the test command, or a particular specification with test-only MyParticularSpec.

What I would like to do is mark some particular specifications, or even single methods inside a specification, in order to do things like:

  • running all tests that are not integration (that is, that do not access external resources)
  • running all tests that do not access external resources in write mode (but still running the reading tests)
  • running all tests but a given one

and so on.

I guess something like that should be doable, perhaps by adding some annotations, but I am not sure how to go for it.

Does there exist a mechanism to selectively run some tests and not other ones?

EDIT I have answered myself when using test-only. Still the command line option does not work for the test task. Following the sbt guide I have tried to create an additional sbt configuration, like

object ApplicationBuild extends Build {
  // more settings
  lazy val UnitTest = config("unit") extend(Test)
  lazy val specs = "org.scala-tools.testing" %% "specs" % "1.6.9" % "unit"

  val main = PlayProject(appName, appVersion, appDependencies, mainLang = SCALA)
    .configs(UnitTest)
    .settings(inConfig(UnitTest)(Defaults.testTasks) : _*)
    .settings(
      testOptions in UnitTest += Tests.Argument("exclude integration"),
      libraryDependencies += specs
    )
}

This works when I pass arguments without options, for instance when I put Test.Argument("plan"). But I was not able to find how to pass a more complex argument. I have tried

Tests.Argument("exclude integration")
Tests.Argument("exclude=integration")
Tests.Argument("-exclude integration")
Tests.Argument("-exclude=integration")
Tests.Argument("exclude", "integration")
Tests.Argument("exclude \"integration\"")

and probably more. Still not any clue what is the correct syntax.

Does anyone know how to pass arguments with options to specs2 from sbt?


Source: (StackOverflow)

Execute code before and after specification

I have simple specification with several cases in it:

class MySpec extends Specification {

  "Something" should {

    "case 1" in {
      ...
    }

    "case 2" in {
      ...
    }
  }
}

Now I need to start application, run all cases, and shutdown the application. Starting/stopping the application is time consuming and I don't want it to happen around each case.

How do I run code before cases are started and after all the cases have finished?


Source: (StackOverflow)

How do you run only a single Spec2 specification with SBT?

If you have 2 tests defined in your SBT project:

class Spec1 extends Specification {
  def is =
    "Tests for specification 1" ^
      p ^
      "Test case 1" ! todo ^
      end
}

and

class Spec2 extends Specification {
  def is =
    "Tests for specification 2" ^
      p ^
      "Test case 2" ! todo ^
      end
}

Then running test from inside SBT will execute both these tests. What is the simplest way to run only one of these tests?


Source: (StackOverflow)

specs/scalatest interaction issue in Play app

I am having a problem I really can't explain... It is in isolation in the project at https://github.com/betehess/play-scalatest.

When I run test, sbt gets stuck for a while and then throws this exception:

> test
[error] Uncaught exception when running tests: java.net.ConnectException: Connection timed out
Exception in thread "Thread-1" java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:196)
    at java.net.SocketInputStream.read(SocketInputStream.java:122)
    at java.net.SocketInputStream.read(SocketInputStream.java:210)
    at java.io.ObjectInputStream$PeekInputStream.peek(ObjectInputStream.java:2293)
    at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(ObjectInputStream.java:2473)
    at java.io.ObjectInputStream$BlockDataInputStream.refill(ObjectInputStream.java:2543)
    at java.io.ObjectInputStream$BlockDataInputStream.skipBlockData(ObjectInputStream.java:2445)
    at java.io.ObjectInputStream.skipCustomData(ObjectInputStream.java:1941)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1915)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1990)
    at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:500)
    at java.lang.Throwable.readObject(Throwable.java:914)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1017)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1798)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
    at sbt.React.react(ForkTests.scala:117)
    at sbt.ForkTests$$anonfun$mainTestTask$1$Acceptor$2$.run(ForkTests.scala:76)
    at java.lang.Thread.run(Thread.java:745)

Looks like sbt gets stuck in a blocking call with the forked environment at https://github.com/sbt/sbt/blob/0.13.5/main/actions/src/main/scala/sbt/ForkTests.scala#L117.

Some remarks:

  • I run Ubuntu 13.10 and Java HotSpot(TM) 64-Bit "1.7.0_65"
  • none of my colleagues can reproduce the problem on their machines...
  • the problem happens only when scalatest is on the classpath, even if not used here
  • the problem goes away if I don't use the PlayScala pluggin and add specs2 explicitly as a dependency
  • the problem goes away if I move the scalatest dependency into the main build.sbt

Source: (StackOverflow)

How to run specifications sequentially

I want to create few specifications that interoperate with database.

class DocumentSpec extends mutable.Specification with BeforeAfterExample {
  sequential

  def before() = {createDB()}
  def after() = {dropDB()}

  // examples
  // ...
}

Database is created and dropped before and after every example (which is executed sequentially). Everithing works as expected until there is only one spec that works with database. Because specifications are executed parallel, they interfere and fail.

I hope that I'm able to avoid this by instructing specs2 to run tests with side effects sequentially while keeping side effect free tests to run in parallel. Is it possible?


Source: (StackOverflow)

Unable to test controller using Action.async

I'm trying to test controller, which is using new Action.async. Following documentation I have excluded part under controller I want to test to separate trait with type reference:

trait UserController { this: Controller =>
  def index() = Action { /* snip */ }
  def register() = Action.async(parse.json) { request => /* snip */ }
}

Documentation states that I'm supposed to test it as:

object UsersControllerSpec extends PlaySpecification with Results {
  class TestController() extends Controller with UserController
    "index action" should {
      "should be valid" in {
        val controller = new TestController()
        val result: Future[SimpleResult] = controller.index().apply(FakeRequest())
        /* assertions */
      }
    }
  }
}

For index() method it works perfectly, unfortunately I'm not able to do the same with register(), as applying FakeRequest on it returns instance of Iteratee[Array[Byte], SimpleResult]. I've noticed it has run() method that returns Future[SimpleResult] but no matter how I build FakeRequest it returns with 400 without any content or headers. Seems to me like content of FakeRequest is disregarded at all. Am I supposed to feed request body to iteratee somehow and then run it? I couldn't find any example how could I do that.


Source: (StackOverflow)

Play 2.0 FakeApplication setup with test configuration

I have a specs2 test which uses a FakeApplication and an embedded mongodb database.

def inMemoryMongoDatabase(name: String = "default"): Map[String, String] = {
    val dbname: String = "play-test-" + scala.util.Random.nextInt
    Map(
        ("mongodb." + name + ".db" -> dbname),
        ("mongodb." + name + ".port" -> EmbeddedMongoTestPort.toString))
}

override def around[T <% Result](t: => T) = {
    running(FakeApplication(additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) {
        t // execute t inside a http session
    }
}

The FakeApplication uses the default application.conf configuration in the conf directory and additional configuration for the test databases that are created for each test.
This was working find until we setup a mongodb replicat set. Now the application.conf contains configuration for this replicat set

mongodb.default.replicaset {
host1.host = "localhost"
host1.port = 27017
host2.host = "localhost"
host2.port = 27018
host3.host = "localhost"
host3.port = 27019
}

As the FakeApplication uses the default configuration the tests fail because the hosts of the replicaset cannot be found. I want to have a different configuration for my tests, basically remove the mongodb.default.replicaset entry. If mongodb.default.replicaset were a simple Map[String, String] that would be easy as I could just add it to the additonalConfiguration but when I try to do that it fails because the expected value type is not a String but an Object. I have also tried to provide a separate test.conf file to the FakeApplication via the path parameter.

override def around[T <% Result](t: => T) = {
    running(FakeApplication(path = new java.io.File("conf/test.conf"), additionalConfiguration = inMemoryMongoDatabase(), additionalPlugins = Seq("se.radley.plugin.salat.SalatPlugin"))) {
        t // execute t inside a http session
    }
}

That didn't work either as it didn't load any config.

I would greatly appreciate any help. Thanks.

Chris


Source: (StackOverflow)

BDD in Scala - Does it have to be ugly?

I've used lettuce for python in the past. It is a simple BDD framework where specs are written in an external plain text file. Implementation uses regex to identify each step, proving reusable code for each sentence in the specification.

Using scala, either with specs2 or scalatest I'm being forced to write the the specification alongside the implementation, making it impossible to reuse the implementation in another test (sure, we could implement it in a function somewhere) and making it impossible to separate the test implementation from the specification itself (something that I used to do, providing acceptance tests to clients for validation).

Concluding, I raise my question: Considering the importance of validating tests by clients, is there a way in BDD frameworks for scala to load the tests from an external file, raising an exception if a sentence in the test is not implemented yet and executing the test normally if all sentences have been implemented?


Source: (StackOverflow)

How do I run Scala + specs2 from the command line?

I'm a completely newbie Scala programmer, and I have no previous experience with Java; I come from ruby. I'm trying to run my first TDD sample program. I'm planning something very small, with maybe 5 or 6 tests. I'm trying to use the specs2 lib. I have no IDE, I usually program with vim and execute stuff from the command line.

How do I work with scala & specs2 on my little .scala file from the command line?

In the Quick Start they mention this:

scala -cp ... specs2.run HelloWorldSpec
  1. I don't have any idea what that elipsis (...) is standing for. What do I have to put there?
  2. That command references (I assume) a file called specs2.run. But on the downloads section I only get a .jar file. Where is specs2.run?
  3. In the dependencies section I'm given between two technologies - sbt and maven (I googled for them, didn't know them before). Do I have to use sbt/maven no matter what? Can't I just use a console command? It's only 1 file with 5 tests.
  4. I'm aware that there is a sample app, but again it comes with no instructions on how to run it. I think it comes prepared to work with sbt and maven. I would rather not have to learn to use any of those just to make a quick test. Is it possible?

Thanks a lot.


Source: (StackOverflow)

Why is this specs2 test using Mockito passing?

Suppose I had this interface and class:

abstract class SomeInterface{
  def doSomething : Unit
}

class ClassBeingTested(interface : SomeInterface){
  def doSomethingWithInterface : Unit = {
    Unit
  }
}

Note that the doSomethingWithInterface method does not actually do anything with the interface.

I create a test for it like this:

import org.specs2.mutable._
import org.specs2.mock._
import org.mockito.Matchers
import org.specs2.specification.Scope

trait TestEnvironment extends Scope with Mockito{
  val interface = mock[SomeInterface]
  val test = new ClassBeingTested(interface)
}

class ClassBeingTestedSpec extends Specification{
  "The ClassBeingTested" should {
    "#doSomethingWithInterface" in {
      "calls the doSomething method of the given interface" in new TestEnvironment {
        test.doSomethingWithInterface
        there was one(interface).doSomething
      }
    }
  }
}

This test passes. Why? Am I setting it up wrong?

When I get rid of the scope:

class ClassBeingTestedSpec extends Specification with Mockito{
  "The ClassBeingTested" should {
    "#doSomethingWithInterface" in {
      "calls the doSomething method of the given interface" in {
        val interface = mock[SomeInterface]
        val test = new ClassBeingTested(interface)
        test.doSomethingWithInterface
        there was one(interface).doSomething
      }
    }
  }
}

The test fails as expected:

[info]   x calls the doSomething method of the given interface
[error]      The mock was not called as expected: 
[error]      Wanted but not invoked:
[error]      someInterface.doSomething();

What is the difference between these two tests? Why does the first one pass when it should fail? Is this not an intended use of Scopes?


Source: (StackOverflow)

How can i skip a test in specs2 without matchers?

I am trying to test some db dependent stuff with specs2 in scala. The goal is to test for "db running" and then execute the test. I figured out that i can use orSkip from the Matcher class if the db is down.

The problem is, that i am getting output for the one matching condition (as PASSED) and the example is marked as SKIPPED. What i want instead: Only execute one test that is marked as "SKIPPED" in case the test db is offline. And here is the code for my "TestKit"

package net.mycode.testkit

import org.specs2.mutable._
import net.mycode.{DB}


trait MyTestKit {

  this: SpecificationWithJUnit =>

  def debug = false

  // Before example
  step {
    // Do something before
  }

  // Skip the example if DB is offline
  def checkDbIsRunning = DB.isRunning() must be_==(true).orSkip

  // After example
  step {
    // Do something after spec
  }
}

And here the code for my spec:

package net.mycode

import org.specs2.mutable._
import net.mycode.testkit.{TestKit}
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner

@RunWith(classOf[JUnitRunner])
class MyClassSpec extends SpecificationWithJUnit with TestKit with Logging {

  "MyClass" should {
    "do something" in {
      val sut = new MyClass()
      sut.doIt must_== "OK"
    }

  "do something with db" in {
    checkDbIsRunning

    // Check only if db is running, SKIP id not
  }
}

Out now:

Test MyClass should::do something(net.mycode.MyClassSpec) PASSED
Test MyClass should::do something with db(net.mycode.MyClassSpec) SKIPPED
Test MyClass should::do something with db(net.mycode.MyClassSpec) PASSED

And output i want it to be:

Test MyClass should::do something(net.mycode.MyClassSpec) PASSED
Test MyClass should::do something with db(net.mycode.MyClassSpec) SKIPPED

Source: (StackOverflow)

Integrate Specs2 results with Jenkins

I want to integrate the Specs2 test results with Jenkins.

I was added the below properties in sbt:

resolver:

"maven specs2"      at  "http://mvnrepository.com/artifact"

libraryDependencies:

"org.specs2"              %% "specs2"            % "2.0-RC1"                  % "test",

System Property:

testOptions in Test += Tests.Setup(() => System.setProperty("specs2.outDir", "/target/specs2-reports"))              //Option1

//testOptions in Test += Tests.Setup(() => System.setProperty("specs2.junit.outDir", "/target/specs2-reports"))    //Option2

testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "console", "junitxml")

If I run the below command, it is not generating any specs reports in the above mentioned directory("/target/specs2-reports").

sbt> test

If I run the below command, it is asking for the directory as shown in the below error message:

sbt> test-only -- junitxml

[error] Could not run test code.model.UserSpec: java.lang.IllegalArgumentException: junitxml requires directory to be specified, example: junitxml(directory="xxx")

And it is working only if I give the directory as shown below:

sbt> test-only -- junitxml(directory="\target\specs-reports")

But sometimes its not generating all the specs report xmls (some times generating only one report, sometimes only two reports etc.).

If I give test-only -- junitxml(directory="\target\specs-reports") in the jenkins it is giving the below error.

[error] Not a valid key: junitxml (similar: ivy-xml)
[error] junitxml(
[error]         ^

My main goal is, I want to generate the consolidated test reports in junit xml format and integrate with Jenkins. Kindly help me to solve my problem.

Best Regards,

Hari


Source: (StackOverflow)

Play Framework 2 scala specs2 mockito, how do I write a mocking unit test

So the play framework talks about having specs2 and specs2 having mockito

I want to use mockito to write a test where the template that the controller invokes is a mockito mock.

All the doc's I've found so far are java implementations where you call the mock static function and give it the Mocked class as a generics argument.

From what I can tell the mock function is not exposed by default within a specification, so how do I create a mockito mock?

Please give an example that includes both creating the mock, and asserting the mock is called with certain arguments


Source: (StackOverflow)