Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve rspec --init. #1219

Merged
merged 3 commits into from Dec 23, 2013
Merged

Improve rspec --init. #1219

merged 3 commits into from Dec 23, 2013

Conversation

myronmarston
Copy link
Member

@myronmarston myronmarston commented Dec 15, 2013

  • Add lots more suggested settings to spec_helper.rb
    to give a great initial experience.
  • Add a cucumber scenario that demonstrates that the
    settings generated by rspec --init are all valid.
    It doesn't demonstrate that they do what they are
    intended to do, but it protects against misspelled
    settings and whatnot.
  • Remove old cruft.
  • Put the init contents in their own files. Much
    cleaner than using heredocs.

I'd like some 馃憖 on this to see what others think about all the settings this adds. Is this overkill? I think it'll make for a better starting experience to have more in the generated spec_helper.rb file. Are there any settings I've added that shouldn't be included? Anything I'm missing?

It would also be good to find a way to allow rspec-rails' generator to leverage this and build on top of it for the additional rails-specific stuff it adds. I'm not sure of the best way to do that, though.

/cc @alindeman @JonRowe @xaviershay @soulcutter @samphippen

- Add lots more suggested settings to spec_helper.rb
  to give a great initial experience.
- Add a cucumber scenario that demonstrates that the
  settings generated by `rspec --init` are all valid.
  It doesn't demonstrate that they do what they are
  intended to do, but it protects against misspelled
  settings and whatnot.
- Remove old cruft.
- Put the init contents in their own files. Much
  cleaner than using heredocs.
@@ -0,0 +1,3 @@
--color
--warnings
-rspec_helper
Copy link
Member

@yujinakayama yujinakayama Dec 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is prone to be confused as if there's -rspec_helper option. Maybe --require spec_helper would be more explicit.

Copy link
Member Author

@myronmarston myronmarston Dec 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea. Fixed in 9387778.

@JonRowe
Copy link
Member

JonRowe commented Dec 15, 2013

LGTM, 馃憤 on the explanations for each setting

@@ -16,3 +17,19 @@ Feature: --init option
"""
When I run `rspec --init`
Then the output should contain "exist .rspec"

Scenario: Accept and use the recommended settings in spec_helper (which are initially commented out).
Copy link
Member

@xaviershay xaviershay Dec 15, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cuke is a good idea.

@xaviershay
Copy link
Member

xaviershay commented Dec 15, 2013

Fantastic change overall, left some specific opinions on individual settings.

@myronmarston
Copy link
Member Author

myronmarston commented Dec 16, 2013

BTW, @xaviershay, thanks for the detailed feedback.

- Add missing back ticks.
- Combine `filter_run`/`run_all_when_everything_filtered`
  configs and explanations.
- Remove the `expose_dsl_globally = false` config for now,
  with the plan to potentially add it back in a later
  release if user feedback about it is positive.
- Re-order things a bit.
@myronmarston
Copy link
Member Author

myronmarston commented Dec 22, 2013

I'd love to merge this soon, but given that the recommendations that show up in the generated spec_helper.rb go directly against what rspec-rails generates, it would be good to have a definitive plan to resolve that (even if we don't implement it yet). @alindeman -- can you weigh in, please?

@JonRowe
Copy link
Member

JonRowe commented Dec 23, 2013

rspec-rails is great for newbies getting into rspec and or rails. Personally I'd advocate against using it if you're a seasoned Ruby dev, it's only ever added pain for me. Note that this is isn't RSpec's fault, but Rails fault. As such I'm ok with it being slightly at odds with pure rspec.

I've always seen rspec-rails as being "rspec the rails way"

@alindeman
Copy link
Contributor

alindeman commented Dec 23, 2013

I'd love to merge this soon, but given that the recommendations that show up in the generated spec_helper.rb go directly against what rspec-rails generates, it would be good to have a definitive plan to resolve that (even if we don't implement it yet). @alindeman -- can you weigh in, please?

Is there anything in this improved spec_helper.rb that will cause issues in -rails by default? If not, I'm 馃憤 to synchronize them.

@alindeman
Copy link
Contributor

alindeman commented Dec 23, 2013

I've always seen rspec-rails as being "rspec the rails way"

I definitely agree with this. I think RSpec has the potential to be offputting to new Rails users if there is a significant barrier to entry, even if it's an objectively superior way of writing tests.

That said, compromises like a rails_spec_helper.rb that default to the slow, coupled, though "rails" way, alongside another file that allows you to iterate toward a faster, less coupled, "modular" way is really appealing to me.

馃憤 to a spec_helper.rb that matches here (can we just invoke it directly in rspec-rails?), though with a rails_spec_helper.rb that has more rails-y defaults.

@myronmarston
Copy link
Member Author

myronmarston commented Dec 23, 2013

Is there anything in this improved spec_helper.rb that will cause issues in -rails by default? If not, I'm 馃憤 to synchronize them.

Not that I can think of. Note that all the settings in this file are commented out by default since they are all just suggestions. The defaults of disabling the :should syntax for rspec-mocks and rspec-expectations could potentially cause issues if anything in rspec-rails assumes the :should syntax is available....that's the one possible issue I can think of.

@myronmarston
Copy link
Member Author

myronmarston commented Dec 23, 2013

I definitely agree with this. I think RSpec has the potential to be offputting to new Rails users if there is a significant barrier to entry, even if it's an objectively superior way of writing tests.

That said, compromises like a rails_spec_helper.rb that default to the slow, coupled, though "rails" way, alongside another file that allows you to iterate toward a faster, less coupled, "modular" way is really appealing to me.

Right...using require 'rails_spec_helper' rather than require 'spec_helper' in your spec files doesn't seem like much of a barrier to entry.

馃憤 to a spec_helper.rb that matches here (can we just invoke it directly in rspec-rails?), though with a rails_spec_helper.rb that has more rails-y defaults.

I don't know much about the rails generators. If you can run arbitrary code during a rails generator you can have it run RSpec::Core::ProjectInitializer.new.run. Alternately, if you want it to emit your own output to match the typical generator output, you can just use the dot_rspec and spec_helper files that this PR adds, and write them to disk from your generator w/ whatever output you need. Or we can improve ProjectInitializer to make it usable by rspec-rails if there is a simple change we can do to help. Let us know what you need.

Anyhow, I'm going to merge since we all seem to be on the same page about this :).

myronmarston added a commit that referenced this pull request Dec 23, 2013
@myronmarston myronmarston merged commit 98c6ad4 into master Dec 23, 2013
@myronmarston myronmarston deleted the rspec-init branch Dec 23, 2013
@alindeman
Copy link
Contributor

alindeman commented Dec 23, 2013

Or we can improve ProjectInitializer to make it usable by rspec-rails if there is a simple change we can do to help. Let us know what you need.

Got it! I've added it to the list鈩 and will try to get to it this week.

@slowjack2k
Copy link

slowjack2k commented Sep 24, 2015

Hi,

I have a question to those 2 helpers.

Say I have a spec a_spec.rb which requires 'rails_spec_helper'
and a spec b_spec.rb which only requires 'spec_helper' .

When I run

rspec a_spec.rb b_spec.rb

will rspec clean every thing up or will b_spec.rb run with every thing loaded?

Further more when I configure additional settings, for instance

within rails_spec_helper

config.use_transactional_fixtures = true

within spec_helper

config.use_transactional_fixtures = false

will they mess up?

regards
dieter

@myronmarston
Copy link
Member Author

myronmarston commented Sep 24, 2015

will rspec clean every thing up or will b_spec.rb run with every thing loaded?

I'm not sure what you mean by "will rspec clean every thing up" but ruby does not provide a way to "unrequire" a file and it would be confusing/surprising for RSpec to do that to a file you have required -- so for the command you provided, the specs will run with both helper files loaded (assuming you are requiring the helper files at file load time rather than within an individual spec).

will they mess up?

Yes. config.use_transactional_fixtures is global state. If you set it to one value, then change it to a new value, it'll be set to the new value. I wouldn't recommend setting it in different files.

Besides, use_transaction_fixtures is not an rspec-core config option -- it's one added by rspec-rails to support rails testing and as such, it doesn't really make sense to set it in spec_helper.rb as spec_helper.rb is intended for "base" RSpec options and is meant to be usable w/o rails or rspec-rails (but also with rails and rspec-rails).

@slowjack2k
Copy link

slowjack2k commented Sep 24, 2015

Thanks for the explanation @myronmarston . It answers my question. With 'clean every thing up' I meant reset Rspec config and unload every thing accordingly. Until now I thought rspec will fork new processes or call system or some thing else. So that every spec is run in a clean environment.

config.use_transactional_fixtures was only an example but I should have been more accurate
and call the 2 helpers unit_spec_helper.rb and acceptance_spec_helper.rb.

So when I set

# acceptance_spec_helper.rb
RSpec.configure do |config|
config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end
# unit_spec_helper.rb
RSpec.configure do |config|
config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

It will screw depending on the execution order of my specs.

So whats the best way to deal with such different rspec configurations?

@myronmarston
Copy link
Member Author

myronmarston commented Sep 25, 2015

I'm not totally sure how you want your configuration to behave, but my best guess at what you want is this:

# unit_spec_helper.rb
RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end
end
# acceptance_spec_helper.rb
RSpec.configure do |config|
  original_strategy = nil

  config.before(:context, :file_path => /spec\/acceptance/) do
    original_strategy = DatabaseCleaner.strategy
    DatabaseCleaner.strategy = :truncation
  end

  config.after(:context, :file_path => /spec\/acceptance/) do
    DatabaseCleaner.strategy = original_strategy
  end
end

This sets the default global strategy to :transaction but then in acceptance_spec_helper.rb sets things up so that before specs in spec/acceptance get run, the strategy is temporarily changed to :truncation and then changed back afterwards.

Is that the behavior you're trying to achieve?

@slowjack2k
Copy link

slowjack2k commented Sep 25, 2015

@myronmarston I think your solution is the nearest as I come to my goal and I appreciate your help. To explain it a little furthor my folder layout:

  • spec/
    • support
    • acceptance
    • support
    • integration
    • support
    • unit
      • support
    • spec_helper.rb
    • rails_helper.rb
    • acceptance_spec_helper.rb
    • integration_spec_helper.rb
    • unit_spec_helper.rb

Unit Specs are without external deps (as far as you can achieve it within rails), so they require only spec_helper.rb & global support & unit support folder.

Integration specs are with external deps, so they require only rails_helper.rb & global support & integration support folder. They need the DB-Cleaner settings.

Acceptance are end to end tests so they require only rails_helper.rb & global support & acceptance support folder. Because these tests use for instance capybara so I can't use transactional fixtures. But furthor more I need some more around filters for instance:

 config.after(:each) do
    wait_for_ajax if respond_to? :wait_for_ajax
  end

But this is only a starting point. The configurations will differ more and more over time I think.

When I get you right I have to ensure that I use config.before(:context, :file_path => /spec\/acceptance/)
and must ensure that my support methods, modules, classes don't interfer each other.

Edit: Can't rspec fork before a spec file is loaded and executed? This would solve my issues ;).

Edit2: I tried your approach but it didn't work. config.use_transactional_fixtures can't be changed within a before hook and DatabaseCleaner has no getter for strategy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants