sbt 如何在 scala 代码中访问项目的基本目录

sbt how to access base directory of project in scala code

我得到了一个供应商创建的代码,看起来他们的工程师在单元测试中做了很多硬编码。 我有一个函数的单元测试,它输出作为代码一部分生成的报告的完整绝对路径作为字符串。 目前失败的单元 test/assertion 看起来像

val reportPath  = obj.getReportPath()
assert(reportPath.equals("file:/Users/khalid.mahmood/ReportingModule/target/report.csv")

其中 ReportingModule 是项目的名称。

代码逻辑对我来说很好,reportPath 变量的值是:

file:/Users/vikas.saxena/coding_dir/ReportingModule/target/report.csv

因为我已将项目克隆到主目录中名为 coding_dir 的子目录中,所以逻辑对我来说没问题。

我想修改断言以确保代码自行获取项目的基本目录,并且在谷歌搜索中我发现 sbt 具有 base 相当于 project.baseDir (from maven) link

然而,以下代码更改对我来说没有效果

assert(reportPath.equals(s"""$base""" + "/target/report.csv")

我能得到一些关于如何正确执行此操作的指示吗?

如果您使用的是 ScalaTest,则可以 ConfigMap 执行此操作。

首先,您需要告诉 ScalaTest Runner 将路径添加到 ConfigMap。这可以在您的 .sbt 文件中完成,如下所示:

Test / testOptions += Tests.Argument(
  TestFrameworks.ScalaTest, s"-DmyParameter=${baseDirectory.value}")

(请注意,它不一定是 baseDirectory.value,许多其他 sbt 设置也可以。我建议针对您的特定用例使用 target.value)。

在测试本身中,您需要访问 ConfigMap 中的值。最简单的方法是使用 Fixture Suite(例如 FixtureAnyFunSuite) and mix in the ConfigMapFixture trait:

import org.scalatest.funsuite.FixtureAnyFunSuite
import org.scalatest.fixture.ConfigMapFixture

class ExampleTest extends FixtureAnyFunSuite with ConfigMapFixture {
  test("example") { configMap =>
    val myParameter = configMap.getRequired[String]("myParameter")
    // actual test logic goes here
    succeed
  }
}

当然还有其他方法可以解决问题。例如,您还可以简单地获取当前工作目录 (cwd) 并从那里开始工作。然而,这样做的缺点是,在多模块构建中,cwd 将根据 sbt 中的 Test / fork 设置是真还是假而有所不同。因此,为了使您的代码对这些可能发生的情况具有鲁棒性,我建议坚持使用 ConfigMap 方式。