0

I'm working on a Ruby gem. I'm writing unit tests for it in minitest.

Currently I'm using require_relative 'lib/my_gem' to load the gem scripts for test purposes.

Eventually I'll be publishing the gem to rubygems.org for public use.

At that point, I'd like to test that the unit tests still pass when I do a require 'my_gem'. This should give some confirmation that users of that gem, when they install it, will get the same exact results that I do.

What is the correct way to do that in rake or minitest (or some other technique)?

It would be ideal to be able to flip back and forth using a command line arg.

Ruby: 3.2.3, minitest:5.25.4 rake:13.2.1

2
  • It would probably be easier to just use require 'my_gem' in your tests. Adding your lib directory to $LOAD_PATH should do the trick. In Rake there's Rake::TestTask#libs. Commented Mar 12 at 8:02
  • To advance on what @Stefan is saying - typically in a gem your lib/gem_name.rb file will handle requiring all the parts so your tests should be requiring this file instead of loading files individually. Some gems are split into sections which let you just require parts of the gem - ActiveSupport is a really good example of this. Commented Mar 13 at 15:59

1 Answer 1

1

TBH as a gem maintainer I have never needed to run gem tests against some specific release. But it seems the following approach should work in your case:

  • use require "<my-gem>" in tests
  • run tests with bundler - bundle exec rake ...
  • have 2 Gemfile files to run tests with local source code and with installed locally gem

Developing a gem you usually include dependencies declared in a gemspec file into a Gemfile file with the gemspec declaration:

# Gemfile

gemspec

# development dependencies
# ...

It adds into a Gemfile.lock file declaration to use source code of the developed gem (my-gem) from source code located in the current directory. For instance for a gem I am maintaining (dynamoid) it looks like the following:

PATH
  remote: .
  specs:
    dynamoid (3.11.0)
      activemodel (>= 4)
      aws-sdk-dynamodb (~> 1.0)
      concurrent-ruby (>= 1.0)

More details you may find here - https://bundler.io/guides/rubygems.html.

In the second Gemfile to run tests agains a released version of your gem you may require explicitly my-gem with a specific version instead of using gemspec method:

# Gemfile

gem "<my-gem>", "1.0"

# development dependencies
# ...

As an option you can use a single Gemfile and check some env variable to either use gemspec method or declare explicitly a dependency on my-gem:

# Gemfile

if ENV['MY_GEM_VERSION']
  gem 'my-gem', ENV['MY_GEM_VERSION']
else
  gemspec
end

# development dependencies

Usually I use the following dirty hack to run some gem's tests locally:

  1. install dependencies with bundle install command
  2. use ruby -I ./lib -I ./test rake test to run tests agains the source code
  3. use rake test to run tests agains an installed gem version
Sign up to request clarification or add additional context in comments.

4 Comments

I don't think they are asking about extrernal dependencies. Rather it's about loading the files in the gem intself.
@max sort of. Creating a gem has several things you have to do correctly. for example naming all the files I need in the .gemspec file. How do I know I did that correctly? If my unit tests pass the same way if I use require_relative (from the local directory) and require (after I publish and then install from rubygems.org) then that's a bit of evidence that I set the gemspec correctly. So I would prefer to not just continually edit the minitest files back and forth. Is there a different technique I can use?
Wondering why require_relative is used in the tests. Bundler ensures that when require <my-gem> is called local source code is used instead of any installed version by default.
@max Yeah, I understand and my answer is about running a command with bundle exec (e.g. to run tests) either with loading a gem's local source code or loading an installed gem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.