Automated Testing (theory and examples)

0 Shares
0
0
0

This is an overdue post that I wrote during my programming school:

Automated testing can be viewed as a trade-off between budget, time and quality.The effort invested in automated tests should result in at least an equivalent improvement in software quality.

There are Test Driven Development and Behaviour Driven Development type of testing.

Test Driven Development (TDD)

TDD is a set of tests that drive the development and make sure that NO CODE goes into production without associated tests.

TDD rules:

  1. You may not write production code until you have written a failing unit test
  2. You may not write more of a unit test than is sufficient to fail, and not compliling is failing
  3. You may not write more production code than is sufficient to pass the current failing test

The TDD Cycle (the Red, Green, Refactor cycle):

  1. We first write a failing test, represented in many testing tools by the color red.
  2. We then implement code to get the test to pass, represented by the color green.
  3. If necessary, we refactor the code, changing its form without changing its function.

Behaviour-Driven Development (BDD)

  • BDD is based on TDD
  • BDD is speficying how your application should work, rather than verifying that it works
  • Its about implementing an application by describing its behavior from the perspective of its customer’s point of view

TDD vs BDD:

The difference is that one is called Behaviour Driven Development – and some people find that wording useful – and one (or two) is called (Acceptance) Test Driven Development – and some people find that wording useful in a different way.

  • Difference in language example:

    1. In TDD: assertEquals(count,5)
    2. In BDD: $(count).should_be(5)
  • Explaining differences between TDD vs BDD using the Sorting algoritm where using different types of algorithms to sort:

  1. TDD: The unit test will change for each algorithm because you want to know as you doing the sort, its doing it correctly

  2. BBD: its one set of test you need for all of these sorting algorithms

Testing for Rails:

There is a wide variety of different approaches and aids for testing in rails. Based on my research, here I am listing some of the most used testing tools by the rails community:

  • Test::Unit: Rails by default provides unit, functional and integration tests but its not the only way to test rails applications.

  • NullDB: A way to speed up testing by avoiding database use

  • Machinist: Blueprints to generate Active Record objects

      Hole.blueprint do 
        number 1
      end
    
      (1..18).each {|n| Hole.make(:number =>n)}
    
  • Shoulda: An extension to Test::Unit with the idea of contexts ( contains additional helpers, macros and assertions)

  • Cucumber: *Good for making sure all these sort of high-level features and functionalities are covered

    • Based on definition of scenarios within features (key words used in cucumber: Feature (In order, As a) Scenario(Given, When, Then)
  • Capybara: Makes it easy to simulate how a user interacts with your application capybara

  • Factory Girl:

    • A replacement for fixtures (fixtures are sample of pre defined data to populate testing database runs).
    • It has a straightforward definition syntax, support for multiple build strategies(saved and unsaved instances, attribute bases, and stubbed objects), and support for multiple factories for the same class(user, admin_user, and so on), including factory inheritance.

    • factory_girl_rails provides rails integration for factory_girl. Setup steps:

      1. gem install factory_girl_rails
      2. Add factory_girl_rails to your gem file (gem ‘factory_girl_rails’)
      3. FYI: You need to ensure that factory_girls_rails is available in the development group. If its not, rails will generate standard yml files instead of factory files
  • RSpec:

    • Its a BDD unit-testing framework for Ruby.
    • It combines the general techniques and principles of TDD.
    • spec provides the structure for writing executable examples of how your code should behave and an spec command with tools to constrain which examples get run and tailor the output.
    • Its an idea about how software development should be managed by both business interests and technical insight and it assume the use of specialized software tools to support the development process(spec-rails is a testing framework for rails 3.x and 4x).
    • Describe a step with a Describe, Context or It block that contains the business specification

Example of spec file:

describe Class do
  before do 
    setup something
  end

  it "should return something" do 
    actual_result.should eq(expected_result)
  end
end


Example of Rspec:

describe Player do
  before(:each) do
    @valid_attributes = {
      :first_name => "value for first_name";
      :last_name => "value for last_name";
      :active => true
    }
    end

  it "should create a new instance given valid attributes" do 
    Player.create!(@valid_attributes)
  end

Code Example

  1. Model specs
class User

   has_and_belongs_to_many :companies

   validates :companies, presence: true, associated: true
   validates :email, presence: true
   validates :email, uniqueness: true
   validates :password, presence: true


   class << self
      # Finds user by email
      # Method does not case sensitive
      def find_by_email(email)
         where(email: /#{email}$/i).first
      end
   end

   def first_company
      companies.first
   end
end

Model Specs – Example rspec model code

require 'spec_helper'

describe User do 

   describe 'associations' do 
      it { have_and_belong_to_many(:companies) }
   end

   describe 'validations' do
      it { should validate_presence_of(:email) }
      it { should validate_uniqueness_of(:email) }
      it { should validate_presence_of(:password) }
      it { should validate_presence_of(:companies) }
   end

   describe '.find_by_email' do 
      let!(:user) { create(:user, email: '[email protected]') }

      it 'return user by email' do
         User.find_by_email('[email protected]').should == user
      end

      it 'does not case sensitive' do 
         User.find_by_email('[email protected]').should == user
      end
   end

   describe "#first_company" do
      let(:first_company) { create(:company, name: 'first') }
      let(:user) { create(:user, companies: [first_company] }
      subject {user.first_company }

      it 'should return the first company' do
         should == first_company
      end

end
simple_example.md
Markdown
describe String do
  subject { "gabriela" }

  describe "#upcase" do
    it "should return GABRIELA" do
      subject.upcase.should == "GABRIELA"
    end
  end

  describe "#include?" do
    let(:included) { "a" }
    let(:not_included) { "o" }

    it "should return true if it contains string" do
      subject.include?(included).should == true
      # subject.should end_with("0")
      # subject.end_with?.should == true
    end


    it "should return false if not included" do
      subject.include?(not_included).should == false
    end
  end

  describe "#include?" do
    context "when it contains the string" do
      let(:string) { "a" }
      it "should return true" do
        subject.include?(string).should == true
      end
    end
    context "when it doens't contain the string" do
      let(:string) { "o" }
      it "should return false" do
        subject.include?(string).should == false
      end
    end
  end
end

Resource: https://gist.github.com/evagabriela/189517c3130f4cdeb04c
0 Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like
waltdisneyconfessions: “‘La Luna’ was so beautiful to me. As a a fourth generation woman whose mother and grandmother…
Read More
{devbeat} Q&A with David Heinemeir Hansson, Creator, Ruby on Rails  We have DHH answer questions through skype at the…
Read More
Cheat-sheet: Job application code challenge check-list: Analyze and write problem definition and approach (inc. pseudo code) Create a…
Read More