8000 rb_minitest test wrapper helper · Issue #223 · bazel-contrib/rules_ruby · GitHub
[go: up one dir, main page]

Skip to content

rb_minitest test wrapper helper #223

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
noahkawasakigoogle opened this issue Apr 18, 2025 · 3 comments
Open

rb_minitest test wrapper helper #223

noahkawasakigoogle opened this issue Apr 18, 2025 · 3 comments
8000
Labels
help wanted Extra attention is needed

Comments

@noahkawasakigoogle
Copy link
Contributor
noahkawasakigoogle commented Apr 18, 2025

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.
@p0deje
Copy link
Member
p0deje commented Apr 18, 2025

@noahkawasakigoogle In my projects, I don't pass args at all to rb_test for RSpec and rely on the fact that only spec files declared as srcs/deps will be present in a runfiles tree. When rspec is being executed, it automatically picks up the spec files in spec/ directory. Have you tried using the same approach for minitest?

@noahkawasakigoogle
Copy link
Contributor Author
noahkawasakigoogle commented Apr 19, 2025

Unfortunately, Minitest just doesn't have that type of "magic" built in with any sort of test runner CLI tooling, its just barebones ruby CLI execution. Rake tasks + minitest makes this type of stuff possible, but minitest alone cannot do it. And using rake tasks with bazel just doesnt make sense, because Bazel should be the layer at which all the srcs/deps declarations are set for best caching behavior.

Luckily it's pretty easy to wrap in pure ruby, here are among the resources I dug through to figure this out.

@p0deje
Copy link
Member
p0deje commented Apr 20, 2025

Would you be up to open a PR adding this?

@p0deje p0deje added the help wanted Extra attention is needed label May 1, 2025
copybara-service bot pushed a commit to protocolbuffers/protobuf that referenced this issue May 14, 2025
Additional details discussed in bazel-contrib/rules_ruby#233 and bazel-contrib/rules_ruby#223

Restoring tests revealed latent bug in JRuby's `RubyMessage#convert` that was exposed by the introduction `test_to_hash` while tests were not running; fix included.

Closes #21733

COPYBARA_INTEGRATE_REVIEW=#21733 from protocolbuffers:fix_rb_test 3f8418f
PiperOrigin-RevId: 758470283
JasonLunn added a commit to protocolbuffers/protobuf that referenced this issue May 14, 2025
Additional details discussed in bazel-contrib/rules_ruby#233 and bazel-contrib/rules_ruby#223

Restoring tests revealed latent bug in JRuby's `RubyMessage#convert` that was exposed by the introduction `test_to_hash` while tests were not running; fix included.

Closes #21733

COPYBARA_INTEGRATE_REVIEW=#21733 from protocolbuffers:fix_rb_test 3f8418f
PiperOrigin-RevId: 758470283
shaod2 pushed a commit to shaod2/protobuf that referenced this issue May 14, 2025
)

Additional details discussed in bazel-contrib/rules_ruby#233 and bazel-contrib/rules_ruby#223

Restoring tests revealed latent bug in JRuby's `RubyMessage#convert` that was exposed by the introduction `test_to_hash` while tests were not running; fix included.

Closes protocolbuffers#21733

COPYBARA_INTEGRATE_REVIEW=protocolbuffers#21733 from protocolbuffers:fix_rb_test 3f8418f
PiperOrigin-RevId: 758470283
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants
0