I have a scenario where I want to test if a call really returned
before X seconds, throwing an error if it takes more than that. If i
were using junit i would use Timout rule [1].
Is org.scalatest.concurrent.Conductor the right way to go when using scalatest?
[1] http://kentbeck.github.com/junit/javadoc/latest/org/junit/rules/Timeout.html
--
Fabio Cechinel Veronez
Conductor isn't really meant for that, no. What you need is a timeout
construct, which I didn't want to add to ScalaTest until someone asked
for it from whom I could get requirements. In the meantime, you'll
need to roll your own. I don't have time today to look into it, but
I'd suggest you look at java.util.concurrent, which probably has
something that will let you run a bit of code with a timeout. Anyone
else have some suggestions?
BIll
> --
> You received this message because you are subscribed to the Google
> Groups "scalatest-users" group.
> To post to this group, send email to scalate...@googlegroups.com
> To unsubscribe from this group, send email to
> scalatest-use...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/scalatest-users?hl=en
> ScalaTest itself, and documentation, is available here:
> http://www.artima.com/scalatest
>
--
Bill Venners
Artima, Inc.
http://www.artima.com
Thanks for your suggestion for Fabio. As to your question about how
best to run all tests in the same suite with a timeout, I'd probably
suggest overriding withFixture rather than runTests. I'll come back to
that, but first let me run by you and Fabio what I'd been imagining
might make sense to add to ScalaTest. I wanted to wait until someone
asked so I could have a real use case.
For ScalaTest I had been imagining a Timeout or Timeouts trait that
has a withTimeout method, that would take an implicit config parameter
that determines the timeout, but it could be overridden. So the client
code would look like:
withTimeout {
// test code you want to execute within the default timeout
}
withTimeout (1000) {
// Test code you'd want to execute within a 1000 millisecond timeout
}
You could also override for all uses of withTimeout in scope by
overriding the implicit
implicit override val timeoutConfig = new TimeoutConfig(100) // define
a new default
withTimeout {
// now this has to complete within 100 milliseconds
}
As Sean suggested, if you want to just do this in a few tests you can
just wrap those places with a withTimeout call. If you want all tests
to run with a timeout, I'd put it in withFixture. This is described,
for example, here (scroll down a bit until you see Overriding
withFixture(NoArgTest)):
http://www.scalatest.org/scaladoc-1.6.1/org/scalatest/Suite.html#sharedFixtures
override def withFixture(test: NoArgTest) {
withTimeout {
test()
}
}
If it times out, it will be reported as a test failure, which I
suspect is what most people would want.
One question I have is should withTimeout actually return a value that
results from the code passed to it. Seems like it would make it more
generally useful, and people who don't care would just ignore the
result.
How does that sound for your use case, Fabio? In fact, if you could
elaborate a bit more on exactly what you're trying to do that you want
to make sure happens within a time period that would be useful to
know.
Thanks.
Bill
Ack, I wrote this this morning and thought I'd sent it out. Found it
just now sitting here. Sorry for the delay.
On the second subject, you can get durations printed out with the
following in (old) sbt:
Seq(TestArgument(TestFrameworks.ScalaTest, "-oD"))
http://www.scalatest.org/scaladoc-1.6.1/#org.scalatest.tools.ScalaTestFramework
Sorry I suspect that may be for sbt 0.9.x rather than 0.10.x. Can
someone post what it is for sbt 0.10.x?
On the first subject, timeouts, can you let me know what you'd like to
see happen when the timeout occurs? My guess is you'd want to see a
test failure. That means you're using timeouts to ensure a test
doesn't take longer than a specified max.
Another thing it could do (in the next version of ScalaTest, where
I'll be adding the timeouts) is "cancel" the test, which would mean
that this time it took too long, and I don't consider that a failure,
but I just want to note it this time. Next time hopefully the network
will be faster and the test will finish within the timeout.
Thanks.
Bill
I have uploaded a new 1.8-SNAPSHOT with the timeouts functionality. It
is built with Scala 2.9.0 and deployed for 2.9.0, 2.9.0-1, and 2.9.1.
These are on oss.sonatype.org now, to which scala-tools.org is
redirecting. You can see them here:
https://oss.sonatype.org/content/repositories/snapshots/org/scalatest/
There are two main traits concerned with timeouts: Timeouts and
TimeLimitedTests.
Timeouts provides a failAfter method (in 2.0 there will also be a
cancelAfter added) that let's you specify a time limit for a bit of
code, like this:
failAfter(100) {
Thread.sleep(200)
}
The duration values are milliseconds. I added a TimeSugar trait that
you can use if you want to specify units:
import org.scalatest.TimeSugar._
failAfter(100 millis) {
Thread.sleep(200 millis)
}
If you're using a library that already already offers such sugar, you
can use it instead, so long as there's an implicit conversion from
that libraries result to a Long number of milliseconds.
The code is executed in the main test thread, the thread that invokes
failAfter, so you don't need to worry about synchronization. A second
thread is fired off inside a timer to keep track of the timeout, and
to attempt to interrupt the main thread if the timeout expires. An
interruption strategy is passed as an implicit parameter. More info is
here:
http://www.artima.com/docs-scalatest-1.8-14.Feb.2012/#org.scalatest.concurrent.Timeouts
The other main timeout trait is TimeLimitedTests. This trait overrides
withFixture and wraps each test in a failAfter call using a timeLimit
val that you must specify as a member. It passes a
defaultTestInterruptor that you can override. This trait lets you
specify a time limit for all tests in a suite. More info is here:
http://www.artima.com/docs-scalatest-1.8-14.Feb.2012/#org.scalatest.concurrent.TimeLimitedTests
Please give it a try and post feedback and suggestions to
scalatest-users. I plan to release all these new
concurrency/assynchrony tools in 1.8, which I plan to start RCing
around the end of February. So the more people who can try them out in
the meantime the better.
Thanks.
Bill
On Fri, Jun 17, 2011 at 12:57 PM, Fabio Cechinel Veronez
<fabio....@gmail.com> wrote: