Gregg
Gregg

Reputation: 499

Mapping from Maven standard directory to Bazel for test resources

We have test dependency files in src/test/resources per the Maven Standard Directory Layout. These test files end up in the JAR and on the classpath when test classes fetch them via, e.g. Resources#asCharSource.

What is the preferred way in Bazel to depend to test files and have them appear in the classpath?

I have the following in my src/test/resources/BUILD:

filegroup(
    name = "test-deps",
    testonly = 1,
    srcs = glob(["*.txt"]),
    visibility = ["//visibility:public"],
)

And the following in my src/main/java/com/path/to/my/test/BUILD:

java_test(
    name = "MyTest",
    srcs = ["MyTest.java"],
    resources = ["//src/test/resources:test-deps"],
    test_class = "com.path.to.my.test.MyTest",
    deps = [
        "//src/main/com/path/to/my/code",
        "//:junit_junit",
    ],    
)

This works, but I'm not sure if it is the best way in Bazel.

Upvotes: 4

Views: 3556

Answers (1)

kris
kris

Reputation: 23592

Yes, that is the recommended approach. As mentioned in the docs for resources, Bazel understands the Maven Standard Directory Layout and will put the data files at the right classpath:

The location of the resources inside of the jar file is determined by the project structure. Bazel first looks for Maven's standard directory layout, (a "src" directory followed by a "resources" directory grandchild).

If you wanted to bundle the resource separately, you could create a resources-only jar and then depend on it with the resource_jars attribute.

Edit: as Ittai points out below, Bazel will not introspect resources, so you'd have to be careful not to end up with any collisions (e.g., pkg1/src/main/resources/foo and pkg2/src/main/resources/foo). Neither resources not resource_jars will check this for you, so if this is a concern, you might want to put any resources you need in a filegroup and have a genrule target or test that checks for collisions.

Upvotes: 5

Related Questions