How to display entire stack trace for thrown exceptions from ScalaCheck tests? - scala

I'm running ScalaCheck tests in sbt, and if my test fails because the code under test throws an exception, the test report shows the failed test, the thrown exception and the message, but not the entire stack trace (note the mere Exception: java.lang.NullPointerException: exception exception message below).
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to scalacheck (in build file:/Users/jacek/sandbox/scalacheck/)
[info] Updating {file:/Users/jacek/sandbox/scalacheck/}scalacheck...
[info] Resolving jline#jline;2.11 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/scalacheck/target/scala-2.11/test-classes...
[info] ! String.throw exception: Exception raised on property evaluation.
[info] > ARG_0: ""
[info] > Exception: java.lang.NullPointerException: exception
[error] Error: Total 1, Failed 0, Errors 1, Passed 0
[error] Error during tests:
[error] StringSpecification
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 5 s, completed Jun 25, 2014 3:25:47 AM
I found https://groups.google.com/forum/#!msg/scalacheck/AGBgE_JlqpI/B2eSG84_QzYJ from 2008 which seems to report the same issue, and indicates it should be fixed in the next release. I'm currently using the latest release 1.11.4.
I also found http://www.scala-sbt.org/release/docs/Testing.html which indicates sbt has a testOptions key which I suppose seems reasonable to use, and I know ScalaTest has a setting for full stack traces, "-F", but that doesn't work for ScalaCheck. Even the example from the above page, testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-d", "-g") gives me an error:
[error] Could not run test org.example.myproject.MyTestClass: java.lang.Exception: [1.1] failure: option name expected
[error]
[error] -d -g
[error] ^
How do I use these test arguments, is there a list of these arguments anywhere, and finally, is it possible to get a stacktrace out of it all, or am I chasing a red herring?

tl;dr There's no support for verbosity under sbt with the released version of ScalaCheck. You'd have to build a version from the sources yourself to have the feature.
The available options for ScalaCheck are described in Test Execution:
Available options:
-workers, -w: Number of threads to execute in parallel for testing
-minSize, -n: Minimum data generation size
-verbosity, -v: Verbosity level
-minSuccessfulTests, -s: Number of tests that must succeed in order to pass a property
-maxDiscardRatio, -r: The maximum ratio between discarded and succeeded tests allowed before ScalaCheck stops testing a property. At least minSuccessfulTests will always be tested, though.
-maxSize, -x: Maximum data generation size
The source code of org.scalacheck.util.Pretty tells us more about the different levels of vebosity:
implicit def prettyThrowable(e: Throwable) = Pretty { prms =>
val strs = e.getStackTrace.map { st =>
import st._
getClassName+"."+getMethodName + "("+getFileName+":"+getLineNumber+")"
}
val strs2 =
if(prms.verbosity <= 0) Array[String]()
else if(prms.verbosity <= 1) strs.take(5)
else strs
e.getClass.getName + ": " + e.getMessage / strs2.mkString("\n")
}
So, 0 gives nothing, 1 takes 5 lines out of a stack trace, whereas a number greater than 1 gives you the entire stack trace as follows:
➜ scalacheck scala -cp .:/Users/jacek/.ivy2/cache/org.scalacheck/scalacheck_2.11/jars/scalacheck_2.11-1.11.4.jar StringSpecification -verbosity 3
+ String.startsWith: OK, passed 100 tests.
Elapsed time: 0.242 sec
! String.concatenate: Falsified after 0 passed tests.
> ARG_0: ""
> ARG_1: ""
Elapsed time: 0.003 sec
+ String.substring: OK, passed 100 tests.
Elapsed time: 0.126 sec
! String.throw exception: Exception raised on property evaluation.
> ARG_0: ""
> Exception: java.lang.NullPointerException: exception
StringSpecification$$anonfun$14.apply(StringSpecification.scala:19)
StringSpecification$$anonfun$14.apply(StringSpecification.scala:18)
scala.Function1$$anonfun$andThen$1.apply(Function1.scala:55)
org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:622
)
org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:622
)
org.scalacheck.Prop$.secure(Prop.scala:473)
org.scalacheck.Prop$$anonfun$forAllShrink$1.org$scalacheck$Prop$$anonfun$$r
esult$1(Prop.scala:622)
org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:659)
org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:616)
org.scalacheck.Prop$$anon$1.apply(Prop.scala:309)
org.scalacheck.Test$.org$scalacheck$Test$$workerFun$1(Test.scala:335)
org.scalacheck.Test$$anonfun$org$scalacheck$Test$$worker$1$1.apply(Test.sca
la:316)
org.scalacheck.Test$$anonfun$org$scalacheck$Test$$worker$1$1.apply(Test.sca
la:316)
org.scalacheck.Test$.check(Test.scala:385)
org.scalacheck.Test$$anonfun$checkProperties$1.apply(Test.scala:402)
org.scalacheck.Test$$anonfun$checkProperties$1.apply(Test.scala:395)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala
:245)
scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala
:245)
scala.collection.immutable.List.foreach(List.scala:383)
scala.collection.generic.TraversableForwarder$class.foreach(TraversableForw
arder.scala:35)
scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
scala.collection.AbstractTraversable.map(Traversable.scala:104)
org.scalacheck.Test$.checkProperties(Test.scala:395)
org.scalacheck.Properties.mainRunner(Properties.scala:62)
org.scalacheck.Prop$class.main(Prop.scala:106)
org.scalacheck.Properties.main(Properties.scala:27)
StringSpecification.main(StringSpecification.scala:-1)
sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:
-2)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:5
7)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImp
l.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
scala.reflect.internal.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClas
sLoader.scala:68)
scala.reflect.internal.util.ScalaClassLoader$class.asContext(ScalaClassLoad
er.scala:31)
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.asContext(Scala
ClassLoader.scala:99)
scala.reflect.internal.util.ScalaClassLoader$class.run(ScalaClassLoader.sca
la:68)
scala.reflect.internal.util.ScalaClassLoader$URLClassLoader.run(ScalaClassL
oader.scala:99)
scala.tools.nsc.CommonRunner$class.run(ObjectRunner.scala:22)
scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:39)
scala.tools.nsc.CommonRunner$class.runAndCatch(ObjectRunner.scala:29)
scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:39)
scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:72)
scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:94)
scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:103)
scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala:-1)
Elapsed time: 0.000 sec
You're right that the documentation for sbt is incorect. There are no "-d", "-g" options and I believe they're simply a copy-and-paste error in the documentation. It was already fixed in a pull request that's soon to be accepted.
The verbosity option is not supported under sbt in the recent version of ScalaCheck 1.11.4. The following is the entire build definition of a sample project.
build.sbt
scalaVersion := "2.11.1"
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.11.4" % "test"
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "3")
Even when the verbosity parameter is properly specified in build.sbt, test execution won't print more than a single line.
➜ scalacheck xsbt test
[info] Loading global plugins from /Users/jacek/.sbt/0.13/plugins
[info] Set current project to scalacheck (in build file:/Users/jacek/sandbox/scalacheck/)
[info] + String.startsWith: OK, passed 100 tests.
[info] ! String.concatenate: Falsified after 0 passed tests.
[info] > ARG_0: ""
[info] > ARG_1: ""
[info] + String.substring: OK, passed 100 tests.
[info] ! String.throw exception: Exception raised on property evaluation.
[info] > ARG_0: ""
[info] > Exception: java.lang.NullPointerException: exception
[error] Error: Total 4, Failed 1, Errors 1, Passed 2
[error] Error during tests:
[error] StringSpecification
[error] (test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 1 s, completed Jun 25, 2014 2:57:08 AM
The reason is that org.scalacheck.ScalaCheckFramework has the following implementation and assumes verbosity always be 0:
override def onTestResult(n: String, r: Test.Result) = {
for (l <- loggers) {
import Pretty._
l.info(
(if (r.passed) "+ " else "! ") + n + ": " + pretty(r, Params(0))
)
}
handler.handle(asEvent((n,r)))
}
A pull request to fix it has already been accepted to the repo under Support verbosity under sbt for TestFrameworks.ScalaCheck. You'd have to build ScalaCheck yourself with sbt publishLocal in the directory where you cloned the repo. Don't forget to use 1.12.0-SNAPSHOT version in build.sbt to pick up the changes.

Since the issue that Jacek Laskowski noted has been resolved, you can now get stack traces from ScalaCheck in sbt by adding a line to your build.sbt file to set ScalaCheck's verbosity level.
testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "2")
As Jacek Laskowski noted, a verbosity of 0 will give you just the exception.
[info] ! RandomAccessFile.readWriteInt: Exception raised on property evaluation.
[info] > ARG_0: 0
[info] > ARG_0_ORIGINAL: -2073744736
[info] > Exception: java.lang.UnsupportedOperationException: null
A verbosity of 1 will give you the first five lines of the stack trace.
[info] ! RandomAccessFile.readWriteInt: Exception raised on property evaluation.
[info] > ARG_0: 0
[info] > ARG_0_ORIGINAL: 2147483647
[info] > Exception: java.lang.UnsupportedOperationException: null
[info] java.nio.IntBuffer.array(IntBuffer.java:994)
[info] csc365a01.RandomAccessFile.readInt(RandomAccessFile.scala:22)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply$mcZI$sp(RandomAccessFileSpec.scala:14)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply(RandomAccessFileSpec.scala:11)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply(RandomAccessFileSpec.scala:11)
A verbosity greater than one will give you the full stack trace.
[info] ! RandomAccessFile.readWriteInt: Exception raised on property evaluation.
[info] > ARG_0: 0
[info] > ARG_0_ORIGINAL: 1693735989
[info] > Exception: java.lang.UnsupportedOperationException: null
[info] java.nio.IntBuffer.array(IntBuffer.java:994)
[info] csc365a01.RandomAccessFile.readInt(RandomAccessFile.scala:22)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply$mcZI$sp(RandomAccessFileSpec.scala:14)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply(RandomAccessFileSpec.scala:11)
[info] RandomAccessFileProps$$anonfun$1$$anonfun$apply$1.apply(RandomAccessFileSpec.scala:11)
[info] scala.Function1$$anonfun$andThen$1.apply(Function1.scala:52)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:712)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$3.apply(Prop.scala:712)
[info] org.scalacheck.Prop$.secure(Prop.scala:456)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1.org$scalacheck$Prop$$anonfun$$result$1(Prop.scala:712)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:719)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1$$anonfun$4.apply(Prop.scala:719)
[info] scala.collection.immutable.Stream.map(Stream.scala:418)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1.getFirstFailure$1(Prop.scala:719)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1.shrinker$1(Prop.scala:729)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:751)
[info] org.scalacheck.Prop$$anonfun$forAllShrink$1.apply(Prop.scala:706)
[info] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:292)
[info] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:291)
[info] org.scalacheck.PropFromFun.apply(Prop.scala:22)
[info] org.scalacheck.Prop$$anonfun$delay$1.apply(Prop.scala:461)
[info] org.scalacheck.Prop$$anonfun$delay$1.apply(Prop.scala:461)
[info] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:292)
[info] org.scalacheck.Prop$$anonfun$apply$5.apply(Prop.scala:291)
[info] org.scalacheck.PropFromFun.apply(Prop.scala:22)
[info] org.scalacheck.Test$.org$scalacheck$Test$$workerFun$1(Test.scala:294)
[info] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[info] org.scalacheck.Test$$anonfun$3.apply(Test.scala:323)
[info] org.scalacheck.Platform$.runWorkers(Platform.scala:40)
[info] org.scalacheck.Test$.check(Test.scala:323)
[info] org.scalacheck.ScalaCheckRunner$$anon$2$$anonfun$execute$3$$anonfun$apply$2.apply(ScalaCheckFramework.scala:102)
[info] org.scalacheck.ScalaCheckRunner$$anon$2$$anonfun$execute$3$$anonfun$apply$2.apply(ScalaCheckFramework.scala:100)
[info] scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:733)
[info] scala.collection.immutable.List.foreach(List.scala:381)
[info] scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
[info] scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
[info] scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:732)
[info] org.scalacheck.ScalaCheckRunner$$anon$2$$anonfun$execute$3.apply(ScalaCheckFramework.scala:100)
[info] org.scalacheck.ScalaCheckRunner$$anon$2$$anonfun$execute$3.apply(ScalaCheckFramework.scala:97)
[info] scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
[info] scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:241)
[info] scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
[info] scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:186)
[info] scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:241)
[info] scala.collection.mutable.ArrayOps$ofRef.flatMap(ArrayOps.scala:186)
[info] org.scalacheck.ScalaCheckRunner$$anon$2.execute(ScalaCheckFramework.scala:97)
[info] sbt.TestRunner.runTest$1(TestFramework.scala:76)
[info] sbt.TestRunner.run(TestFramework.scala:85)
[info] sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202)
[info] sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:202)
[info] sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:185)
[info] sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202)
[info] sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:202)
[info] sbt.TestFunction.apply(TestFramework.scala:207)
[info] sbt.Tests$$anonfun$9.apply(Tests.scala:216)
[info] sbt.Tests$$anonfun$9.apply(Tests.scala:216)
[info] sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44)
[info] sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:44)
[info] sbt.std.Transform$$anon$4.work(System.scala:63)
[info] sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
[info] sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226)
[info] sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17)
[info] sbt.Execute.work(Execute.scala:235)
[info] sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
[info] sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226)
[info] sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159)
[info] sbt.CompletionService$$anon$2.call(CompletionService.scala:28)
[info] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[info] java.util.concurrent.FutureTask.run(FutureTask.java:266)
[info] java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[info] java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[info] java.lang.Thread.run(Thread.java:745)
[info] Elapsed time: 0.047 sec

Related

sbt testOnly exclusion list with tag does not work

I have a test class as
import org.scalatest.FlatSpec
import scala.collection.mutable
class Tags101Spec extends FlatSpec {
"A Stack" should "pop values in last-in-first-out order" in {
val stack = new mutable.Stack[Int]
stack.push(1)
stack.push(2)
assert(stack.pop() === 2)
assert(stack.pop() === 1)
}
it should "throw NoSuchElementException if an empty stack is popped" in {
val emptyStack = new mutable.Stack[String]
intercept[NoSuchElementException] {
emptyStack.pop()
}
}
"A String" should "return 0 size when empty" taggedAs (Fast) in {
assert("".size === 0)
}
"A Sorted List of 10 numbers" must "return 10 as the first element when reversed" taggedAs (Slow) in {
assert(10 === (1 to 10).toList.reverse.head)
}
}
In the same directory, I have a class called Tags which looks like
import org.scalatest.Tag
object Slow extends Tag("Slow Tests")
object Fast extends Tag("Fast Tests")
I run my tests using sbt by including a tag using -n flag and it works
sbt:Unit Testing in Scala> testOnly -- -n Fast
[info] Tags101Spec:
[info] A Stack
[info] A String
[info] A Sorted List of 10 numbers
[info] Run completed in 137 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
Since only 1 test was taggedAs(Fast), the test ran only one test.
Now, I want to do the opposite, exclude the Fast tag and run remaining tests. Here is what I tried
sbt:Unit Testing in Scala> testOnly -- -l Fast
[info] Tags101Spec:
[info] A Stack
[info] - should pop values in last-in-first-out order
[info] - should throw NoSuchElementException if an empty stack is popped
[info] A String
[info] - should return 0 size when empty
[info] A Sorted List of 10 numbers
[info] - must return 10 as the first element when reversed
[info] Run completed in 252 milliseconds.
[info] Total number of tests run: 4
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 4, failed 0, canceled 0, ignored 0, pending 0
And as you see, it ran 4 tests, which is all the tests, including 1 Fast tagged test.
What am I missing here? How can I make exclusion tag work with sbt?
Thanks
The argument to -l or -n should be the name string argument passed to Tags constructor, not the name of the object. For example, given
object Slow extends Tag("SlowTests")
object Fast extends Tag("FastTests")
then exclude with
testOnly -- -l FastTests
instead of
testOnly -- -l Fast
which outputs
[info] Tags101Spec:
[info] A Stack
[info] - should pop values in last-in-first-out order
[info] - should throw NoSuchElementException if an empty stack is popped
[info] A String
[info] A Sorted List of 10 numbers
[info] - must return 10 as the first element when reversed
[info] Run completed in 187 milliseconds.
[info] Total number of tests run: 3
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
where we see A string test did not execute.
Personally I would use a fully qualified name as the name argument when constructing Tags like so
package example
import org.scalatest.Tag
object Slow extends Tag("example.Slow")
object Fast extends Tag("example.Fast")
and execute with
testOnly -- -n example.Fast
which outputs
[info] Tags101Spec:
[info] A Stack
[info] A String
[info] - should return 0 size when empty
[info] A Sorted List of 10 numbers
[info] Run completed in 158 milliseconds.
[info] Total number of tests run: 1
[info] Suites: completed 1, aborted 0
[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.

How do I specify specific test from the build.sbt

How do I can specify the test from the build.sbt file , I wanted to run one test only and I used the filter as in the sbt docs, but it doesn't work with me, this is my code I have two test classes and in my sbt I specify test1 to be rub but it seems that the two test are running at the same time any one know what I should do ?
Test1Demo.scala
import org.scalatest.{FlatSpec, Matchers}
class Test1Demo extends FlatSpec with Matchers{
"value of x " should " be 9 " in { assert(my.App.x == 9) }
}
Test2Demo.scala
import org.scalatest.{FlatSpec, Matchers}
class Test2Demo extends FlatSpec with Matchers{
"value of y " should " be 8 " in { assert(my.App2.y == 8) }
}
build.sbt
version := "0.1"
scalaVersion := "2.12.8"
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % Test
testOptions in Test := Seq(Tests.Filter(s => s.startsWith("Test1")))
the output :
[info] Done updating.
[info] Compiling 2 Scala sources to /home/****/target/scala-2.12/classes ...
[info] Done compiling.
[info] Compiling 2 Scala sources to /home/****/target/scala-2.12/test-classes ...
[info] Done compiling.
[info] Test2Demo:
[info] value of y
[info] - should be 8
[info] Test1Demo:
[info] value of x
[info] - should be 9
[info] Run completed in 6 seconds, 365 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 2, aborted 0
[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 264 s, completed Apr 15, 2019 2:47:10 PM
If you want to run value of x test from Test1Demo:
testOnly *Test1Demo -- -z value
This sbt command will run only the tests whose name includes the substring "value".
For exact match rather than substring, use -t instead of -z.
Pay attention to -- (two -, not one)

How to resolve "Ambiguous reference to a JS library"?

I'm struggling resolving some Javascript library dependency clashes in the following build.sbt file:
lazy val root = project.in(file(".")).enablePlugins(ScalaJSPlugin)
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-java-time" % "0.1.0",
"org.querki" %%% "jquery-facade" % "0.10"
)
jsDependencies ++= Seq(
"org.webjars.bower" % "jquery" % "3.0.0-beta1" / "jquery.js"
)
When running the fastOptJS task I'm getting the following error message:
[trace] Stack trace suppressed: run last compile:resolvedJSDependencies for the full output.
[error] (compile:resolvedJSDependencies) org.scalajs.core.tools.jsdep.JSLibResolveException: Some references to JS libraries could not be resolved:
[error] - Ambiguous reference to a JS library: jquery.min.js
[error] Possible paths found on the classpath:
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/dist/jquery.min.js
[error] - META-INF/resources/webjars/jquery/2.1.4/jquery.min.js
[error] originating from: root:compile
[error] - Ambiguous reference to a JS library: jquery.js
[error] Possible paths found on the classpath:
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/src/jquery.js
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/dist/jquery.js
[error] - META-INF/resources/webjars/jquery/2.1.4/jquery.js
[error] originating from: root:compile, root:compile
[error] Total time: 1 s, completed Mar 2, 2016 12:36:43 PM */
How can I resolve the ambiguous references to Javascript libraries in this case?
Based on this Github issue, I learned that it is possible to specify a qualifying path to disambiguate references to Javascript libraries.
Let's try to disambiguate the jquery.js reference by adding the path dist.
jsDependencies ++= Seq(
"org.webjars.bower" % "jquery" % "3.0.0-beta1" / "dist/jquery.js"
)
But running fastOptJS again returns the same error
[error] - Ambiguous reference to a JS library: jquery.min.js
[error] Possible paths found on the classpath:
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/dist/jquery.min.js
[error] - META-INF/resources/webjars/jquery/2.1.4/jquery.min.js
[error] originating from: root:compile
[error] - Ambiguous reference to a JS library: jquery.js
[error] Possible paths found on the classpath:
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/src/jquery.js
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/dist/jquery.js
[error] - META-INF/resources/webjars/jquery/2.1.4/jquery.js
[error] originating from: root:compile
[error] Total time: 2 s, completed Mar 2, 2016 7:29:08 PM
This problem is actually created by the libraryDependencies entry "org.querki" %%% "jquery-facade" % "0.10". Using the dependency graph SBT plugin we see the full dependency graph:
[info] root:root_sjs0.6_2.11:0.1-SNAPSHOT [S]
[info] +-org.querki:jquery-facade_sjs0.6_2.11:0.10 [S]
[info] | +-org.querki:querki-jsext_sjs0.6_2.11:0.6 [S]
[info] | | +-org.scala-js:scalajs-library_2.11:0.6.5 (evicted by: 0.6.7)
[info] | | +-org.scala-js:scalajs-library_2.11:0.6.7 [S]
[info] | |
[info] | +-org.scala-js:scalajs-dom_sjs0.6_2.11:0.8.0 [S]
[info] | | +-org.scala-js:scalajs-library_2.11:0.6.0 (evicted by: 0.6.7)
[info] | | +-org.scala-js:scalajs-library_2.11:0.6.5 (evicted by: 0.6.7)
[info] | | +-org.scala-js:scalajs-library_2.11:0.6.7 [S]
[info] | |
[info] | +-org.scala-js:scalajs-library_2.11:0.6.5 (evicted by: 0.6.7)
[info] | +-org.scala-js:scalajs-library_2.11:0.6.7 [S]
[info] | +-org.webjars:jquery:2.1.4
[info] |
[info] +-org.scala-js:scalajs-java-time_sjs0.6_2.11:0.1.0 [S]
[info] | +-org.scala-js:scalajs-library_2.11:0.6.6 (evicted by: 0.6.7)
[info] | +-org.scala-js:scalajs-library_2.11:0.6.7 [S]
[info] |
[info] +-org.scala-js:scalajs-library_2.11:0.6.6 (evicted by: 0.6.7)
[info] +-org.scala-js:scalajs-library_2.11:0.6.7 [S]
[info] +-org.webjars.bower:jquery:3.0.0-beta1
The output shows org.querki:jquery-facade_sjs0.6_2.11:0.10 to depend on org.webjars:jquery:2.1.4. This explains the Ambiguous reference to a JS library error message above because we still have two jquery library versions available in the listed dependencies.
What we can try next is use exclude on the library dependency.
libraryDependencies ++= Seq(
"org.scala-js" %%% "scalajs-java-time" % "0.1.0",
"org.querki" %%% "jquery-facade" % "0.10" exclude("org.webjars","jquery")
)
Running the fastOptJS task now returns
[error] (compile:resolvedJSDependencies) org.scalajs.core.tools.jsdep.JSLibResolveException: Some references to JS libraries could not be resolved:
[error] - Ambiguous reference to a JS library: jquery.js
[error] Possible paths found on the classpath:
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/src/jquery.js
[error] - META-INF/resources/webjars/jquery/3.0.0-beta1/dist/jquery.js
[error] originating from: root:compile
[error] Total time: 2 s, completed Mar 2, 2016 7:47:14 PM
So although we got rid of some errors, we are not quite there yet. I'm not 100% sure here, but it seems this error is a result in how the build.sbt of the jQuery Facade includes jQuery using jsDependencies itself:
jsDependencies += "org.webjars" % "jquery" % "2.1.4" / "jquery.js" minified "jquery.min.js"
So it seems we ran into the same problem we had at the start. A unqualified jquery.js (i.e. without a preceding path) cannot not be resolved unambiguously.
To solve this problem we can use to the jsManifestFilter setting. I found this tip in the Scala.js Gitter room.
jsManifestFilter := {
import org.scalajs.core.tools.jsdep.{JSDependencyManifest, JSDependency}
(seq: Traversable[JSDependencyManifest]) => {
seq map { manifest =>
def isOkToInclude(jsDep: JSDependency): Boolean = {
println(s"jsDep=>$jsDep")
jsDep.resourceName != "jquery.js"
}
new JSDependencyManifest(
origin = manifest.origin,
libDeps = manifest.libDeps filter isOkToInclude,
requiresDOM = manifest.requiresDOM,
compliantSemantics = manifest.compliantSemantics
)
}
}
}
Here we overwrite the jsManitestFilter setting and explicitly filter out the naked jquery.js dependency. The fastOptJS task runs fine now:
[info] Resolving org.eclipse.jetty#jetty-continuation;8.1.16.v20140903 ...
[info] Done updating.
jsDep=>JSDependency(resourceName=dist/jquery.js)
jsDep=>JSDependency(resourceName=jquery.js, minifiedResourceName=Some(jquery.min.js))
[info] Fast optimizing jsdeps/target/scala-2.11/root-fastopt.js
[success] Total time: 3 s, completed Mar 2, 2016 8:27:40 PM
Note that the added println statement also outputs the resourceName for the included dependencies.

How to run task before all tests from all modules in sbt

I have a multi-module Play! application built with sbt and I have a problem on CI server with parallel tests and evolutions: when sbt starts tests and first starts evolution script, other fails because of "Database 'default' is in inconsistent state" for a while (until evolution script stops).
I know how to execute evolutions manually and how to run them from sbt, but I don't know how can I plug this configuration to sbt to ensure evolutions are applied only once and before all tests from all modules.
For reference I'm using following for running evolutions:
object ApplyEvolutions extends App {
OfflineEvolutions.applyScript(
new File("."),
this.getClass.getClassLoader,
args.headOption.getOrElse("default"))
}
And my sbt settings:
val runEvolution = taskKey[Unit]("Applies evolutions")
lazy val runEvolutionTask = runEvolution := {
val log = streams.value.log
val dbName = "default"
Run.executeTrapExit( {
log.info(s"Applying evolutions for database $dbName")
Run.run("controllers.ApplyEvolutions",
(fullClasspath in Compile).value.map { _.data },
Seq(dbName),
log
)(runner.value)
}, log )
}
lazy val runEvolutionsBeforeTests = Seq(
Tasks.runEvolutionTask,
(test in Test) <<= (test in Test) dependsOn Tasks.runEvolution
)
tl;dr Use alias
I use SBT 0.13.2-M3.
[task-dependson]> about
[info] This is sbt 0.13.2-M3
[info] The current project is {file:/Users/jacek/sandbox/so/task-dependsOn/}task-dependson 0.1-SNAPSHOT
[info] The current project is built against Scala 2.10.3
[info] Available Plugins: sbt.plugins.IvyModule, sbt.plugins.JvmModule, sbt.plugins.GlobalModule, com.typesafe.sbt.SbtGit, com.typesafe.sbt.SbtProguard, growl.GrowlingTests, org.sbtidea.SbtIdeaPlugin, sbtman.Plugin, np.Plugin, com.timushev.sbt.updates.UpdatesPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.3
Here's an example of a task - sayHelloT - that's executed once before test in all subprojects. I use Specs2 as the testing framework.
import java.util.concurrent._
lazy val a = project
lazy val b = project
lazy val sayHelloT = taskKey[Unit]("Say Hello")
sayHelloT := {
val log = streams.value.log
log.info("Sleeping for 5 secs...")
TimeUnit.SECONDS.sleep(5)
log.info("Hello, my friend")
}
libraryDependencies in ThisBuild += "org.specs2" %% "specs2" % "2.3.10" % "test"
scalacOptions in Test ++= Seq("-Yrangepos")
addCommandAlias("sht", ";sayHelloT; test")
As you can see there are two subprojects - a and b - and a single alias sht that will execute sayHelloT and only after it finishes successfully which takes 5 secs, test kicks in.
[task-dependson]> sht
[info] Sleeping for 5 secs...
[info] Hello, my friend
[success] Total time: 5 s, completed Mar 12, 2014 10:19:39 PM
[info] ASpec
[info]
[info] A project should
[info] + contain 11 characters
[info]
[info] Total for specification ASpec
[info] Finished in 205 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for task-dependson/test:test
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[info] BSpec
[info]
[info] B project should
[info] + contain 11 characters
[info]
[info] Total for specification BSpec
[info] Finished in 240 ms
[info] 1 example, 0 failure, 0 error
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 3 s, completed Mar 12, 2014 10:19:42 PM

Is there any way to make sbt stop printing so much info? [duplicate]

This question already has answers here:
How to change log level from command line?
(2 answers)
Closed 9 years ago.
When running tests with sbt, there is so much crap that's printed that I miss all of the useful information. Running the example specs, here is everything I get:
> test
[info]
[info] == compile ==
[info] Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[info] Nothing to compile.
[info] Post-analysis: 17 classes.
[info] == compile ==
[info]
[info] == copy-resources ==
[info] == copy-resources ==
[info]
[info] == copy-test-resources ==
[info] == copy-test-resources ==
[info]
[info] == test-compile ==
[info] Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling test sources...
[info] Nothing to compile.
[info] Post-analysis: 6 classes.
[info] == test-compile ==
[info]
[info] == test-start ==
[info] == test-start ==
[info]
[info] == spec.game.battle.gameobject.component.health.event.helloWorld ==
[info] + 'hello world' has 11 characters
[info] + 'hello world' matches 'h.* w.*'
[info] == spec.game.battle.gameobject.component.health.event.helloWorld ==
[info]
[info] == test-complete ==
[info] == test-complete ==
[info]
[info] == Test cleanup 1 ==
[info] Deleting directory C:\Users\..\AppData\Local\Temp\sbt_cc3b61d5
[info] == Test cleanup 1 ==
[info]
[info] == test-finish ==
[info] Passed: : Total 2, Failed 0, Errors 0, Passed 2, Skipped 0
[info]
[info] All tests PASSED.
[info] == test-finish ==
[info]
[info] == test-cleanup ==
[info] == test-cleanup ==
[info]
[info] == test ==
[info] == test ==
[success] Successful.
[info]
[info] Total time: 1 s, completed Apr 9, 2011 8:12:47 PM
>
Is there any way to make it so it only shows the spec lines?
Have you tried warn?
> warn
Set log level to warn