how to let SBT generate more detailed outputs of tests? Now only thing I get is the name of method and stack trace - I would like to have some more control over it, to get rid of stack trace, and possibly have formatted info e.g. expected, actual...
Thank you for help
Normally you should get some output. As an example:
class ATest extends FlatSpec with ShouldMatchers {
"Some Object" should "do something and will fail" in {
1 should be(2)
}
}
will return:
[info] Some Object
[info] - should do something and will fail *** FAILED *** (QuaternionSpec.scala:17)
[info] org.scalatest.TestFailedException: 1 was not equal to 2
Can you show your test code?
To turn off the stacktrace you can use:
trace off
Related
I have a subproject in my build.sbt with a rather long setting for initialCommands, comprising a list of imports and some definitions. I'd like to test this as part of regular CI, because otherwise I won't notice breaking changes after refactoring code. It is not clear to me how to do so.
Just running sbt console doesn't seem to cut it, because there is always a "successful" exit code even when code doesn't compile.
Moving the code out into an object defined in a special source file won't help because I need the list of imports to be present (and I don't want to cakeify my whole code base).
Moving the code out into a source file and then loading that with :load also always gives a successful exit code.
I found out about scala -e but that does strange things on my machine (see the error log below).
This is Scala 2.12.
$ scala -e '1'
cat: /release: No such file or directory
Exception in thread "main" java.net.UnknownHostException: <my-host-name-here>: <my-host-name-here>: Name or service not known
You could generate a file and run it like any other test file:
(sourceGenerators in Test) += Def.task {
val contents = """object TestRepl {
{{}}
}""".replace("{{}}", (initialCommands in console).value)
val file = (sourceManaged in Test).value / "repltest.scala"
IO.write(file, contents)
Seq(file)
}.taskValue
When I execute sbt testOnly *JoinTest* no tests are found and the following output is shown, but com.typesafe.slick.testkit.tests.JoinTest should have been executed:
testOnly *JoinTest*
[info] Compiling 1 Scala source to /ext/git/slick/slick-testkit/target/scala-2.10/test-classes...
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for testkit/test:testOnly
You're so close. Try this instead:
testOnly -- *JoinTest*
The -- allows you test send arguments to the test kit. Without that it's expecting a list of JUnit tests. More info here.
every time when I had a class called as yours .JoinTest to lunch / run all the tests from it I just wrote:
testOnly *.JoinTest
link from sbt 0.13 with details about this
additional if you want to run a specific test case from that class you can use the following command
testOnly *.JoinTest -- -z "test name you want to run"
to discover other commands that you can use with -- you can take a look at this link
I am trying to write a simple console client application where i can present some options to the user, get their input and act accordingly. If i run the code through intellij or paste it into the scala console, it works. If i run it through sbt (which is how i really need it to run), i run into all sorts of problems.
I have sbt version 0.13.8, OS is Mac, my build.sbt contains:
scalaVersion := "2.11.6"
fork in run := true
EDIT I started with the minimum scala activator template in case that is useful info in this context
I have simplified the code to barebones,
import scala.io.StdIn._
object TestClient {
def main(args: Array[String]): Unit = {
join()
}
def join(): Unit = {
val name = readLine(s"Enter your name.${System.getProperty("line.separator")}")
name match {
case n: String => println(n)
case o => {
println(s"invalid name ${o}")
join()
};
}
}
}
When go into sbt and from the prompt enter run. one of the following seems to happen
1) I get this exception as soon as i run
Exception in thread "Thread-2" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:3332)
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:137)
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:121)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:569)
at java.lang.StringBuffer.append(StringBuffer.java:369)
at java.io.BufferedReader.readLine(BufferedReader.java:370)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at sbt.BasicIO$$anonfun$processFully$1$$anonfun$apply$8.apply(ProcessImpl.scala:58)
at sbt.BasicIO$$anonfun$processFully$1$$anonfun$apply$8.apply(ProcessImpl.scala:58)
at sbt.BasicIO$.readFully$1(ProcessImpl.scala:63)
at sbt.BasicIO$.processLinesFully(ProcessImpl.scala:69)
at sbt.BasicIO$$anonfun$processFully$1.apply(ProcessImpl.scala:58)
at sbt.BasicIO$$anonfun$processFully$1.apply(ProcessImpl.scala:55)
at sbt.SimpleProcessBuilder$$anonfun$3.apply$mcV$sp(ProcessImpl.scala:354)
at sbt.Spawn$$anon$3.run(ProcessImpl.scala:17)
2)
No memory issues, but getting these messages in an infinite loop, so the readline does not seem to be waiting for any input
background log: info: Enter your name.
background log: info: invalid name null
background log: info: Enter your name.
background log: info: invalid name null
...
Either way I am unable to actually enter any input in the console. Not sure what I'm missing or doing wrong
Put
connectInput in run := true
in your build.sbt. See the official docs for more info on how to correctly handle forks in sbt.
I'm getting stack traces when a ScalaTest test fails in SBT. I've tried set traceLevel in Test := -1 at the SBT prompt, tried changing things in the build.sbt file, etc., but nothing seems to help.
What I'd like to get rid of is this:
> test
[info] TestWritingFunctions:
[info] - threeSquares examples *** FAILED ***
[info] scala.NotImplementedError: an implementation is missing
[info] at scala.Predef$.$qmark$qmark$qmark(Predef.scala:252)
[info] at TestWritingFunctions$$anonfun$1.apply$mcV$sp(WritingFunctions.scala:17)
[info] at TestWritingFunctions$$anonfun$1.apply(WritingFunctions.scala:16)
[info] at TestWritingFunctions$$anonfun$1.apply(WritingFunctions.scala:16)
[info] at org.scalatest.Transformer$$anonfun$apply$1.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer$$anonfun$apply$1.apply(Transformer.scala:22)
[info] at org.scalatest.OutcomeOf$class.outcomeOf(OutcomeOf.scala:85)
[info] at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
[info] at org.scalatest.Transformer.apply(Transformer.scala:22)
[info] at org.scalatest.Transformer.apply(Transformer.scala:20)
[info] ...
As you can see, the test is failing because I used the new ??? construct as a placeholder, but since I know there's a placeholder there, I'd just like a *** FAILED *** message without all the rigamarole. Is that possible?
You can use "-o..." without F or S (i.e, "-o" or "-oD" would give you no stack traces, but not "-oF", "-oS", or "-oDS" would give you a stack trace). That means you'd be suppressing all stack traces. If you specify no reporters at all, you'll get a "-o", which means no stack traces.
If you like the short stack traces in general, but don't want to see them when a NotImplementedError is thrown by ???, you can override withFixture and change NotImplementedError into pending tests:
import org.scalatest._
trait PendingIfUnimplemented extends SuiteMixin { this: Suite =>
abstract override def withFixture(test: NoArgTest): Outcome = {
super.withFixture(test) match {
case Failed(ex: NotImplementedError) => Pending
case other => other
}
}
}
This way you'll still get short, long, or no stack traces for regular failures, whatever you chose, but see (pending) for tests that fail because of ???.
(not authoritative, but since no one else has answered:)
I suspect that traceLevel isn't doing anything because the stack traces are coming from ScalaTest, not from sbt.
sbt does have a logLevel setting which is relevant. Try this:
set logLevel in Test := Level.Warn
But note that this suppresses not only the stack traces, but all of the lines in your example that begin with [info]. Instead, you'll just get the [error] stuff at the end, which does at least have the names of the suites with failing tests.
If you really want to only suppress the stack traces without changing anything else, I think that might not be possible. Looking at http://www.scalatest.org/user_guide/using_the_runner , I see options for making stack traces shorter (-oS) or longer (-oF), but no option for omitting the stack trace altogether.
The stacktraces are truncated - e.g. they end with [info] ...
Using last or changing traceLevel doesn't help - it simply prints the complete stacktrace of the sbt wrapper.
This is testing with testng (also I believe using scalatest and sl4j)
Using hints found in the documentation here:
(quoted)
You can configure the output shown when running with sbt in four ways: 1) turn off color, 2) show short stack traces, 3) full stack traces, and 4) show durations for everything. To do so you must pass a -o argument to ScalaTest, and after the -o, place any combination of:
D - show durations
S - show short stack traces
F - show full stack traces
W - without color
For example, "-oDF" would show full stack traces and durations (the amount of time spent in each test).
To pass arguments from sbt to ScalaTest you can either add test options globally, like this:
testOptions in Test += Tests.Argument("-oD")
(See the website for the rest of the quote)
You can use the following sbt command to enable full stack traces in tests:
> set testOptions in YourProjectName += Tests.Argument("-oF")
Per Sasha's comment, this can also be done from the command line per test run as shown below.
$ sbt test -- -oF
As an alternative to getting SBT to print the full stack trace, could you put a try-catch block around your test runner? For example, from the REPL:
scala> try { throw new Exception } catch { case e => e }
res1: java.lang.Throwable = java.lang.Exception
scala> res1.printStackTrace
java.lang.Exception
at $line2.$read$$iw$$iw$.liftedTree1$1(<console>:8)
at $line2.$read$$iw$$iw$.<init>(<console>:8)
at $line2.$read$$iw$$iw$.<clinit>(<console>)
...