@h6165
Manual Tests
Semi automated tests
The developer
Testers/QA should write tests is an outdated idea, not practiced in Ruby world
When to start testing
As early as possible
When to absolutely start testing
When the following signs show-up:
Regressions
Implementation slowness
Poor quality in general
Developer stress
Test first, then code
Rails comes with a test environment.
The idea is: the database should be separate
And some settings/config/gems should also be separate
Test scripts are programs written as part of the same code base
The scripts are executed using a test runner
Test scripts contain a bunch of test-cases
Every test-case undergoes a setup and a teardown phase
Data creation/setup needed for the test-case happens in the setup-phase
Teardown is for cleanup, deletes all data created by the test
(Ideally) each test-case runs in complete isolation, and should not be dependent on any other tests
Rails ships with the MiniTest test framework. RSpec is a popular alternative
All Rails project get MiniTest by default, and can be replaced with RSpec
The default data creation technique in Rails is fixtures, while the popular one is factories.
The difference has been a subject of much debate
We will cover RSpec for this workshop. Switching between the two is not very difficult after knowing the fundamentals
There is also a debate over whether TDD is the correct way to approach software development
Rails creator David H Hansen has written articles opposing, and there have been several in-depth arguments from both sides
It is worth looking into the entire discussion before arriving at a decision
## Code under test:
def add(a, b)
a + b
end
## The test
RSpec.describe 'add' do ## mention what is being tested
it 'should give 5 for 2 and 3' do ## The test case
c = add(2, 3) ## Invoke the code
expect(c).to eq(5) ## Verify the result
end
end
it:
Holds the test case
expect..to..eq
The assertion statement. Does the verification
describe
Wraps the test cases, and declares what is being tested
## Tautology
require 'rspec'
RSpec.describe 'the truth' do
it 'should be true' do
expect(true).to eq(true)
end
it 'should not be false' do
expect(true).to_not eq(false)
end
end
## rspec sample1.rb
## Addition
def add(a, b)
a + b
end
## The test
require 'rspec'
RSpec.describe 'add' do
it 'should give 5 for 2 and 3' do
c = add(2, 3)
expect(c).to eq(5)
end
end
## rspec sample2.rb
## prime_number.rb
class PrimeNumber
def self.is_it?(num)
(2...num).each { |x| return false if num % x == 0 }
true
end
end
## prime_number_spec.rb
require 'rspec'
require File.expand_path('../prime_number.rb', __FILE__)
RSpec.describe 'PrimeNumber' do
describe 'is_it?' do
it 'should be true for 5' do
expect(PrimeNumber.is_it?(5)).to eq(true)
end
it 'should be false for 77' do
expect(PrimeNumber.is_it?(77)).to eq(true)
end
end
end