scala-cli icon indicating copy to clipboard operation
scala-cli copied to clipboard

Support tests with JUnit on Scala Native

Open Gedochao opened this issue 9 months ago • 5 comments

Is your feature request related to a problem? Please describe. Given the following code with JUnit:

//> using test.dep org.junit.jupiter:junit-jupiter:5.12.1
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.Assertions._

class SimpleTest {
  @Test
  def testTrue(): Unit = {
    assertTrue(true)
  }
}
scala-cli test .
# Downloading 2 dependencies and one internal dependency
# Compiling project (test, Scala 3.6.4, JVM (23))
# Compiled project (test, Scala 3.6.4, JVM (23))
# No test framework found

Currently, Scala CLI doesn't detect JUnit tests out of the box. SBT supports it via https://github.com/sbt/sbt-jupiter-interface, but adding the interface as a dependency is evidently not enough:

//> using test.dep net.aichler:jupiter-interface:0.11.1
// this doesn't help, posting for awareness.

What's worse, this actually crashes on Scala Native, where there seems to be a separate TestAdapter for handling JUnit... which Scala CLI doesn't handle.

scala-cli test . --native
# Compiling project (test, Scala 3.6.4, Scala Native 0.5.7)
# Compiled project (test, Scala 3.6.4, Scala Native 0.5.7)
# [info] Linking (multithreadingEnabled=true, disable if not used) (1296 ms)
# [info] Discovered 1510 classes and 9502 methods after classloading
# [info] Checking intermediate code (quick) (93 ms)
# [info] Discovered 1465 classes and 7418 methods after optimization
# [info] Optimizing (debug mode) (2482 ms)
# [info] Produced 10 LLVM IR files
# [info] Generating intermediate code (3319 ms)
# [info] Compiling to native code (1559 ms)
# [info] Linking with [pthread, dl, m]
# [info] Linking native code (immix gc, none lto) (142 ms)
# [info] Postprocessing (0 ms)
# [info] Total (8450 ms)
# Error: scala.NotImplementedError: an implementation is missing

The crash actually comes from here: (indeed, we have not implemented this) https://github.com/VirtusLab/scala-cli/blob/50868ed74c0ec1058d3e63db6d69182fdd33e5d2/modules/test-runner/src/main/scala/scala/build/testrunner/AsmTestRunner.scala#L84-L92

Describe the solution you'd like Optimally, we could look for a way to support JUnit. Minimally, we should prevent projects from JUnit from crashing with Scala Native.

Gedochao avatar Apr 09 '25 15:04 Gedochao

One way to solve some problems would be to just use Bloop for running. We wouldn't need to implement things twice. There is already an endpoint for that.

tgodzik avatar Apr 09 '25 15:04 tgodzik

https://github.com/scalacenter/bloop/blob/main/frontend/src/main/scala/bloop/bsp/BloopBspServices.scala#L807 here

tgodzik avatar Apr 09 '25 15:04 tgodzik

One way to solve some problems would be to just use Bloop for running. We wouldn't need to implement things twice. There is already an endpoint for that.

We likely could, but we'd still need to keep the existing solution for use with --server=false...

Gedochao avatar Apr 09 '25 15:04 Gedochao

One way to solve some problems would be to just use Bloop for running. We wouldn't need to implement things twice. There is already an endpoint for that.

We likely could, but we'd still need to keep the existing solution for use with --server=false...

I always forget about that one. Though we should be able to somehow resue how Bloop works with the tests. Maybe we could extract a module? 🤔

tgodzik avatar Apr 09 '25 15:04 tgodzik

Ah, interesting. Turns out it can be made to work.

com.novocode:junit-interface covers for JUnit 4 only (and not 5, like junit-jupiter), but it is perhaps good enough for the time being. The following code works fine:

//> using dep com.novocode:junit-interface:0.11
import org.junit.Test

class MyTests {

  @Test
  def foo(): Unit = {
    assert(2 + 2 == 4)
    println("Hello from " + "tests")
  }
}

...for as long as we don't run it with --native, of course. Then it crashes rather ungracefully. Adjusted the issue title.

We just need a fix for Scala Native, I think. If we ever decide JUnit 5 is to be supported as well, it would warrant a dedicated issue (as we'd need some more sophisticated workaround to catch Jupiter tests, like SBT does).

Gedochao avatar Apr 10 '25 09:04 Gedochao