OK, I don't usually ask questions because I don't like looking like an idiot, however, at this point I no longer care. This is driving me insane!
I have a repo here at:
https://github.com/pgpkeys/journal_app/tree/feature/model_rspecs_modification
My gist of the issue is at: https://gist.github.com/977300
I have a factory created (using factory_girl) which exists in [Dir[Rails.root] + "/factories/*.rb. My spec/support/factories.rb loads this factory. However when I run bundle exec rake spec I'm getting constant errors with show,edit,update, and delete that ActiveRecord::RecordNotFound: Couldn't find Owner without an ID. I have let(:owner)
{ Factory(:owner) } in my spec/controllers/owners_controller_spec.rb file . It also requires spec_helper.rb (even though its already done by rake spec) which points to the spec/support/*.rb which is supposed to load factories/*.rb.
The problem might be because of 'database_cleaner' gem which wipes the database every time tests run. Because of this, the database could be empty?
Related
So I've been messing with this for the last hour and a half or so and just can not figure out how to do this.
In my Ruby test.rake file, which gets called from another project after a Snapshot Gem is created, I need to check to see if a dependency for Capybara exists in the Rakefile for the other project, since we have since deprecated Capybara and are replacing it with something else.
So, I included a simple check to see if the project contains Feature/Capybara tests, and if so, to scan through each spec test and see if it has dependency for Capybara in it, and if so log a warning to tell the user that Capybara has been deprecated.
My problem is, I can not get this to work at all. When I attach this to a Jenkins job and run it, I keep getting the unexpected Print statement in the else clause.
Am I missing something here? From what I understand, my code is doing the following things:
Checking if the spec/features directory exists
Using glob to select all of the files in the directory that end with .rb (Spec tests), with each file instance being assigned to file
Take the current instance of file, read each line of it, and use grep to find any instances of the word "capybara" in them, and print out the right message if found.
Else, if the word is NOT found, print the error message in the else clause.
I'm somewhat new to Ruby so I feel like maybe I am missing something with the syntax, but other than that I'm stumped! Any help would be greatly appreciated! Here is what the code and the Rakefile I am trying to parse through look like:
test.rake:
if Dir.exist?('spec/features')
path = 'spec/features/'
Dir.glob(path + '*.rb') {|file|
if File.readlines(file).grep(/capybara/).any?
print "The capybara dependency has been found!"
else
print "SOMETHING WENT WRONG"
end
}
end
Rakefile:
#!/usr/bin/env rake
# frozen_string_literal: true
require 'roll_out/rake_tasks'
require 'roll_out/security'
require 'roll_out/jira'
require 'REDACTED/philter/lint_results'
require 'roll_out/capybara'
load 'REDACTED/tasks/REDACTED.rake'
Your code looks almost good except .each missing
i did my test and it works fine.
Dir.glob('spec/features/*.rb').each do |f|
puts 'haha' if File.readlines(f).any?{|line| line.include?('capybara')}
end
I'm doing an Rspec feature to test some user story and I'm getting the error message:
Internal Server Error uninitialized constant Tree::MY_BRAnCH
Now, I know the test fails because the table "trees" doesn't have the proper rows but only fails when I run the suite test.
RAILS_ENV=test bundle exec rspec spec/
pointing to the articles_spec.rb file as responsible. But if I run just the feature file:
RAILS_ENV=test bundle exec rspec spec/features/articles_spec.rb
the test pass fine. Digging in the code I see other developer made a test with the indication:
before { truncate(Tree) }
So that test is executed first and is removing the data in the table.
My question is: how can avoid this? Need I to reload all the database before each rspec file?
or what policy should we follow to be sure the rspec tests are not affecting other developers?
It seems unlikely that truncating a database table would cause an uninitialized constant error. More likely, articles_spec.rb causes Tree::MY_BRAnCH to be defined. That's why running articles_spec.rb alone passes. When you run the whole spec suite, something tries to use the constant before it has been defined, hence uninitialized constant.
One solution could be to search your codebase for usages of Tree::MY_BRAnCH and make sure that it has been defined before it is used. You may need to learn about one or more of the following code loading techniques:
Kernel#require
Kernel#autoload
ActiveSupport::Autoload
I'm struggling with this for quite a while now: I'm trying to upgrade an app from Rails 3.2 to Rails 4. While on Rails 3.2 all specs are passing, they fail under certain conditions in Rails 4.
Some specs are passing in isolation while failing when run together with other specs.
Example Video
https://www.wingolf.org/ak-internet-files/Spec_Behaviour.mp4 (4 mins)
This example video shows:
Running 3 specs using :focus–––green.
Running them together with another spec–––two specs passing before now fail.
Running the 3 specs, but inserting two empty lines–––one spec fails.
Undo does not help when using guard.
focus/unfocus does not help.
Restarting guard does not help.
Running all specs and then running the 3 specs again does help and make them green again. But adding the other task makes two specs fail, again.
As one can see, some specs are red when run together with other specs. Even entering blank lines can make a difference.
More Observations
For some specs, passing or failing occurs randomly when run several times.
The behavior is not specific to one development machine but can be reproduced on travis.
To delete the database completely between the specs using database_cleaner does not help.
To Rails.cache.clear between the specs does not help.
Wrapping each spec in an ActiveRecord::Base.transaction does not help.
This does occur in Rails 4.0.0 as well as in Rails 4.1.1.
Using this minimal spec_helper.rb without spring or anything does not help.
Using guard vs. using bundle exec rspec some_spec.rb:123 directly doesn't make a difference.
This behavior goes for model specs, thus doesn't have to do anything with parallel database connections for features specs.
I've already tried to keep as many gems at the same version as in the (green) Rails-3.2 branch, including guard, rspec, factory_girl, etc.–––does not help.
Update: Observations Based on Comments & Answers
Thanks to engineerDave, I've inserted require 'pry'; binding.pry; into one of the concerning specs. Using the cd and show-source of pry, it was ingeniously easy and fun to narrow down the problem: Apparently, this has_many :through relation does not return objects when run together with other specs, even when called with (true).
has_many(:groups,
-> { where('dag_links.descendant_type' => 'User').uniq },
through: :memberships,
source: :ancestor, source_type: 'Group'
)
If I call groups directly, I get an empty result. But if I go through the memberships, the correct groups are returned:
#user.groups # => []
#user.groups(true) # => []
#user.memberships.collect { |m| m.group } # returns the correct groups
Has Rails changed the has many through behavior in Rails 4 in a way that could be responsible? (Remember: The spec works in isolation.)
Any help, insights and experiences are appreciated. Thanks very much in advance!
Code
Current master branch on Rails 3.2––all green.
Rails-4 branch––strange behavior.
The file/commit seen in the video––strange behavior.
All specs passing on travis for Rails 3.2.
Diff of the Gemfile.lock (or use git diff master..sf/rails4-minimal-update Gemfile.lock |grep rspec)
How to Reproduce
This is how one can check if the issue still exists:
Preparation
git clone git#github.com:fiedl/wingolfsplattform.git
cd wingolfsplattform
git checkout sf/rails4-minimal-update
bundle install
# please create `config/database.yml` to your needs.
bundle exec rake db:create db:migrate db:test:prepare
Run the specs
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb
bundle exec rspec ./vendor/engines/your_platform/spec/models/user_group_membership_spec.rb:213
The problem still exists, if the spec :213 is green in the second call but is red when run together with the other specs in the first call.
Based on that you're using:
the should syntax
that you indicate you've upgraded recently (perhaps a bundle update?)
that your failure messages indicate a NilObject error.
Is something like this perhaps what is causing it?
https://stackoverflow.com/a/16427072/793330
Are you are calling an object in your test which hasn't been instantiated yet?
I think this might be an rspec 3 upgrade issue where should is deprecated.
Have you ruled out an rspec gem upgrade to the new rspec 3 syntax (2.99 or 3.0.0+) as the culprit?
"Remove support for deprecated expect(...).should. (Myron Marston)"
IMO this behavior would not be caused by a Rails 4 update as its centered around your test suite.
Update (with pry debug):
Also you could use the pry gem to get a window into what is going on in your specs.
Essentially you can put a big "stop" sign (similar to a debug break) right before the spec executes to get a handle on the environment at that point.
it {
require 'pry'; binding.pry
should == something
}
Although beaware sometimes these pry calls wreck havoc on guard's threading and you have to kill it with CTRL+Z and then kill -9 PID that shows.
Update #2: Looking at updated answer.
You might be running up against FactoryGirl issues based on your has_many issue
You may need to trigger a before action in your Factory to pre-populate the associated record. Although this could get messy, i.e. here be monsters, you can trigger after and before callbacks in your factory that will bring these objects into being.
after(:create) do |instance|
do stuff here
end
I have some weird issues going on (for a very weird use case as I'll explain). I'm setting up a multi-tenant application using postgres schemas for data multi-tenancy.
Each company in my system will get its own schema. The way I accomplish this is with an after_commit on the model, on create, that then goes and creates a new postgres schema, and loads schema.rb into it. (copied from rake db:schema:load code) using ruby load.
You can see the gem here
Anyway, all this works (in the console). Creating a company creates the new schema and i can switch to it etc... my problem lies in my integration tests. I have an rspec test that creates to companies like so:
before do
#c1 = Factory :company
#c2 = Factory :company
end
What's odd is that I start to get the logs about the db schema loading, but they're truncated. Almost as if they're happening in parallel. Here's a sample output:
>> create: database: unique_name1
-- create_table("first_table_in_schema_rb", {:force=>true})
>> create: database: unique_name2
create: database is my log line, the -- create_table is from schema.rb itself.
As you can see, the second create: database seems to happen while I'm loading schema.rb from the first company creation.
Does anyone know if load is somehow asynchronous? I know ruby doesn't have real threads, but could it be using fibres or something? This is really messing me up because when my test comes around, the postgres schema that was meant to be created doesn't seem to exist.
Rails 3.0.8
Ruby 1.9.2
Im not 100% sure this is your problem because im sure of what happens with require but not with load, the things this happen to me once with require because require is not atomic, so loading code from a file with require will cause a race condition. Maybe that is what is happening with load but i was not able to find any info about load been atomic or not.
nevermind... issue had nothing to do with load it was the fact that i was already connected to the wrong schema when importing the schema.rb
There was in fact an exception being thrown that was silently caught somewhere
Today, I use the factory_girl instead of the rails fixtures, but i get a problem:
After I run the command "spec spec" done, the data resets to the fixtures, who can tell me the answer?
thank you!
If you intend to use both factories and fixtures in your project and not running them through the rake tasks: eg rake spec, you will need to make sure that you are doing removal of the values from the db by hand. its likely what you are doing is just grabbing an old record in the database and you think the data is being reset. You can verify this by using puts inside your spec to trace the number of records in the db.
puts MyRecord.count
You can clear values in an after or before block.
before(:each) do
Factory(:my_model)
end
after(:each) do
MyModel.delete_all
end
if you intend to use this model or factory in other spec files, you can add these to global before and after blocks in the spec helper.