Override test options in sbt task - sbt

I'm trying to define two sbt test tasks, but I want them to use different testOptions.
My first task looks like this:
TaskKey[Unit]("testServices") := {
(testOnly in Test).toTask({
... //some logic here
}).value
}
and testOptions in Test are set as:
testOptions in Test += Tests.Argument(
TestFrameworks.ScalaTest,
"-u", "target/results/junit",
"-h", "target/results/html",
"-M", "target/results/failures.log",
"-C", "com.lorem.ipsum.reporter.MyReporter"
)
Now I want to define new task (lets call it testServicesSimplified) which should be exact copy of previous one but should use following testOptions:
testOptions in Test += Tests.Argument(
TestFrameworks.ScalaTest,
"-C", "com.lorem.ipsum.reporter.SimplifiedReporter",
)
Is there any way to override testOptions just for that one new task? Or maybe there is other way to be able to run same tests with two different reporters?

Related

Airflow how to connect the previous task to the right next dynamic branch with multiple tasks?

I am facing this situation:
I have generated two dynamic branches. Each branch has multiple chained tasks.
This is what I need Airflow create for me:
taskA1->taskB1 taskC1->taskD1
taskA2->taskB2... taskZ.. taskC2->taskD2
taskA3->taskB3 taskC3->taskD3
and here is my sudocode:
def create_branch1(task_ids):
source = []
for task_id in task_ids:
source += [
Operator1(task_id=’task_A{0}'.format(task_id))) >>
Operator2(task_id=’task_B{0}’.format(task_id)) ]
return source
def create_branch2(task_ids):
source = []
for task_id in task_ids:
source += [
Operator1(task_id=’task_C{0}'.format(task_id))) >>
Operator2(task_id=’task_D{0}’.format(task_id)) ]
return source
create_branch1 >> dummyOperator(Z) >> create_branch2 >> end
However, what the Airflow generates, looks like this:
taskA1->taskB1 taskD1<-taskC1
taskA2->taskB2...taskZ...taskD2<-taskC2
taskA3->taskB3 taskD3<-taskC3
I mean in the second branch, dummyOperator(Z) will be connected to the last task of the chain (D), instead of connecting to the first task of the chain in the second branch (C).
It seems, no matters what, DummpyOperator(task-Z) will connect to the last task of the chained branches.
Do you have any idea, how to tackle this issue?

Conditional scalacSettings / settingKey

I want my scalacSettings to be more strict (more linting) when I issue my own command validate.
What is the best way to achieve that?
A new scope (strict) did work, but it requires to compile the project two times when you issue test. So that's not a option.
SBT custom command allows for temporary modification of build state which can be discarded after command finishes:
def validate: Command = Command.command("validate") { state =>
import Project._
val stateWithStrictScalacSettings =
extract(state).appendWithSession(
Seq(Compile / scalacOptions ++= Seq(
"-Ywarn-unused:imports",
"-Xfatal-warnings",
"...",
))
,state
)
val (s, _) = extract(stateWithStrictScalacSettings).runTask(Test / test, stateWithStrictScalacSettings)
s
}
commands ++= Seq(validate)
or more succinctly using :: convenience method for State transformations:
commands += Command.command("validate") { state =>
"""set scalacOptions in Compile := Seq("-Ywarn-unused:imports", "-Xfatal-warnings", "...")""" ::
"test" :: state
}
This way we can use sbt test during development, while our CI hooks into sbt validate which uses stateWithStrictScalacSettings.

specs2: Tag specification/individual test and exclude it from running using sbt

I need to skip specifications and individual tests while running my test suite.
Here's an example such test:
package models
import org.specs2.mutable._
import org.specs2.runner._
class SlowTaggedSpecification extends Specification{
"SLOW_SPEC" should {
"BAD!! Not Skipped" in {
"axbcd" must find( "bc".r )
}
} section( "SLOW_SPEC" )
}
class SlowFastTaggedSpecification extends Specification{
"SLOW_FAST_SPEC" should {
"run fast test" in {
"axbcd" must find( "bc".r )
} section( "FAST_TEST" )
"SLOW_TEST should be skipped (BAD!! NOT Skipped)" in {
"axbcd" must find( "bc".r )
} section( "SLOW_TEST" )
} section( "SLOW_FAST_SPEC" )
}
I need to skip SLOW_SPEC (entire spec) and SLOW_TEST (indvidual test only).
My build.sbt is:
scalaVersion := "2.11.1"
libraryDependencies += "org.specs2" %% "specs2" % "2.3.12" % "test"
When I run the following command line:
sbt '~testOnly models.* -- -l SLOW_SPEC'
sbt '~testOnly models.* -- -l SLOW_TEST'
none of the tests gets skipped. May I know how do I exclude a specification and an individual test using tags? Also, what would be the sbt syntax if I weren't using testOnly , but test?
sbt '~test -- -l SLOW_SPEC'
causes sbt to complain. My sbt version is 0.13.5
Any pointers would be appreciated.
The command line argument to exclude tags is
sbt> ~testOnly models.* -- exclude SLOW_SPEC
If you want to exclude tags when using the test command you need to use Test.Arguments in your build.sbt file:
testOptions in Test += Tests.Argument(TestFrameworks.Specs2, "exclude", "SLOW_SPEC")
If you want to specifically run a SLOW_SPEC test, then use the following:
sbt 'set testOptions in Test := Seq()' '~testOnly models.SlowTaggedSpecification'

Variable dependent tasks in SBT

I can make a Makefile that has a target that processes all sources in the directory.
SOURCE_DIR := src
TARGET_DIR := target
SOURCES := $(wildcard $(SOURCE_DIR)/*)
$(TARGET_DIR)/%: $(SOURCE_DIR)/%
md5sum $^ > $#
all: $(SOURCES:$(SOURCE_DIR)/%=$(TARGET_DIR)/%)
A nice advantage here is that each file is a separate target, so they can be processed incrementally, and concurrently. The concurrent part is important in this situation.
I am trying to something similar with SBT, but am finding it surprisingly difficult. The SBT analog of a Make target sees to be a task, so I try creating one task that aggregate a variable number of smaller tasks.
import org.apache.commons.codec.digest.DigestUtils
all <<= Def.task().dependsOn({
file(sourceDir.value).listFiles.map { source =>
val target = rebase(sourceDir.value, targetDir.value)(f)
Def.task {
IO.write(target, DigestUtils.md5Hex(IO.readBytes(source)))
}
}
}: _*)
I get the error
`value` can only be used within a task or setting macro, such as :=, +=, ++=,
Def.task, or Def.setting
How can I make a proper SBT build file that resembles my Makefile, with a dynamic number of concurrent targets/tasks?
I needed flatMap.
all <<= (sourceDir, targetDir).flatMap { (sourceDir, targetDir) =>
task{}.dependsOn({
file(sourceDir).listFiles.map { source =>
task {
val target = rebase(sourceDir, targetDir)(f)
IO.write(target, DigestUtils.md5Hex(IO.readBytes(source)))
}
}
}: _*)
}
There might be a slicker way to do task{}.dependsOn(...: _*), but I don't know what it is.

sbt-assembly: skip specific test

I would like to configure sbt-assembly to skip a specific test class.
Is there any way to do this? If it helps, I tagged the test using ScalaTest #Network tag.
See Additional test configurations with shared sources. This allows you to come up with alternative "test" task in FunTest configuration while reusing your test source.
After you have fun:test working with whatever filter you define using testOptions in FunTest := Seq(Tests.Filter(itFilter)), you can then rewire
test in assembly := test in FunTest
Eugene is right (obviously) but that wasn't quite enough information for me to get it to work - I have a build.scala file. I am defining baseSettings like this:
val baseSettings = Defaults.defaultSettings ++
buildSettings ++
Seq(sbt.Keys.test in assembly := {})
You can tag your tests with ignore, then sbt/ScalaTest won't run them. See ScalaTest docs on Tagging tests.
Just for completeness, if you want to skip all tests in assembly task or run only particular ones you can customize it with test in assembly := { ... }
Based on #eugene-yokata reply, I found how to use the flag from ScalaTest:
lazy val UnitTest = config("unit") extend (Test)
lazy val companyApp = (project in file("applications/"))
.assembly("com.company.app", "app.jar")
.configs(UnitTest)
.settings(
inConfig(UnitTest)(Defaults.testTasks),
UnitTest / testOptions ++= Seq(
Tests.Argument(
TestFrameworks.ScalaTest,
"-l",
"com.company.tag.HttpIntegrationTest"
),
Tests.Argument(
TestFrameworks.ScalaTest,
"-l",
"com.company.tag.EsIntegrationTest"
)
),
test in assembly := (UnitTest / test).value
)

Resources