2014-06-24 6 views
5

Ich bin ScalaCheck Tests in ausgeführt, und wenn mein Test fehlschlägt, weil der getestete Code eine Ausnahme auslöst, zeigt der Testbericht den fehlgeschlagenen Test, die ausgelöste Ausnahme und die Nachricht, aber nicht die gesamte Stack-Ablaufverfolgung (beachten Sie die einfache Exception: java.lang.NullPointerException: exception Ausnahmebedingung unten).Wie wird der gesamte Stack-Trace für geworfene Ausnahmen von ScalaCheck-Tests angezeigt?

[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 

Ich fand https://groups.google.com/forum/#!msg/scalacheck/AGBgE_JlqpI/B2eSG84_QzYJ aus dem Jahr 2008, die das gleiche Problem zu melden scheint und gibt es in der nächsten Version behoben werden soll. Ich verwende derzeit die neueste Version 1.11.4.

Ich fand auch http://www.scala-sbt.org/release/docs/Testing.html die sbt hat einen testOptions Schlüssel gibt, die ich vernünftig annehmen, scheint zu verwenden, und ich weiß ScalaTest eine Einstellung für volle Stack-Traces hat, "-F", aber das ist für Scalacheck funktioniert nicht. Auch das Beispiel aus der oben genannten Seite, testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-d", "-g") mir einen Fehler gibt:

[error] Could not run test org.example.myproject.MyTestClass: java.lang.Exception: [1.1] failure: option name expected 
[error] 
[error] -d -g 
[error]^

Wie ich diese Test Argumente nicht verwenden, gibt es eine Liste dieser Argumente überall, und schließlich ist es möglich, einen Stacktrace raus aus Alles, oder jage ich einen Ablenkungsmanöver?

Antwort

5

tl; dr Es gibt keine Unterstützung für verbosity unter sbt mit der freigegebenen Version von ScalaCheck. Sie müssen eine Version aus den Quellen selbst erstellen, um die Funktion zu haben.

Die verfügbaren Optionen für Scalacheck in Test Execution beschrieben:

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") 
} 
, nichts

So 0 gibt 1:

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 

Der Quellcode von org.scalacheck.util.Pretty uns mehr über die verschiedenen Ebenen der vebosity erzählt nimmt 5 Zeilen aus einer Stack-Trace, während eine Zahl größer als 1 gibt Ihnen die gesamte Stack-Trace wie folgt:

➜ 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 

Sie haben Recht, dass die Dokumentation für sbt incorect ist. Es gibt keine "-d", "-g" Optionen und ich glaube, dass sie einfach ein Kopieren-und-Einfügen-Fehler in der Dokumentation sind. It was already fixed in a pull request that's soon to be accepted.

Die Option verbosity wird in der aktuellen Version von ScalaCheck 1.11.4 nicht unter sbt unterstützt. Das Folgende ist die gesamte Build-Definition eines Beispielprojekts.

build.sbt

scalaVersion := "2.11.1" 

libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.11.4" % "test" 

testOptions in Test += Tests.Argument(TestFrameworks.ScalaCheck, "-verbosity", "3") 

Selbst wenn die verbosity Parameter richtig in build.sbt angegeben ist, wird die Testausführung druckt nicht mehr als eine einzige Zeile.

➜ 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 

Der Grund dafür ist, dass org.scalacheck.ScalaCheckFramework die folgende Implementierung hat und nimmt verbosity immer 0 sein:

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))) 
} 

Eine Pull-Anforderung, es zu beheben bereits an den Repo unter Support verbosity under sbt for TestFrameworks.ScalaCheck angenommen. Sie müssten ScalaCheck selbst mit sbt publishLocal in dem Verzeichnis erstellen, in dem Sie das Repo geklont haben. Vergessen Sie nicht, die Version 1.12.0-SNAPSHOT in build.sbt zu verwenden, um die Änderungen zu übernehmen.

1

Da das Problem, das Jacek Laskowski festgestellt hat, behoben wurde, können Sie nun Stack-Scaals von ScalaCheck in sbt abrufen, indem Sie eine Zeile zu Ihrer build.sbt Datei hinzufügen, um ScalaChecks Ausführlichkeitslevel einzustellen.

Wie Jacek Laskowski bemerkte, wird eine Ausführlichkeit von 0 Ihnen nur die Ausnahme geben.

[info] ! RandomAccessFile.readWriteInt: Exception raised on property evaluation. 
[info] > ARG_0: 0 
[info] > ARG_0_ORIGINAL: -2073744736 
[info] > Exception: java.lang.UnsupportedOperationException: null 

A Ausführlichkeit von 1 finden Sie die ersten fünf Zeilen des Stack-Trace geben.

[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) 

Eine Ausführlichkeit größer als eins gibt Ihnen die volle 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