Daniel Lucraft
2008-Sep-27 12:02 UTC
[rspec-users] Running RSpec from within my Ruby application
Hi all (I tried to send this question to the list a few hours ago, but it seems to have not got through. If it did sorry for the duplication.) Does anyone have any tips or examples of how to run RSpec example groups programmatically from within a Ruby application? Essentially I would like to be able to: 1. load example groups from a set of files I know about 2. run them 3. get back an object that contains information about successes and failures 4. reload the example groups I think I i can accomplish (3) with a custom formatter, (4) by reflecting on and undefining the classes Example::Subclass_1 etc as required. But I''m having real trouble with the first two steps. Here''s what I have so far: require ''rubygems'' require ''spec'' $spec_runner_at_exit_hook_registered = true require ''some_specs'' err = StringIO.new out = StringIO.new options = Spec::Runner::Options.new(err, out) options.add_example_group(Spec::Example::ExampleGroup::Subclass_1) runner = Spec::Runner::ExampleGroupRunner.new(options) runner.run puts "results:" puts out.string puts "\n\n[script end]" But the results string here claims that there were 0 examples run. By looking at the output I know that my example is being run however. Can someone help me put these pieces together? thanks, Dan
Daniel Lucraft
2008-Sep-27 15:25 UTC
[rspec-users] Running RSpec from within my Ruby application
Well, after some time fiddling, I''ve come up with this:
require ''rubygems''
# make sure nothing gets added to ruby''s at_exit hook:
$spec_runner_at_exit_hook_registered = true
# load RSpec
require ''spec''
require ''spec/runner/formatter/base_formatter''
# helper to find all defined example groups
def lookup_example_groups
cs = []
Spec::Example::ExampleGroup.constants.each do |c|
if c =~ /Subclass_/
cs << Spec::Example::ExampleGroup.const_get(c)
end
end
cs
end
# helper to undefine example groups
def clean_example_groups(groups)
groups.each do |c|
puts "cleaning #{c.to_s}"
Spec::Example::ExampleGroup.send(:remove_const,
c.to_s.split("::").last.intern)
end
end
# my custom formatter, mainly just a stub for now, but will be used
# to pass information about failing specs back to the gui.
class RubyFormatter < Spec::Runner::Formatter::BaseFormatter
def initialize
super(rspec_options, StringIO.new)
@pass_count = 0
@fail_count = 0
end
def start(example_count)
@example_count = example_count
end
def example_passed(*args)
@pass_count += 1
end
def example_failed(*args)
@fail_count += 1
end
def inspect
"<RubyFormatter total:#{@example_count}, passed:#{@pass_count},
failed:#{@fail_count}>"
end
end
# stub out options to use my own formatter
def rspec_options.formatters
@o ||= RubyFormatter.new
[@o]
end
# load the actual specs
load ''some_specs.rb''
# run the example groups
lookup_example_groups.each do |eg|
eg.run
end
# examine the results
p rspec_options.formatters.first
# undefine example groups
clean_example_groups(lookup_example_groups)
# clear up formatter
rspec_options.instance_variable_set(:@o, nil)
# system is now clean (?), and ready to reload specs etc
As you can probably tell, I''m coding without really understanding. This
works well enough for my
needs right now, but please let me know how these things can be done better.
thanks,
Dan
--- Daniel Lucraft <dan.lucraft at googlemail.com> wrote:
> Hi all
>
> (I tried to send this question to the list a few hours ago, but it
> seems to have not got through. If it did sorry for the duplication.)
>
> Does anyone have any tips or examples of how to run RSpec example
> groups programmatically from within a Ruby application?
>
> Essentially I would like to be able to:
> 1. load example groups from a set of files I know about
> 2. run them
> 3. get back an object that contains information about successes and
failures
> 4. reload the example groups
>
> I think I i can accomplish (3) with a custom formatter, (4) by
> reflecting on and undefining the classes Example::Subclass_1 etc as
> required.
>
> But I''m having real trouble with the first two steps.
Here''s what I have so far:
>
> require ''rubygems''
> require ''spec''
>
> $spec_runner_at_exit_hook_registered = true
> require ''some_specs''
>
> err = StringIO.new
> out = StringIO.new
> options = Spec::Runner::Options.new(err, out)
>
> options.add_example_group(Spec::Example::ExampleGroup::Subclass_1)
> runner = Spec::Runner::ExampleGroupRunner.new(options)
>
> runner.run
> puts "results:"
> puts out.string
> puts "\n\n[script end]"
>
> But the results string here claims that there were 0 examples run. By
> looking at the output I know that my example is being run however.
>
> Can someone help me put these pieces together?
>
> thanks,
> Dan
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>
Scott Taylor
2008-Sep-27 22:16 UTC
[rspec-users] Running RSpec from within my Ruby application
On Sep 27, 2008, at 8:02 AM, Daniel Lucraft wrote:> Hi all > > (I tried to send this question to the list a few hours ago, but it > seems to have not got through. If it did sorry for the duplication.) > > Does anyone have any tips or examples of how to run RSpec example > groups programmatically from within a Ruby application? > > Essentially I would like to be able to: > 1. load example groups from a set of files I know about > 2. run them > 3. get back an object that contains information about successes and > failures > 4. reload the example groups >I''m missing the why. What is the higher-level objective that you''re trying to accomplish? Seems like you want something like autotest + a custom formatter? Scott
Daniel Lucraft
2008-Sep-28 09:20 UTC
[rspec-users] Running RSpec from within my Ruby application
--- Scott Taylor <mailing_lists at railsnewbie.com> wrote:> I''m missing the why. What is the higher-level objective that you''re > trying to accomplish? Seems like you want something like autotest + a > custom formatter?The app (www.redcaride.com) has a plugin system with reloading, which lets you work on your plugin without restarting the application. Now I can reload and rerun the specs too, so you really do never have to leave the app. I know that this is a slightly dangerous way of running specs - but it is convenient. And I plan to make it almost as quick to load another app instance and run your specs in a clean fashion as well. best, Dan