davetron5000 / gli

Make awesome command-line applications the easy way
http://davetron5000.github.io/gli
Apache License 2.0
1.26k stars 102 forks source link

Testing with rspec #221

Closed edusantana closed 3 years ago

edusantana commented 9 years ago

Sorry... I'm not a good ruby programmer, but, can you help us to write a rspec test? How can we do it?

I see the cucumber test, but that's not what I would like to do.

davetron5000 commented 9 years ago

GLI is set up to use Test::Unit for unit testing, but you can use rspec pretty easily. After installing it (put it in your Gemfile or just do gem install rspec), just create specs.

This might help: http://stackoverflow.com/questions/12307097/how-to-use-rspec-without-rails

But, basically create a spec directory from the root of your GLI app, and create _spec.rb files in there that run your unit tests.

The default unit test that GLI creates would look like this in RSpec:

require 'rspec'

RSpec.describe "test spec" do
  before do
  end

  after do
  end

  it "works" do
    expect(true).to eq(true)
  end
end
rspec spec/test_spec.rb 
.

Finished in 0.00131 seconds (files took 0.07533 seconds to load)
1 example, 0 failures

Let me know if that helps.

davetron5000 commented 9 years ago

Edit: "dummy" meant "this spec is just a dumb spec" not "you are a dummy". Changed the test so that's clear. Did not mean to imply you are a dummy for not knowing this (I find RSpec very confusing myself)

johannkm commented 7 years ago

What is the API we should use to call commands in order to test them?

davetron5000 commented 7 years ago

You can exercise the commands as you would normally, i.e. as they are done in the Test::Unit tests. There shouldn't be anything specific you need to do.

johannkm commented 7 years ago

Can you give an example of how I would call a command that I defined in the executable from my _spec.rb files?

Thanks for getting back to me.

davetron5000 commented 7 years ago

It depends on what you are trying to test. Generally you wouldn't test a Command because that's provided by GLI and you don't need to test GLI.

SUppose you have defined this:

command :foo do |c|
   c.action do |global_options,command_options,args|
      message = command_options[:loud] ? "HI" : "hello"
      puts message
   end
end

GLI provides no way to test the action block directly. The common pattern is to have it defer to a regular ruby class you can test:

command :foo do |c|
   c.action do |global_options,command_options,args|
      puts Message.new(command_options).hi
   end
end

class Message
  def initialize(options={})
    @options = options
  end

  def hi
      if @options[:loud]
        "HI"
      else
        "hello"
      end
  end
end

RSpec.describe Message do
  describe "#hi" do
    it "yells when asked" do
      expect(Message.new(loud: true).hi).to eq("HI")
    end
    it "is quiet when not asked to be loud"
      expect(Message.new.hi).to eq("hellow")
    end
  end
end

It's more code, but then you can test against basic Ruby classes and not GLI's internals.

Not sure if that's what you were thinking of?

If you really do want to execute GLI commands, you can instantiate them and call methods—they are just Ruby classes, to. There's nothing specific to RSpec you'd need to know.