no tests were executed for sbt integration test in system folder - scala

I want to run sbt system:test to run the integration tests in system folder. Here's the build.sbt changes, but it the console log still says No tests were executed. any ideas why? thanks!!
lazy val `myproj` = (project in file(".")).enablePlugins(PlayScala).configs(SystemTest).settings(
inConfig(SystemTest)(Defaults.testSettings),
// other settings here
)
lazy val SystemTest = config("system") extend Test describedAs "System tests"

Try this
lazy val root = (project in file("."))
.enablePlugins(PlayScala)
.configs(SystemTest)
.settings( inConfig(SystemTest)(Defaults.testSettings) : _*)
lazy val SystemTest = config("system") extend(Test)
scalaSource in SystemTest := baseDirectory.value / "/system"
The last line is to give the path of the folder where yours test cases are.
You can see this blog as well.
Hope this helps!

Play/SBT offer You integration tests "out of the box" with command sbt it:test and below configuration:
lazy val root = (project in file("."))
.configs(IntegrationTest)
.settings(
Defaults.itSettings,
)

Related

How to set main class from submodule to root in sbt

I have multimodule setup, where root is just a project wrapper for submodules core and util.
Core is actually the application and contains main class(extending App) which I want to run.
Staying at project root(wrapper) I want to run sbt run and execute the main method from core submodule
lazy val root = project
.in(file("."))
.aggregate(util, core)
.settings(
mainClass in Compile := (mainClass in Compile in core).value
)
lazy val util = project
.in(file("util"))
lazy val core = project
.in(file("core"))
.settings(
mainClass in Compile := Some("com.iwaneez.scala.Hello"),
libraryDependencies ++= commonDependencies
)
.dependsOn(util)
I expect to run the application just by executing sbt run
addCommandAlias can be used to replace run in the root project.
lazy val root = project
.in(file("."))
.aggregate(util, core)
.settings(
addCommandAlias("run", "core/run")
)
sbt:root> run --test
[info] Running com.iwaneez.scala.Hello --test
Hello List(--test)
The following command will let you run the project
sbt "project core" run

Multiple main classes with SBT assembly

I'm looking to create jars for AWS Lambda to run job tasks. Currently my build.sbt file looks something like this:
lazy val commonSettings = Seq(...)
lazy val core = project
.settings(commonSettings: _*)
lazy val job = project
.settings(commonSettings: _*)
.dependsOn(core)
lazy val service = project
.settings(commonSettings: _*)
.settings(
mainClass in assembly := Some("io.example.service.Lambda"),
assemblyJarName in assembly := "lambda.jar"
)
.dependsOn(core)
Running sbt assembly assembles the service module into a jar for my API and that works fine. The module job however will have multiple Main classes (one pr. job) and when I run sbt assembly job the service module is also assembled (even through its not depended on).
How can I configure my setup to only assemble the job module when needed, and specify individual mainClasses as separately assembled jars?
Set mainClass in assembly in job to define which main class to use, and run job/assembly to just assemble the job assembly jar.
You will need to override the default main class at build time by setting the property explicitly.
sbt "; set mainClass in assembly := Some("another/class"); job/assembly"
Not sure it's good practice but alternatively you can define a sub-project for each job with the correct main class set.
lazy val job1 = project
.settings(commonSettings: _*)
.settings(
mainClass in assembly := Some("io.example.service.Lambda"),
assemblyJarName in assembly := "lambda.jar"
)
.dependsOn(core)
lazy val job2 = project
.settings(commonSettings: _*)
.settings(
mainClass in assembly := Some("io.example.service.Lambda2"),
assemblyJarName in assembly := "lambda2.jar"
)
.dependsOn(core)

sbt with sub-modules and multiple scala versions

I'm building a scala applications with these module and dependencies :
a shared lib "common"
module "A" depends on "common" and can be built in scala 2.10 only
module "B" depends on "common" and can be built in scala 2.11+ only
I'm trying to have all the 3 modules in a single sbt build :
import sbt._
import Keys._
lazy val root = (project in file("."))
.aggregate(common, A, B)
lazy val common = (project in file("common"))
lazy val A = (project in file("A"))
.dependsOn(common)
lazy val B = (project in file("B"))
.dependsOn(common)
I've read things about crossScalaVersions, but whatever combination I try in root build, or in common, etc, I can't manage to make this work properly.
Any clue ?
I'm using sbt 0.13.8 by the way.
Using bare sbt this might not be possible.
An example build.sbt file representing such situation:
lazy val common = (project in file("common"))
.settings(crossScalaVersions := Seq("2.10.6", "2.11.8"))
lazy val A = (project in file("A"))
.settings(scalaVersion := "2.10.6")
.dependsOn(common)
lazy val B = (project in file("B"))
.settings(scalaVersion := "2.11.8")
.dependsOn(common)
This will work just fine.
Now. A compilation of any project leads to a creation of a package. Even for the root. If you follow the console, at some point it says:
Packaging /project/com.github.atais/target/scala-2.10/root_2.10-0.1.jar
So as you see sbt needs to decide on some Scala version, just to build this jar! That being said your projects A and B must have a common Scala version so they can be aggregated in a common project root.
Therefore, you can't have:
lazy val root = (project in file("."))
.aggregate(common, A, B)
if they do not share any Scala version they could be built with.
But... sbt-cross to the rescue
You can use sbt-cross plugin to help you out.
In project/plugins.sbt, add
addSbtPlugin("com.lucidchart" % "sbt-cross" % "3.2")
And define your build.sbt in a following way:
lazy val common = (project in file("common")).cross
lazy val common_2_11 = common("2.11.8")
lazy val common_2_10 = common("2.10.6")
lazy val A = (project in file("A"))
.settings(scalaVersion := "2.10.6")
.dependsOn(common_2_10)
lazy val B = (project in file("B"))
.settings(scalaVersion := "2.11.8")
.dependsOn(common_2_11)
lazy val root = (project in file("."))
.aggregate(common, A, B)
And then it works :-)!
In my experience sbt multi-module builds are quite finicky to get to work reliably if you require any extra hoops to jump through such as this requirement.
Have you considered the simpler way to achieve this:
publish your common dependency (sbt publish-local if you only need to access it yourself)
make two projects A and B
make both A and B import common as a dependency

Why does sbt create layers of projects and src in IDEA?

I am new to SBT and trying to build a project. My Build.scala looks like
lazy val ec = project.in(file("."))
.settings(commonSettings: _*)
.settings(name := "ec")
.aggregate(ahka, currentLogProcessor, main)
lazy val currentLogProcessor = project.in(file("currentLogProcessor"))
.settings(commonSettings: _*)
.settings(name := "currentlogprocessor")
.settings(
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
)
lazy val main = project
.settings(commonSettings: _*)
.settings(name := "main")
When SBT refreshes in IntelliJ, I see following
As you could see, even if the settings looks same for currentLogProcessor and main, the project structure is very very different.
project inside currentLogProcessor looks good but project under main is layer with project and src
What is the issue here? How can I remove the layers of project inside project?
Thanks
Your projects ec and main share the same folder. Remove main or ec, or change "in file" for one of them.
lazy val main = project in file("another_path") ...
The answer by #ka4eli is correct, but I'd like to point out few issues with the build definition that can make understanding it so much painful.
Defining top-level aggregate project
lazy val ec = project.in(file("."))
.settings(commonSettings: _*)
.settings(name := "ec")
.aggregate(ahka, currentLogProcessor, main)
You don't need it whatsoever as it's defined automatically anyway - you're just repeating what sbt does implicitly. Just remove it from the build and add build.sbt with the following:
commonSettings
Use build.sbt for a project's build definition
lazy val currentLogProcessor = project.in(file("currentLogProcessor"))
.settings(commonSettings: _*)
.settings(name := "currentlogprocessor")
.settings(
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
)
By default, lazy val's name is used to call a project project macro should point to, i.e. no need for in(file("currentLogProcessor")). The same applies to the name setting - you're using all-lowercase name that may or may not be needed.
Use build.sbt under currentLogProcessor directory to have the same effect:
name := "currentlogprocessor"
commonSettings
libraryDependencies += "com.myorg.util" % "LP" % "0.18.0-SNAPSHOT" % "provided"
It's that simple.
Apply the rules to the main project.
Have fun with sbt = it's so simple that people hardly accept it and mess up build definitions on purpose to claim otherwise :)

Run sbt project in debug mode with a custom configuration

I want to introduce a debug mode in my sbt 0.11 project using a special configuration.
I've tried to implement this using the following code but unfortunately, it doesn't seems to work as expected. I'm launching debug:run but the run doesn't suspends as expected.
object Test extends Build {
lazy val root = Project("test", file("."))
.configs( RunDebug )
.settings( inConfig(RunDebug)(Defaults.configTasks):_*)
.settings(
name := "test debug",
scalaVersion := "2.9.1",
javaOptions in RunDebug += "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005",
fork in RunDebug := true
)
lazy val RunDebug = config("debug").extend( Runtime )
}
Ok that works with the following :
object Test extends Build {
lazy val root = Project("test", file("."))
.configs( RunDebug )
.settings( inConfig(RunDebug)(Defaults.configTasks):_*)
.settings(
name := "test debug",
scalaVersion := "2.9.1",
javaOptions in RunDebug ++= Seq("-Xdebug", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"),
fork in RunDebug := true
)
lazy val RunDebug = config("debug").extend( Runtime )
}
now I can run my code in debug mode using debug:mode.
for simply running sbt project in debug mode , just do
JAVA_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
and then
sbt run would run SBT in debug mode, you can create a remote debug configuration in eclipse and connect to it.
this is a rather lame, but useful when you have a multi module play project and want to run one of the modules in the debug mode
In Intellij IDEA, I just boot the program in Dedug mode and it seems to work properly without further configuration.