3

Say I have a scalatest class in main/scala, like

import org.scalatest.FunSuite

class q3 extends FunSuite {
    test("6 5 4 3 2 1") {
        val digits = Array(6,5,4,3,2,1)
        assert(digits.sorted === Array(1,2,3,4,5,6))
    }
}

How do I run it with sbt?

I've tried sbt test, sbt testOnly, sbt "testOnly *q3" and they all had output like

[info] Run completed in 44 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 0, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] No tests were executed.
[info] No tests to run for Test / testOnly

A similar question from a few years back said they successfully used testOnly but I can't get it to work.

The metals extension on VSCode shows a "test" link when the file is open which successfully runs the test, but doesn't show how it does that. I want to know how to do it through sbt.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
Noam Eyal
  • 318
  • 2
  • 7
  • 2
    Why would you want to run tests in main? Makes no sense. Sbt looks under /test for tests by default so you will have to find a way to change that – sinanspd Feb 06 '20 at 21:41
  • I'm using sbt to put together answers to an assignment and would like them all to be in one directory for simplicity, but some of the questions include writing tests. I know it's not a common thing, I'm just wondering if it's doable. – Noam Eyal Feb 06 '20 at 21:45
  • 2
    You can probably override it by changing stuff in the class path ( https://www.scala-sbt.org/1.x/docs/Classpaths.html ) but If you think this is simple, I can tell you it's not. Standard practices and code organization exist for a reason. We want our code to be as organized as possible. That is ***one*** of the ideas behind microservices. Instead of having a thousand files in one repo, we separate them to many repos/modules etc. I guarantee you this will confuse the hell out of your teacher – sinanspd Feb 06 '20 at 21:53
  • my teacher prefers that they're all in one directory, but if there's no way then there's no way. I'm still confused how the extension runs it though? – Noam Eyal Feb 06 '20 at 22:00
  • 1
    He/She probably meant one project directory. If he/she actually said tests should go in the main directory please tell her/him to quit teaching asap. What extension are you referring to ? – sinanspd Feb 06 '20 at 22:03
  • VSCode metals? And this course isn't on how to make good scala projects (or on scala in particular to be honest) hence the lack of rules. I'm the only person even using sbt. – Noam Eyal Feb 06 '20 at 22:15
  • @sinanspd there are languages like **JavaScript** & **Python** where it is common to have the tests on the same folder as the main code. Thus, the requeriment isn't that weird. – Luis Miguel Mejía Suárez Feb 06 '20 at 22:46
  • @LuisMiguelMejíaSuárez with all due respect, while that's correct, I don't think it is right to operate under the common practices of other languages my friend. Especially when the examples you provided are interpreted languages. Forcing the main thread to run tests in a compiled language have a lot of implications on performance, compile time (which sbt already isn't great with) etc. I don't find it wise to compare the capabilities of an IDE to a build tool for they have different requirements they need to satisfy. Just my two cents. Everyone is welcome to organize their code as they please – sinanspd Feb 06 '20 at 23:43
  • 1
    @sinanspd hey I do agree and I would never recommend this setup for a _"real"_ project (whatever that means). My point was mostly that, if the class is not about Scala or any other particular programming language, and students are free to use which one they prefer and the professor has most of his/her experience working with those languages. Then, the idea of wanting to have tests and main in the same folder seems reasonable. Now, whenever that was a good methodology or not, or if the professor should respect the standards of each language; is, IMHO, is outside of what we should discuss here. – Luis Miguel Mejía Suárez Feb 07 '20 at 00:23

1 Answers1

4

Put ScalaTest on Compile classpath in build.sbt like so

libraryDependencies += "org.scalatest" %% "scalatest" % "3.1.0"

and then call org.scalatest.run runner explicitly from within an App, for example,

object MainTests extends App {
  org.scalatest.run(new ExampleSpec)
}

Putting it together we have in src/main/scala/example/MainTests.scala

package example

import org.scalatest.matchers.should.Matchers
import org.scalatest.flatspec.AnyFlatSpec
import collection.mutable.Stack
import org.scalatest._

class ExampleSpec extends AnyFlatSpec with Matchers {
  "A Stack" should "pop values in last-in-first-out order" in {
    val stack = new Stack[Int]
    stack.push(1)
    stack.push(2)
    stack.pop() should be (2)
    stack.pop() should be (1)
  }
}

object MainTests extends App {
  org.scalatest.run(new ExampleSpec)
}

and run it with runMain example.MainTests. Furthermore, we could gather tests in Suites and execute all like so

class ExampleASpec extends FlatSpec with Matchers {
  "ExampleA" should "run" in { succeed }
}
class ExampleBSpec extends FlatSpec with Matchers {
  "ExampleB" should "run" in { succeed }
}

class ExampleSuite extends Suites(
  new ExampleASpec,
  new ExampleBSpec,
)

object MainTests extends App {
  (new ExampleSuite).execute()
}
Mario Galic
  • 47,285
  • 6
  • 56
  • 98