Running tests from jar with "sbt testOnly" in SBT?

As part of the CI installation, the very first step is to create a package / jar using SBT dist . The following steps are designed to run unit, integration, and functional tests using the dist -created jar.

Is it possible to do this with SBT?

I usually use sbt testOnly "Unit.*" , But this works in the context of the project. I canโ€™t find the documentation showing how to do this when there is already a bank.

I use ScalaTest and I know there is a runner for him, I could use http://www.scalatest.org/user_guide/using_the_runner . But using SBT would be easier if possible.

As an example, something like this is what I'm looking for:

 sbt testOnly "Unit.* -jar myjar.jar" 

My tests will even be included in the jar when I use the following:

 sbt dist 

?

EDIT

  • I created a new folder
  • I added build.sbt with the following content:

     name := "abc" version := "1.0-SNAPSHOT" scalaVersion := "2.10.0" 
  • I added the lib folder and copied my javascript into it

  • I ran sbt testOnly Unit.*

  • Could not find tests

EDIT 2

I tried with the following โ€œcorrectโ€ SBT file:

 name := "ihs2tests" version := "1.0-SNAPSHOT" scalaVersion := "2.10.0" unmanagedBase in Test := new java.io.File(".") 

and moved test.jar to the root of the project. Again, no tests were found.

+5
scala sbt scalatest
source share
2 answers

I usually use sbt testOnly "Unit. *", But this works in the context of the project. I canโ€™t find the documentation showing how to do this when there is already a bank.

The test -family tasks in SBT (with testOnly as an example) work with the compile task, which returns a list of compiled files through an sbt.inc.Analysis instance. I could not figure out how to change it and insert the modified Analysis instance into testOnly so that it knew that the test that I would run was there.

I propose another solution - a trick .

Put the test classes in the jar with the test:package task as follows:

 [test-lib]> test:package [info] Updating {file:/Users/jacek/sandbox/so/test-lib/}test-lib... [info] Resolving org.fusesource.jansi#jansi;1.4 ... [info] Done updating. [info] Compiling 1 Scala source to /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-classes... [info] Packaging /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-lib_2.10-0.1-SNAPSHOT-tests.jar ... [info] Done packaging. [success] Total time: 9 s, completed Mar 4, 2014 11:34:13 PM 

When you have a test jar, you can run the test environment on the command line without SBT (suppose you use ScalaTest considering scalatest , but I will use Specs2). Read the test environment documentation on how to do this, and for Specs2 it specs2.run , as described in Console exit .

Performing tests from a test jar requires determining the correct CLASSPATH, which may or may not be easy to correct. That SBT can be of great help is to manage dependencies and therefore CLASSPATH.

Create another SBT project and save the test jar in the lib subdirectory so that it is on CLASSPATH (as described in Unmanaged dependencies ).

Dependencies in lib extend to all class paths (for compilation, testing, launching, and console).

Add a sample build.sbt where you define your test structure as a project dependency. For Specs2, this is as follows (I used the default configuration described in the Specs2 homepage ):

 libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test" scalacOptions in Test ++= Seq("-Yrangepos") 

The trick is to execute the main class of the test environment, for example. specs2.run for Specs2, as if the class was running on the command line. SBT helps with test:runMain .

 [my-another-project]> test:runMain specs2.run HelloWorldSpec [info] Running specs2.run HelloWorldSpec HelloWorldSpec The 'Hello world' string should + contain 11 characters + start with 'Hello' + end with 'world' Total for specification HelloWorldSpec Finished in 62 ms 3 examples, 0 failure, 0 error Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0" [success] Total time: 5 s, completed Mar 4, 2014 11:15:14 PM 

Donโ€™t worry about this Exception , as it comes from SBT, which catches exit from Specs2 (after running the test), therefore SBT does not work.

+1
source share

It seems that SBT cannot read the jar file without any additional / manual configuration - maybe I'm wrong, but I did not find anything in the docs. So I tried to do something similar to simplify the task:

 unzip some-test.jar java -jar sbt-launch.jar \ 'set scalaSource in Test := new java.io.File(".")' \ 'set fullClasspath in Test += Attributed.blank(file("."))' \ 'test' 

This runs without errors, but finds no tests.

If I add 'set includeFilter in (Test, unmanagedSources) := "*Suite*.class"' to make it find tests, it clearly fails because it expects *.scala files, not compiled *.class files .

I am not an SBT expert, but I think this should be close to a solution. There should be a way to programmatically view all the files from the jar path, and then tell the test structure to use *.class files.

At the moment, it is more reasonable to run tests using the Scalatest test runner or from sbt using the project.

If you want to dig deeper, check out the SBT source code and the standard sbt script shell, which does a lot of tweaking before running the sbt jbb start.

0
source share

All Articles