At my job we have a number of rails projects with similar functionality. We have refactored some of the common functionality out into a gem that is included in all the projects.
The gem is just another rails project, providing models, controllers, and views to be added to the projects that include it.
How do I test the gem? It's not clear to me how to test it independently, but it doesn't make sense to write tests of the gem in the projects that include it.
You should have tests in the gem's project itself.
As an example you can see that cancancan has a directory structure similar to all other rails projects, with a root level 'spec' folder.
You may have to use rspec rather than rspec-rails depending on your gem setup, but there isn't any real magic sauce here. You should write tests that cover the functionality of the gem itself, within the gem's codebase. But you shouldn't be writing tests for the gem in the projects that include it. Or at least not more than you might for other gems (so there may be some mocking / verification / interface building, but no direct testing of the gem).
Related
I've got some helper code (monkey patches) I tend to carry around from rails project to rails project via simply copying files or pasting code into the initializers folder.
I think a clean way to deploy different categories of my initalizer code would be to simply add gems to my project Gemfile that would do the equivalent of this for me. I'm not very skilled at creating gems or the deeper side of ruby on rails engineering so I just wanted to know if this were possible before I got started with it.
Yes, this is definitely possible. It should be probably enough to make a simple gem, put your monkey-patches there and require them in the gem entry point (e.g., if the gem is called foobar, then bundler will require lib/foobar.rb by default).
There is a guide on creating gems available in Bundler docs. In case you need to interact with Rails application configuration, you can take a look at Rails Engines.
I notice after reading the rails guide docs
that minitest comes with the newer Ruby versions out of the box, so it's available right away, no need to install anything else. Rails 4 by default use that.
If fact i use the minitest-reporter gem and it work like charm.
The confusion comes when i see examples defining the :test group of the gemfile like this:
group :test do
gem 'minitest-rails'
gem 'minitest-rails-capybara'
gem 'minitest-colorize'
gem 'minitest-focus'
end
Why is the need of include a minitest-rails gem ?? To use some rails generation later or other kind of specs ??
I'm kinda confused here so any thought about Rails 4 Minitest integration will be appreciated.
According to the mini-test rails README, it makes it so Rails generators for tests will generate in minitest style. It also makes it so minitest style actually works in Rails ActiveSupport::TestCase test classes. (which is what Rails test cases do).
minitest comes with ruby, but the Rails' ActiveSupport::TestCase, which Rails test classes all are, doesn't normally use minitest. minitest-rails makes it so it does.
This project aims to enable Minitest within the Rails TestCase classes. Your test will continue to inherit from ActiveSupport::TestCase, which will now support the spec DSL. You can generate test files with the standard model, controller, resource, and other generators:
https://github.com/blowmage/minitest-rails
One thing that makes this more confusing, is that in newer versions of ruby [i accidentally said 'Rails' before, but it's newer versions of ruby that matter], it's true that Minitest is there and old Test::Unit is not. But Minitest has a sort of "pretend to be Test::Unit" mode -- that's what Rails ActiveSupport::TestCase ordinarily uses, the old Test::Unit style of testing -- even if it's actually the minitest library providing it. minitest-rails makes it support the newer Minitest::Spec::DSL style.
minitest-rails is already a dependency of minitest-rails-capybara which you are using and have added to the test group.
So regardless of whether you explicitly add minitest-rails to the Gemfile or not, it will be installed for your application. However, you might wish to explicitly specify a specific version of minitest-rails that you want to use, and in such case you should add the gem to your Gemfile with the wanted version (something you are not doing in your code).
If you have no interest in using Minitest's spec DSL then you don't need to include minitest-rails. If you have no interest in Capybara's spec DSL then you don't need to include minitest-rails-capybara, although if you want to use Capybara you will need some other mechanism to add it to your application. The minitest-capybara gem doesn't do any rails integration.
It is possible that these two libraries are added to add the Capybara support even though you use test style tests and not spec style tests. The minitest-rails-capybara gem adds generators for Capybara tests in both test style and spec style. Try git blame on your Gemfile to find the commit where those two lines were added, as the commit message might explain why they are in the application.
It's easy to create a new Rails application using "rails new myapp" (or start with a template from Rails Wizard or the RailsApps project).
But after that, what do you do? What gems do you always add? What decisions do you make before beginning development? What important items are often overlooked before deploying an app?
I'd like to put together a reference checklist to share. Any suggestions?
For example:
Create a new RVM gemset
Modify the .gitignore file
Switch from TestUnit to RSpec
Set up Guard to run tests in the background during development
Add the viewport metatag to the default application layout
Don't forget to create a sitemap.xml file
Add a Google Analytics snippet
What else?
Starting with a Rails template.
You should look theses resources :
http://railswizard.org/
https://github.com/RailsApps/rails3-application-templates
http://railsapps.github.com/rails-application-templates.html
https://github.com/quickleft/prologue
For me usual process involves:
Add CSS framework (grids, text, forms)
Add Cells
Add Slim (www.slim-lang.com)
Remove Test::Unit for RSpec
Add application config settings (config.yml)
Add Cucumber
Add FactoryGirl
Add Spork
Add Guard (guard-rspec, guard-cucumber, guard-sass, guard-livereload, guard-spork)
Add Git, Github space, + amend .gitignore
Add Heroku (stage + production) spaces
I'll usually copy over my google_analytics helpers and sitemap_controller from other projects during the development process instead of being organised enough to do it from the start. I like to the the testing and deployment options setup from the get go so I can start developing and releasing early and often.
Dave
create rvm gemset, create .rvmrc, modify .gitignore
Then add gems
gem 'pg'
gem 'thin'
gem 'ruby-debug19', :require => 'ruby-debug'
gem 'rspec-rails'
gem 'factory_girl_rails'
gem 'capybara'
then depending on the project, I often use aws3, paperclip, resque, will_paginate and haml (although I try not to use it on new projects anymore)
Most of the time:
Configuration
add .rvmrc
amberbit-config gem (avaible at GH)
modify .gitignore
Views
haml to sass/coffee stack
rdiscount
Tests
rspec instead of unit tests
capybara, factory_gril, spork, timecop
Development
guard-livereload, with guard, libnotify etc.
active_reload for faster development with assets pipeline
annotate if relational db
pry
I almost forgot to mention: mix of html5 boilerplate for rails with twitter bootstrap it's good combo.
The first think that I do is head to http://railswizard.org/ and create a template, before "rails new app".
I always want to set up Factory Girl under /fixtures, and setup
Cucumber along Rspec. Sometimes I use shoulda too.
Initialize the project as a git repository and link it to
github. Set up the app to use PostgreSQL instead of SQLite.
And last I can think of is that I often make an entry, from the
beginning, to load .rb files form /lib automatically.
I don't add anything. Things get added if project requires them.
I don't load up CSS framework just because there's a need for two columns and a rounded button somewhere.
I don't load FactoryGirl because rails test fixtures actually do a fine job as long as you know how to use them. (Hint: you don't need 100 instances of User in your fixtures)
I don't load RSpec/Cucumber/etc because UnitTest is just as good and I prefer keeping things simple.
There's absolutely no reason to bloat project with things just because you "might need it"
I got tired of having to remember and repeat the mundane tasks required for every new app.
If you're looking for guidance on getting started, we've recently (yesterday!) released a tool to speed up the process, with all sorts of tried and tested libraries for the various aspects of a Rails web app, as well as cleanup scripts to get the fresh app just the way it should be.
Check out http://drone.bz to build an app the same way we do. Under the hood, it uses the app_drone gem to resolve dependencies and build the actual template, but the UI is probably all you need to get started.
There are several similar tools out there, but I decided to be highly opinionated in my recipe choices, and the end result is a solid foundation on which to start developing :)
P.S. Even if you don't use the drones, you can take a look at the steps that are common enough in Rails dev to be automated.
I'm currently working on a couple of different gems both of which mainly consist of rails view helpers.
My problem is that some of these helpers require rendered rails templates to test the output - but I am unsure of the best way to stub a template, without a rails application. I presume that I should be able to leverage rspec-rails in some capacity, but i've been having trouble getting that to work without a rails app present.
Am I approaching this the wrong way? What's the current best-practice to test rails-specific features (in particular - things that happen only in the view) during gem development?
I use the excellent enginex gem, which helps you in setting up a gem skeleton with an embedded rails application for testing. This way you can easily test any rails dependency inside that application. To generate rspec tests run it as follows (default is test-unit):
enginex -t rspec your-gem-name
What I did to incorporate this into my gem, was run this inside some test folder, and copied the necessary files over to my gem. As an example, you could check it out inside my cocoon gem.
Hope this helps.
If a gem has rails dependencies, do you think it is better to write the gem tests in a way they can be run standalone or run them under a rails project?
A gem should be a piece of code which acts stand-alone. Otherwise it is part of the application, so the tests should be created stand-alone as well. In this way others (hypothetically) can perform the tests as well. If the tests depend on your application others cannot test your gem.
Furthermore when you want to test your gem it should not fail because your application is failing. After your gem passed the test, you can test the application knowing that your gem is functioning well (assuming that you tested everything).
Whether the gem is depending on Rails or not is not an issue, since Rails also has been tested (and you can assume it is working properly). So these dependencies do not (/should) influence your gem.
I'd say it depends on the kind of dependencies the gem needs. Eg. if it's just the ActiveRecord it's quite easy to include it into your test suite. In more complex cases you can always mock some of the needed functionality. In a really complex cases, creating a test app is better than nothing (IMO).