Rspec framework without cucumber and step definitions - ruby-on-rails

There is need to build a rspec framework where in we don't want to write feature files and respective step definitions, to run our tests.
So far this is what I have tried this is test run, if it works I will write more.
my_example_spec.rb
require 'rspec'
describe 'Mybehaviour' do
def testMethod
visit(LoginPage).test
end
end
login_page.rb
class LoginPage
include PageObject
page_url("#{FigNewton.base_url}/login")
element :username, "input[id='username']"
element :password, "input[id='password']"
element :submit, "input[id='submit']"
def test
puts "excellent"
end
end
I am using Rubymine when I right click my example file and run it , it gives me
Run options: include {:full_description=>/Mybehaviour/}
All examples were filtered out
0 examples, 0 failures, 0 passed
Finished in 0.000315 seconds
Process finished with exit code 0
Empty test suite.
So I changed it too:
require 'rspec'
describe 'Mybehaviour' do
it 'test Method' do
visit(LoginPage).test
true.should == false
end
end
it gives me:
Run options: include {:full_description=>/Mybehaviour/}
NameError: uninitialized constant LoginPage
./my_example_spec.rb:6:in `block (2 levels) in <top (required)>'
-e:1:in `load'
-e:1:in `<main>'
1 example, 1 failure, 0 passed
Finished in 0.001273 seconds
Process finished with exit code 1
What is the difference when I was using def and when I used it?
I understand that I need to initialize LoginPage, but where and why it is calling it as constant LoginPage instead of class LoginPage.
PS:New to rspec

My guess is you need to require login_page.rb in your spec_helper.rb (if you have one), or at the top of my_example_spec.rb
The test doesn't know about the LoginPage class, and so when it hits visit(LoginPage).test on line 6 it thinks LoginPage is an undefined constant. It doesn't know that you have defined it as a class.
Try adding:
require 'login_page'
either in your spec_helper.rb or after require 'rspec' in my_example_spec.rb

Related

How to create classes in specs without polluting global namespace?

What's the best way to define a class within the context of a spec, and not have it pollute the global namespace? How does the other file even get access to that constant?
bowling_spec.rb
require "spec_helper"
describe Bowling do
context "when validate is defined" do
let(:dummy_class) {
Class.new(described_class) do
METRICS_NAMESPACE = "ExtendedClass.Metrics.namespace"
end
}
it "does nothing" do
dummy_class
end
end
end
Spec - batting_spec.rb
require "spec_helper"
describe Batting do
context do
it "does weird thing" do
expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
end
end
end
If you run the individual spec file
rspec spec/batting_spec.rb
.
Finished in 0.00285 seconds (files took 0.12198 seconds to load)
1 example, 0 failures
If you run the spec which defines the dummy class
rspec spec/bowling_spec.rb spec/batting_spec.rb
.F
Failures:
1) Batting does weird thing
Failure/Error: expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
expected NameError but nothing was raised
# ./spec/batting_spec.rb:6:in `block (3 levels) in <top (required)>'
Finished in 0.01445 seconds (files took 0.12715 seconds to load)
2 examples, 1 failure
Failed examples:
rspec ./spec/batting_spec.rb:5 # Batting does weird thing
To reproduce the error: I created a repo: https://github.com/pratik60/rspec-pollution with updated Readme
Running rspec spec/batting_spec.rb spec/bowling_spec.rb
2 examples, 0 failures
Running rspec spec/bowling_spec.rb spec/batting_spec.rb
Gives the error you mention.
Using binding.pry:
describe Batting do
context do
it "does weird thing" do
require 'pry'
binding.pry
expect { self.class.const_get(:METRICS_NAMESPACE) }.to raise_error(NameError)
end
end
end
self.class.ancestors
[RSpec::ExampleGroups::Batting::Anonymous,
RSpec::ExampleGroups::Batting::Anonymous::LetDefinitions,
RSpec::ExampleGroups::Batting::Anonymous::NamedSubjectPreventSuper,
RSpec::ExampleGroups::Batting,
RSpec::ExampleGroups::Batting::LetDefinitions,
RSpec::ExampleGroups::Batting::NamedSubjectPreventSuper,
RSpec::Core::ExampleGroup,
Going down the inheritance tree
RSpec::Core::ExampleGroup::METRICS_NAMESPACE
(pry):4: warning: toplevel constant METRICS_NAMESPACE referenced by RSpec::Core::ExampleGroup::METRICS_NAMESPACE
=> "ExtendedClass.Metrics.namespace"
Checking the first object on the chain
Object::METRICS_NAMESPACE
=>"ExtendedClass.Metrics.namespace"
Even further
Class::METRICS_NAMESPACE
(pry):2: warning: toplevel constant METRICS_NAMESPACE referenced by Class::METRICS_NAMESPACE
=> "ExtendedClass.Metrics.namespace"
TL ; DR
As you said, when you did METRICS_NAMESPACE = "ExtendedClass.Metrics.namespace", you created a global namespace constant. (That is, a constant inside the uppermost ruby constant, Class)
Simply do this instead
Class.new(described_class) do
self.const_set('METRICS_NAMESPACE', "ExtendedClass.Metrics.namespace")
end
rspec spec/bowling_spec.rb spec/batting_spec.rb
Finished in 1.55 seconds (files took 0.08012 seconds to load)
2 examples, 0 failures

Error during testing in rails

I am trying to run a unit test.
The test needs to have require_relative 'francis'
require 'minitest/autorun'
require_relative 'francis'
class FrancisTest < MiniTest::Test
When I try running rake test TEST=test/francis_test.rb I get an error of
(in C:/Users/chris2/Documents/RailsProjects/francis)
rake aborted!
LoadError: cannot load such file -- C:/Users/chris2/Documents/RailsProjects/francis/test/francis
C:/Users/chris2/Documents/RailsProjects/francis/test/francis_test.rb:2:in `require_relative'
C:/Users/chris2/Documents/RailsProjects/francis/test/francis_test.rb:2:in `<top (required)>'
Tasks: TOP => test:single
(See full trace by running task with --trace)
How can I run this test?
Update
I moved francis_test.rb to the root of the project. I also remarked out the require_relative statement., I also had to change the setup line to #teen = ::Franci.new instead of Francis.new
So the beginning of francis_test looks like
require 'minitest/autorun'
# require_relative 'franci'
require 'test_helper'
class FrancisTest < MiniTest::Test
attr_reader :teen
def setup
#teen = ::Franci.new
end
def test_stating
assert_equal 'Whatevs.', teen.yo('Oh blah di, oh blah da.')
end
def test_yelling
assert_equal 'Chill!', teen.yo('GOOOAAAALLL!')
end
I seem to need require 'test_helper'.
BTW - my ruby and rails versions are
Rails 4.2.5.1
ruby 2.2.4p230 (2015-12-16 revision 53155) [i386-mingw32]
Now if I run rake test TEST=francis_test.rb -v
I see (partial)
# Running:
FrancisTest#test_stating_with_acronyms = 0.01 s = E
FrancisTest#test_inquiring = 0.00 s = E
FrancisTest#test_question_with_just_numbers = 0.00 s = E
. . .
Finished in 0.013518s, 1257.5400 runs/s, 0.0000 assertions/s.
1) Error:
FrancisTest#test_stating_with_acronyms:
ArgumentError: wrong number of arguments (1 for 0)
2) Error:
FrancisTest#test_inquiring:
ArgumentError: wrong number of arguments (1 for 0)
A couple of questions
is attr_reader valid in Ruby 2.2.4? I looked at the API but couldn't quite make sense of it.
Why am I getting 'wrong number of arguments'? I haven't used the attr_reader but it seems that when calling it the way I am, it should be passing the argument to teen.yo.
BTW - the francis table only has one column - 'yo'.
require_relative complements the builtin method require by allowing you to load a file that is relative to the file containing the require_relative statement.
For example, if you have unit test classes in the "test" directory, and data for them under the test "test/data" directory, then you might use a line like this in a test case:
require_relative "data/customer_data_1"
is attr_reader valid in Ruby 2.2.4? I looked at the API but couldn't
quite make sense of it.
Yes, it is. However you don't need it because columns are automatically made available as attributes by ActiveRecord.
Why am I getting 'wrong number of arguments'? I haven't used the
attr_reader but it seems that when calling it the way I am, it should
be passing the argument to teen.yo.
To answer this question, I need the content of your francis.rb file.

Run basic rspec file

I'm new to Ruby and RSpec. I want to create very simple RSpec test:
# test_spec.rb
require 'spec_helper'
describe TestController do
puts(Time.now)
end
But when I run the code this way rspec test_spec.rb I get error:
`<top (required)>': uninitialized constant TestController (NameError)
Can you give me some idea where I'm wrong?
If you pass a class to describe, RSpec attempts to create an instance of that class. If the specified class does not exist, you get an error.
You can pass a string instead:
describe "my first test" do
it "does something" do
expect(1).to be_odd
end
end
Running the above:
$ rspec -fd test_spec.rb
my first test
does something
Finished in 0.00178 seconds (files took 0.10381 seconds to load)
1 example, 0 failures
This error is because after the describe you need a string with the description and you are leaving it without quotes.
describe '3pController' do
puts(Time.now)
end
But the tests should be structured as follows
a (describe) can have many (it) inside (a (it) is where the tests are)
one (decribe) can have more (describe) inside or can have (context), that these at the same time has many (it).
inside this link I will leave the documentation Basic structure
Here you can see a basic example of a test
describe 'sum 2 + 2 equal 4' do
   it { expect(2 + 2).to eq(4)}
end

FactoryGirls randomly fails with 'Factory not registered', why?

I've some tests that randomly fail, approx. 20% of times. It means that WITHOUT changing the code, each time that I run the tests 1 time out of 5 will fail with "Factory not registered" error. It's very weird.. :(
This is the consone output:
Failures:
1) Unit#new_from_string returns factor for metric conversions
Failure/Error: FactoryGirl.create :taza
ArgumentError:
Factory not registered: taza
# ./spec/models/unit_spec.rb:29:in `block (2 levels) in <top (required)>'
Finished in 0.29619 seconds
4 examples, 1 failure
Failed examples:
rspec ./spec/models/unit_spec.rb:22 # Unit#new_from_string returns factor for metric conversions
Randomized with seed 61727
And this is the code:
file: "unit_spec.rb"
require 'spec_helper'
describe Unit, "#new_from_string" do
it "parses the string and returns a Unit object" do
[some tests...]
FactoryGirl.find_definitions
u = FactoryGirl.create :taza
FactoryGirl.create :tbsp
[tests...]
end
it "returns factor for metric conversions" do
[tests not involving factory girl...]
# the following is line 29, that fails
FactoryGirl.create :taza
[tests...]
end
end
file "spec/factories/units.rb":
FactoryGirl.define do
factory :taza , :class => CustomUnit do
singular 'taza'
plural 'tazas'
physical_type Unit::VOLUME
equivalence_factor 200
equivalence_unit 'ml'
end
[other factories...]
end
I think the problem is on this line
FactoryGirl.find_definitions
Actually there is no need for this line when your factories are in correct directories(I see it is), and you put gem factory_girl_rails in Gemfile.
I think, 20% of time, the second test get run at first. At this time, there is no definition of Factory and the test failed. The other test has such definition and get passed. In other time, the first test run first so definition exists.
My suggestion:
Make sure you have factory_girl_rails, not factory_girl in Gemfile.
Remove that line of definition.
[optional but recommended] Put all definition in a single file spec/factories and remove all other factory files, if you don't have too much factories. This would be easier to manage.

RSpec fails for no obvious reason

So I'm using rspec to test my code as I'm going through the Rails Tutorial, and I keep getting this error when I test the code in listing 3.20. Everything checks out when I look at it with my eyeball, but RSpec doesn't seem to like it.
(Note that I just did one of the pages, not all three because they all give the same error)
james#tristan:~/rails_projects/sample_app$
rspec
spec/controllers/pages_controller_spec.rb
F...
Failures:
1) PagesController should have the
right title
Failure/Error: response.should have_selector("title",
expected following output to contain a | Home tag:
# ./spec/controllers/pages_controller_spec.rb:13:in
`block (2 levels) in '
Finished in 0.97999 seconds 4
examples, 1 failure
james#tristan:~/rails_projects/sample_app$
At the top of that spec file it says:
before(:each) do
#
# Define #base_title here.
#
end
Does your spec assign a value to #base_title?

Resources