как найти путь к файлам исходного кода Java при выполнении тестов JUnit через Bazel

Я хотел бы проверить текстовый файл в нашей кодовой базе monorepo с помощью тестов JUnit. Тесты JUnit выполняются через bazel testкоманда. Как я могу настроить Bazel для передачи пути к каталогу исходного кода (не пути к кэшированному скомпилированному файлу JAR) в мои модульные тесты? это могут быть аргументы CLI, переменные среды и т. д.

1 ответ

Один из способов сделать это — использовать dataкоторый делает файлы доступными для тестов (и других двоичных файлов) во время выполнения, а для Java есть библиотека Runfiles, предоставляемая вместе с Bazel, для поиска файлов данных. Например:

BUILD:

      java_test(
  name = "TextFileTest",
  srcs = ["javatests/txtfile/TextFileTest.java"],
  data = ["text.txt"],
  deps = [
      "@bazel_tools//tools/java/runfiles:runfiles",
      "@maven//:junit_junit",
  ],
)

WORKSPACE:

      load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

RULES_JVM_EXTERNAL_TAG = "4.2"
RULES_JVM_EXTERNAL_SHA = "cd1a77b7b02e8e008439ca76fd34f5b07aecb8c752961f9640dea15e9e5ba1ca"

http_archive(
    name = "rules_jvm_external",
    strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
    sha256 = RULES_JVM_EXTERNAL_SHA,
    url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)

load("@rules_jvm_external//:defs.bzl", "maven_install")

maven_install(
    artifacts = [
        "junit:junit:4.13.2",
    ],
    repositories = [
        "https://repo1.maven.org/maven2",
    ],
)

javatests/txtfile/TextFileTest.java:

      package txtfile;

import com.google.devtools.build.runfiles.Runfiles;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.Path;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class TextFileTest {

  @Test
  public void testTextFile() throws Exception {
    Runfiles runfiles = Runfiles.create();
    Path path = Paths.get(runfiles.rlocation("__main__/text.txt"));
    String line = Files.readAllLines(path).get(0);
    Assert.assertEquals(line, "this is text");
  }
}

text.txt:

      this is text
      $ bazel test TextFileTest
INFO: Build option --test_sharding_strategy has changed, discarding analysis cache.
INFO: Analyzed target //:TextFileTest (0 packages loaded, 547 targets configured).
INFO: Found 1 test target...
Target //:TextFileTest up-to-date:
  bazel-bin/TextFileTest.jar
  bazel-bin/TextFileTest
INFO: Elapsed time: 0.288s, Critical Path: 0.01s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action
//:TextFileTest                                                 (cached) PASSED in 0.3s

Executed 0 out of 1 test: 1 test passes.
INFO: Build completed successfully, 1 total action

Обратите внимание, что в runfiles.rlocation("__main__/text.txt")это имя рабочей области, которое по умолчанию __main__. Если есть workspace(name = "workspace name")в файле WORKSPACE, тогда имя рабочей области будет установлено из него.

Другие вопросы по тегам