Skip to content

rb_minitest test wrapper helper #223

@noahkawasakigoogle

Description

@noahkawasakigoogle

Just wanted to contribute how I've gotten minitest to work well with rules_ruby in case others also need to use minitest.

The current rb_test() rule works well for RSpec, which supports glob syntax for test file inputs as well as multiple arguments: https://stackoverflow.com/questions/48778373/how-to-run-multiple-specific-rspec-tests

Suppose this is our test directory:

# spec/
#          test_file.rb
#          another_test_file.rb

This will run both test files with rspec.

rb_test(
    name = "add",
    srcs = glob(["spec/*.rb"]),
    args = glob(["spec/*.rb"]),
    main = "@bundle//bin:rspec",
    deps = [
        ":spec_helper",
        "@bundle",
    ],
)

Unfortunately minitest (Ruby's default test framework) has zero glob support nor the ability to run multiple files as arguments.

rb_test(
    name = "add",
    srcs = glob(["spec/*.rb"]),
    args = glob(["spec/*.rb"]),
    deps = [
        ":spec_helper",
        "@bundle",
    ],
)

This target will run ruby spec/test_file.rb spec/another_test_file.rb however, the second argument will be ignored and left out completely. Only spec/test_file.rb will actually execute.

Here is a minitest wrapper that works well with Bazel glob syntax and providing multiple test files to a single target:

load("@rules_ruby//ruby:defs.bzl", "rb_test")

def rb_minitest(test_files, **kwargs):
    # This adds root of bazel workspace to $LOAD_PATH with the "-I." flag.
    # Which means each test file given to ruby executable as an arg needs to be full path.
    # So we transform the test_files into full path.
    test_files_full_path = ["%s/%s" % (native.package_name(), file) for file in test_files]
    rb_test(
        srcs = test_files,
        args = [
            "-I.",
            "-e",
            "\"ARGV.each { |f| require f }\"",
        ] + test_files_full_path,
        **kwargs
    )

BUILD.bazel example:

rb_minitest(
    name = "tests",
    test_files = glob([
        "spec/*.rb",
    ]),
    deps = [
      ...
    ],
)

A few things to note:

  • Adding -I. to the ruby execution adds . to the $LOAD_PATH, meaning the root of the bazel workspace. For this reason its good to change all require statements to use absolute paths for all ruby imports besides (external gems from the bundle repo).
  • test_files abstracts away the need to provide both srcs and args, which typically will be the same exact file set but with different string values. srcs will be relative file paths from the package path, while args will be full paths from the root of the repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions