Reputation: 4672
I'm working on a project where the standard method to run some test, foo
, is to do run foo --bar --baz --qux --quux someDirectory
. Worse still, documentation is pretty thin, and it took some digging around to figure out that was how tests are run.
The reason this is the case is that the project does some code generation (it generates c++, which then gets compiled and run), and the test is to run the generated code vs. a model that's also a blob of generated code that's produced by the same project. Looking at it from that perspective, you can see how things came to be this way, but it makes running tests unintuitive.
I'd like to be able to run tests with test foo
. Is it possible to make test foo
simply execute the above run command, and, if so, how do I do it?
If it's not possible, I'll add some documentation so newcomers to project can figure things out more easily. But, I'd prefer to make things consistent with other projects that use sbt.
Upvotes: 4
Views: 254
Reputation: 7019
The best way to do this currently is to directly implement a custom task. See Input Tasks for details.
// A custom task is required because `test` doesn't accept input.
lazy val customTest = inputKey[Unit]("custom test")
// This custom parser accepts a space separated list of arguments and then appends
// the fixed arguments to them. To do further parsing based on the user-specified
// arguments, use `flatMap` and return the next Parser.
lazy val testParser =
Def.spaceDelimited().map( (explicitArgs: Seq[String]) =>
explicitArgs ++ Seq("--bar", "--baz", "--qux", "--quux", "someDirectory")
)
customTest := {
// the result of parsing
val args = testParser.parsed
// auto-detected main class: can replace with literal string
val main = (mainClass in Compile).value getOrElse error("No main class detected.")
// main classpath, including compiled classes
val classpath = (fullClasspath in Compile).value.files
// provides Scala code execution
val scalaRun = (runner in (Compile, run)).value
val result = scalaRun.run(main, classpath, args, streams.value.log)
// handle any error
result foreach { errorMsg => sys.error(errorMsg) }
}
Upvotes: 4