Annoying Guard notification when testing - ruby

Recently I made a simple ruby application and have been using minitest to test it.
Following the advice of the Head First Ruby book, I automated this testing using Rake(I'll write what it told me to put in the Rakefile at the end of this post, in case that helps). The test seems to run fine (everything passes in a way I would expect it to), but I always get this notification at the end of it all:
rvm/gems/ruby-2.3.0/gems/guard-2.14.0/lib/guard/notifier.rb:28: warning: instance variable #notifier not initialized
Testing things manually by telling ruby to include which files I want, does not have this issue, only when I use "rake test" to test things.
As far as I can tell, this is related to when I set up Guard when I was following Michael Hartl's Rails Tutorial, at the end of chapter 3. I followed the directions for setting that up (correctly, as far as I can tell), and this was all in a completely different folder(ultimately my ruby and rails projects do have the same parent folder that they sit in, but are themselves in completely separate ruby_projects and rails_projects folders). If possible, I would like to stop this notification on my ruby application that I am testing. Is there a good way to do this?
Contents of the Rakefile I am using, if that helps:
require "rake/testtask"
Rake::TestTask.new(:test) do |t|
t.libs << "lib"
t.test_files=FileList['test/**/test_*.rb']
end
My test file requires minitest/autorun, and the file for the application that I am testing, then has the normal tests

Seems like there's some weird conflict...
The reason is that Guard::Notifier.connect isn't connected. Normally, when you run guard, Guard.setup is called which does this.
If you're not using guard (e.g. interactively), then calling the following from your Rakefile should work around the problem:
Guard::Notifier.connect(notify: false, silent: true)
Guard::Notifier.disconnect
This will initialize the variable.
For a faster response, always report such issues on the project page on Github. If you can share the project where this occurs, maybe a better fix is possible. (It's best to provide a repository, since it really speeds up fixing things and often errors like this are very hard to simulate without the exact code).

Related

How to make Cucumber/Capybara close or quit the browser session after test execution is complete?

I am having some issues in Jenkins. After test execution completes, the browser session is still alive, which is creating some other issue in the pipeline. So I want to quit the browser session after execution completed in my Test Suite. I am using Cucumber>Capybara>SitePrism>Ruby.
How I can do that? I want something like below which will execute after very end of my test suite:
RSpec.configure do |config|
config.after(:suite) do
puts 'Destroy Driver'
end
end
You could try
Capybara.send(:session_pool).each { |name, ses| ses.driver.quit }
which should call quit on every instance of Selenium::Webdriver, however that is accessing the private method sesion_pool, and really those instances should just automatically get cleaned up when capybara exits unless you're doing something strange with sessions (or maybe there's a bug in selenium when used with phantomjs).
This answer is for folks coming here from their internet searches.
Use the quit instance method defined by Capybara::Session.
I found two ways to hit this:
If you're using Capybara::DSL directly (e.g. in a plain ruby script like I am), current_scope.session.quit does the trick.
Or, Capybara.current_session.quit is probably what you need in an RSpec hook since the Capybara::Session methods won't be mixed in there.
Note: The original question seems a bit like an XY problem. I've never had to manually close Capybara sessions after tests and it makes me think there's some other configuration error or other problem getting in the way. Considering the OP is 5 years old however, this is a moot point, although I figured I'd mention it for completeness' sake.
Try doing - Capybara.reset_sessions!
http://www.rubydoc.info/github/jnicklas/capybara/Capybara.reset_sessions!

Launch sinatra from a test/spec or another ruby script

I'm experimenting, and I'm trying to launch dummy Sinatra application from RSpec and kill it when the spec is finished. Something like:
# spec/some_spec.rb
before(:all)
# launch sinatra dummy app
end
after (:all)
# kill sinatra dummy app
end
it 'should return list of whatever' do
expect(JSON.parse(make_request('0.0.0.0:4567/test.json')))
.to include('whatever')
end
I could use system("ruby test/dummy/dummy_app.rb"), but how can I kill that process only? Does anyone know how I can launch the Sinatra inside a test (or from another ruby script)? I know about WebMocks, but I want to see if I can manage to make my test work this way.
Look under RSpec on "Testing Sinatra with Rack::Test". I'd suggest you use that code as boilerplate to get started.
Just add this to your describe block:
def app
Sinatra::Application
end
I would suggest you read up RSpec.
Since you want to test an external system, by the looks of your comment, instead of system "curl whatewer.com", you can use Net::HTTP to make requests and then test against the response.
Have a look at "Testing an external API using RSpec's request specs".
As I'm writing request specs to ensure the features won't be broken I decided to rather write separate Cucumber features. The nice thing is that I can use Capybara, and thanks to Selenium Web Drive, I can launch a server before I run my tests.
So, I created a dummy Sinatra application (that will represent the external service to which the actual code I'm testing is doing requests (including a nasty system('curl whatever.com')).
All I have to do is stub out the methods passed to curl to use Capybara.current_session.server.host and Capybara.current_session.server.port.
Once I'm done with my re-factoring all I have to do is remove the Capybara server variables, and Selenium web drive from the cucumber/capybara configuration.
Tests after a brief change will be still working and will be valid.
Update
In the end I wrote it all with RSpec request tests, as doing it in Cucumber was little bit time consuming and I already spend too much time on this.
I mark these kind of request tests with RSpec tag and Before I lunch these I manually lunch simple Sinatra/Grape dummy API application to which the request are made. (Then I run RSpec tests with this tag)
So basically I end up with specs for functionality that uses net/http that uses WebMock and don't need a server, and request tests for which I need to run the server before I run the specs. So the original question remains, how to lunch a server before tests start
After I cover all the functionality I'm gonig to rewrite the curl to net/http however I'm going to keep those requests specs as I discovered they are nice idea when it comes to crazy API scenarios (like testing https + diggested authentication)

Test a Sinatra app with RSpec - "structure" of tests

I have a Sinatra app with the following structure:
controllers
helpers
models
views
public
I will be using RSpec for testing it. For me, there are two variants of tests - to test with Rack::Test::Methods - to check responses, the content of body and so on, and the second - to test the "core" logic - for example if the method "find_most_expensive" really returns the item with maximum price, to check if a new product is really created and that kind of things.
What I'm wondering is how to organise this tests in the spec folder? Should I have only name_of_controller_spec.rb files and both kind of tests go there? Or should they be separate? And how? To sum up, I have never written tests and I don'y know how exactly and where to put them :( Any kind of advise would be appreciated! :)
You could make just three folders: controllers (with, for example, posts_spec.rb), models (that contains post_spec.rb where testing the methods you have implemented in your model) and helpers (let's say utils_spec.rb).
Take a look at Testing Sinatra with Rack::Test and some repositories on GitHub to have a better idea on how you should organize your code.
https://pragprog.com/book/7web/seven-web-frameworks-in-seven-weeks
The source code is free and it has a chapter on Sinatra tests.
I know, I just ran them as I updated the expect instead of should deprecation warnings.
Only they use shell scripts to test with but you may already be familiar with what you want to use. The point is notice just different names for the folders and not the tests? Maybe could work for you. I like the answer first posted. These can both relate perhaps.
Something I had noticed with Rubocop is to keep your test methods in as little as 25 lines or they fail there. So I would say keep them broken down into small groups.
Ruby koans has tests that you could look at too.

Controlling Rails Initialization for an app extracted as an engine

I was hoping to make a Rails app usable both as an Engine and as a standalone Application.
Specifically, I have a nascent app which I'd like to plug in to a customer's site, but ideally, I'd like to just as easily use the app as a standalone system. However, if config/environments/*.rb exist in the enginified version of my app, I get an Uninitialized Constant error at the time the app that I'm having take a dependency on my engine starts up; Rails complains that the MyEngineModule::Application constant can't be found in development.rb, which I think is simply a load order issue, since this does NOT occur when I run the app standalone. If I delete development.rb, the original initializers that reference my MyEngineModule::Application complain, so then I tried to delete those, and all is well.
Great, except that the original app doesn't work, since its configuration is gone.
Is there some tweak I can make to the initialization load order (or load paths, in the Engine < Rails::Engine class definition) that would prevent the original configs and initializers from being loaded when in an engine context, and allow me to leave them in place for the app context?
The simpler answer is probably this, but I'm feeling stubborn, and would like to know what it would take to make my original goal possible:
extract the code for MyEngine into an engine, remove the config/environments/* files and config/initializers/* files, and make the client app depend on this.
Make a "new" minimalist app depend on MyEngine, and move the environment files and initializers to NewApp.
Assuming I feel some unnatural compulsion to keep my original application runnable as it was, if I want to prevent the "engine" from loading the "application" configuration, what's the best way to handle that? I presume this is only really a problem during development, because I can prevent the environments/*.rb files from being pulled into the gem itself, but I like being able to test locally while I'm developing the engine and its client app.
Continuing my tradition of answering my own esoteric questions, it seems like one passable alternative is to include a guard clause in the engine's environments/*.rb and the initializers that goes something like this:
if defined? CuteEngine::Application
CuteEngine::Application.configure do
config.whatever = something
end
end
This gets around the problem of having two Rails::Application objects at a relatively small cost. Not very happy about it, but I'll live.
Bumping this for new comers.
Rails 3.1 comes with mountable engines, which sounds like exactly what you are describing. The docs aren't great for converting existing code, but it looks like this will do what you want:
module CuteEngine
class Engine < ::Rails::Engine
isolate_namespace CuteEngine
end
end
In your other app's routes.rb file, you'll add:
mount CuteEngine::Engine, at: "/cuteness"
http://edgeguides.rubyonrails.org/engines.html#mounting-the-engine
http://railscasts.com/episodes/277-mountable-engines

A copy of ApplicationController has been removed from the module tree but is still active

Whenever two concurrent HTTP requests go to my Rails app, the second always returns the following error:
A copy of ApplicationController has been removed from the module tree but is still active!
From there it gives an unhelpful stack trace to the effect of "we went through the standard server stuff, ran your first before_filter on ApplicationController (and I checked; it's just whichever filter runs first)", then offers the following:
/home/matchu/rails/torch/vendor/rails/activesupport/lib/active_support/dependencies.rb:414:in
`load_missing_constant'
/home/matchu/rails/torch/vendor/rails/activesupport/lib/active_support/dependencies.rb:96:in
`const_missing'
which I'm assuming is a generic response and doesn't really say much.
Google seems to tell me that people developing Rails Engines will encounter this, but I don't do that. All I've done is upgrade my Rails app from 2.2 (2.1?) to 2.3.
What are some possible causes for this error, and how can I go about tracking down what's really going on? I know this question is vague, so would any other information be helpful?
More importantly: I tried doing a test run in a "production" environment just now, and the error doesn't seem to persist. Does this only affect development, then, and need I not worry too much?
This is a bug in Rails 2.3.3:
https://rails.lighthouseapp.com/projects/8994/tickets/2948-exception-a-copy-of-actorscontroller-has-been-removed-from-the-module-tree-but-is-still-active
There is a patch for it (but incomplete?) in 2-3-stable:
http://github.com/rails/rails/commit/d37ac7958fc88fdbf37a8948102f6b4e45c530b3
You have a few options to address the problem:
Revert to Rails 2.3.2, wait for 2.3.4 to come out, probably at the end of August. 2.3.3 has a couple bad issues, so that might be best.
The problem should not happen in production mode, nor will it happen in development mode under the Thin server. If you are having this issue on Google Engines in production mode, the patch is your only hope. If it's only in dev mode, you can just run your local server with Thin instead of Mongrel.
If it is Google Engines, you can move off of Google Engines and host your app another way. This seems like a lot of work though.
Best of luck, this is a really bad bug many people are running into.
I addition to the workarounds mentioned in the other answers, I have encountered two others:
Add "config.cache_classes = false" to your config/environments/development.rb file. This has the unfortunate side effect of requiring you to restart your server whenever you want to see your changes.
Add 'unloadable' inside your controller classes in your engine. See http://strd6.com/?p=250 and http://dev.rubyonrails.org/ticket/6001
I haven't tried the second approach, since I found the other solution first, but there is of course a trade-off between avoiding having to edit plugin code, which may be reverted if a newer version of the plugin is downloaded, and then the ease of development provided by not having to restart the development server all the time in the second solution.
i faced with same problem for my new engine on rails 2.3.4 and i found solution here.
calling unloadable method solved my problem.
Weird.
Trying running "rake rails:update" to make sure the configs are scripts are up to date. You may have to check the existing ones against a template application.
i had this error and from memory it was one of one of these three things that fixed it.
1) I needed to update mongrel/rack
2) I had an environment variable from restful authentication that i had moved into the production.rb and development.rb files from the environment.rb - shifting it back to environment.rb seemed to help
3) will_paginate was out of date
We called out to an activerecord model in a namespaced module which overrides the "name" class method. Rails expects that the name method returns Product::Categories::MilkProducts::Firstproduct but gets just Firstproduct and throws an error. So if you get this error first check if you redefined self.name.
Firstproduct.method(:name).owner should be Module
Firstproduct.method(:name).source_location
source:
module Product::Categories::MilkProducts
class Base
def self.name
self.to_s.demodulize
end
end
class Firstproduct < Base
self.product = Product.first
end
end

Resources