SlideShare ist ein Scribd-Unternehmen logo
1 von 123
Test Coverage
Building better software
Rails Developers Test
Rails Developers Test

 Rails has testing support baked in
Rails Developers Test

 Rails has testing support baked in
   In fact, it supports many different kinds of testing
Rails Developers Test

 Rails has testing support baked in
   In fact, it supports many different kinds of testing
 The Rails culture and community are very pro-testing
Rails Developers Test

 Rails has testing support baked in
   In fact, it supports many different kinds of testing
 The Rails culture and community are very pro-testing
   Many practice Test Driven Development (TDD)
Rails Developers Test

 Rails has testing support baked in
   In fact, it supports many different kinds of testing
 The Rails culture and community are very pro-testing
   Many practice Test Driven Development (TDD)
 You should too!
Testing Advantages
Testing Advantages
Tests can serve as your memory
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
  They will remember for 6 months
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
  They will remember for 6 months
  They will remember for other developers
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
  They will remember for 6 months
  They will remember for other developers
Upgrades and changes are easier
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
  They will remember for 6 months
  They will remember for other developers
Upgrades and changes are easier
It can help prevent regressions (especially for bugs)
Testing Advantages
Tests can serve as your memory
  They will remember 30,000 lines of code
  They will remember for 6 months
  They will remember for other developers
Upgrades and changes are easier
It can help prevent regressions (especially for bugs)
It increases confidence that your code works
Testing Doubts
Testing Doubts

Testing slows you down (writing more code)
Testing Doubts

Testing slows you down (writing more code)
  Myth: remember to add troubleshooting and
  debugging time when not testing
Testing Doubts

Testing slows you down (writing more code)
  Myth: remember to add troubleshooting and
  debugging time when not testing
Testing doesn’t produce perfect code
Testing Doubts

Testing slows you down (writing more code)
  Myth: remember to add troubleshooting and
  debugging time when not testing
Testing doesn’t produce perfect code
  Truth: but it is a tool for producing better code
Unit Tests
Tests for your models
The Goal
The Goal
Ideally you want 100% coverage
The Goal
Ideally you want 100% coverage
  That means changing a line of code should break at
  least one test
The Goal
Ideally you want 100% coverage
  That means changing a line of code should break at
  least one test
That’s rarely achieved
The Goal
Ideally you want 100% coverage
  That means changing a line of code should break at
  least one test
That’s rarely achieved
Be practical
The Goal
Ideally you want 100% coverage
  That means changing a line of code should break at
  least one test
That’s rarely achieved
Be practical
  Tests are about managing risks
The Goal
Ideally you want 100% coverage
  That means changing a line of code should break at
  least one test
That’s rarely achieved
Be practical
  Tests are about managing risks
    Is the risk worth it? (think screen scraping code)
Avoid Fixtures
Avoid Fixtures

 Rails has a feature called “fixtures” for loading data into
 the database for testing
Avoid Fixtures

 Rails has a feature called “fixtures” for loading data into
 the database for testing
   Rails clears the test database before each test
Avoid Fixtures

 Rails has a feature called “fixtures” for loading data into
 the database for testing
   Rails clears the test database before each test
 This features creates at least as many problems as it
 solves and is best avoided
Avoid Fixtures

 Rails has a feature called “fixtures” for loading data into
 the database for testing
   Rails clears the test database before each test
 This features creates at least as many problems as it
 solves and is best avoided
 I’ll show how to avoid them manually, but there’s a
 plugin, called Factory Girl, that is even better
What not to Test
What not to Test

 You need to test your code, not Rails itself
What not to Test

 You need to test your code, not Rails itself
 In other words, don’t test:
What not to Test

 You need to test your code, not Rails itself
 In other words, don’t test:
   new(), create(), save(), …
What not to Test

 You need to test your code, not Rails itself
 In other words, don’t test:
   new(), create(), save(), …
   find(), first(), all(), …
What not to Test

 You need to test your code, not Rails itself
 In other words, don’t test:
   new(), create(), save(), …
   find(), first(), all(), …
   …
A Simple Model
We are going to add tests for this model
$ ruby script/generate model user email:string first_name:string
                              last_name:string




A Simple Model
We are going to add tests for this model
$ ruby script/generate model user email:string first_name:string
                              last_name:string




        class User < ActiveRecord::Base
         validates_presence_of :email

         def full_name
          return nil if first_name.nil? and last_name.nil?
          "#{first_name} #{last_name}".strip
         end
        end




A Simple Model
We are going to add tests for this model
We Already Have Tests!
We Already Have Tests!
                           require 'test_helper'
Rails creates a test file   class UserTest < ActiveSupport::TestCase
                            # Replace this with your real tests.
for each model or           test "the truth" do
                              assert true
controller it builds        end
                           end
We Already Have Tests!
                           require 'test_helper'
Rails creates a test file   class UserTest < ActiveSupport::TestCase
                            # Replace this with your real tests.
for each model or           test "the truth" do
                              assert true
controller it builds        end
                           end


  Run tests with: rake
                           Loaded suite /Users/james/Desktop/
                                        road_tested/test/unit/
                                        user_test
                           Started
                           .
                           Finished in 0.076431 seconds.

                           1 tests, 1 assertions, 0 failures, 0 errors
We Already Have Tests!
                           require 'test_helper'
Rails creates a test file   class UserTest < ActiveSupport::TestCase
                            # Replace this with your real tests.
for each model or           test "the truth" do
                              assert true
controller it builds        end
                           end


  Run tests with: rake
                           Loaded suite /Users/james/Desktop/

These don’t really test                 road_tested/test/unit/
                                        user_test

anything, but at least     Started
                           .
                           Finished in 0.076431 seconds.
they are all wired up
                           1 tests, 1 assertions, 0 failures, 0 errors
Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
require 'test_helper'

 class UserTest < ActiveSupport::TestCase
  test "email is required" do
    user = User.new # no email
    assert(!user.valid?, "User was valid without an email")
    assert(user.errors.invalid?(:email), "Email was missing but valid")
  end
 end




Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
require 'test_helper'

 class UserTest < ActiveSupport::TestCase
  test "email is required" do
    user = User.new # no email
    assert(!user.valid?, "User was valid without an email")
    assert(user.errors.invalid?(:email), "Email was missing but valid")
  end
 end




Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
require 'test_helper'

 class UserTest < ActiveSupport::TestCase
  test "email is required" do
    user = User.new # no email
    assert(!user.valid?, "User was valid without an email")
    assert(user.errors.invalid?(:email), "Email was missing but valid")
  end
 end




Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
require 'test_helper'

 class UserTest < ActiveSupport::TestCase
  test "email is required" do
    user = User.new # no email
    assert(!user.valid?, "User was valid without an email")
    assert(user.errors.invalid?(:email), "Email was missing but valid")
  end
 end




Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
require 'test_helper'

 class UserTest < ActiveSupport::TestCase
  test "email is required" do
    user = User.new # no email
    assert(!user.valid?, "User was valid without an email")
    assert(user.errors.invalid?(:email), "Email was missing but valid")
  end
 end




Test the Validation
We are not testing that Rails validations work, we
are testing that User requires an email address
One Aspect of full_name()
It’s important to test just one thing at a time
require 'test_helper'

    class UserTest < ActiveSupport::TestCase
     # ...

     test "full name is nil if first and last name are nil" do
      user = User.new # no first_name or last_name
      assert_nil(user.full_name)
     end
    end




One Aspect of full_name()
It’s important to test just one thing at a time
require 'test_helper'

    class UserTest < ActiveSupport::TestCase
     # ...

     test "full name is nil if first and last name are nil" do
      user = User.new # no first_name or last_name
      assert_nil(user.full_name)
     end
    end




One Aspect of full_name()
It’s important to test just one thing at a time
full_name() Edge Cases
Always try to test every edge case
you can think up
require 'test_helper'

    class UserTest < ActiveSupport::TestCase
     # ...

     test "full name will use just the first name if needed" do
      user = User.new(:first_name => "James") # no last_name
      assert_equal(user.first_name, user.full_name)
     end

     test "full name will use just the last name if needed" do
      user = User.new(:last_name => "Gray") # no first_name
      assert_equal(user.last_name, user.full_name)
     end
    end




full_name() Edge Cases
Always try to test every edge case
you can think up
require 'test_helper'

    class UserTest < ActiveSupport::TestCase
     # ...

     test "full name will use just the first name if needed" do
      user = User.new(:first_name => "James") # no last_name
      assert_equal(user.first_name, user.full_name)
     end

     test "full name will use just the last name if needed" do
      user = User.new(:last_name => "Gray") # no first_name
      assert_equal(user.last_name, user.full_name)
     end
    end




full_name() Edge Cases
Always try to test every edge case
you can think up
full_name() Normal Usage
Also test the normal intended usage
require 'test_helper'

class UserTest < ActiveSupport::TestCase
 # ...

 test "full name will combine first and last name if possible" do
  user = User.new(:first_name => "James", :last_name => "Gray")
  assert_equal("#{user.first_name} #{user.last_name}", user.full_name)
 end
end




full_name() Normal Usage
Also test the normal intended usage
Passing Tests
I ran these tests in my code editor
(⌘R in TextMate)
Passing Tests
I ran these tests in my code editor
(⌘R in TextMate)
Functional Tests
Tests for your controllers
What not to Test
What not to Test
 It’s OK to decide not to test some things (controversial)
What not to Test
 It’s OK to decide not to test some things (controversial)
 I don’t test views (controversial)
What not to Test
 It’s OK to decide not to test some things (controversial)
 I don’t test views (controversial)
   They change too frequently
What not to Test
 It’s OK to decide not to test some things (controversial)
 I don’t test views (controversial)
   They change too frequently
   They may be changed by designers
What not to Test
 It’s OK to decide not to test some things (controversial)
 I don’t test views (controversial)
   They change too frequently
   They may be changed by designers
   They shouldn’t contain complex logic anyway
What not to Test
 It’s OK to decide not to test some things (controversial)
 I don’t test views (controversial)
   They change too frequently
   They may be changed by designers
   They shouldn’t contain complex logic anyway
 You should still verify that your controllers work
A Simple Controller
We will add tests for the create action of
this controller
class UsersController < ApplicationController
           def new
             @user = User.new
           end

           def create
            @user = User.new(params[:user])
            if @user.save
              flash[:notice] = "User created."
              redirect_to user_path(@user)
            else
              flash[:error] = "User could not be created."
              render :action => :new
            end
           end

           def show
            @user = User.find(1)
           end
          end




A Simple Controller
We will add tests for the create action of
this controller
Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
require 'test_helper'

   class UsersControllerTest < ActionController::TestCase
    test "entering a bad user shows the form with errors" do
      post :create             # missing email
      assert_template(:new)        # showed the new form
      assert_not_nil(flash[:error]) # with errors
    end

    test "you are taken to the show page when a user is created" do
     post :create, :user => {:email => "james@graysoftinc.com"}
     user = User.find_by_email("james@graysoftinc.com")
     assert_not_nil(user)            # a User was created
     assert_redirected_to(user_path(user)) # sent to show page
    end
   end




Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
require 'test_helper'

   class UsersControllerTest < ActionController::TestCase
    test "entering a bad user shows the form with errors" do
      post :create             # missing email
      assert_template(:new)        # showed the new form
      assert_not_nil(flash[:error]) # with errors
    end

    test "you are taken to the show page when a user is created" do
     post :create, :user => {:email => "james@graysoftinc.com"}
     user = User.find_by_email("james@graysoftinc.com")
     assert_not_nil(user)            # a User was created
     assert_redirected_to(user_path(user)) # sent to show page
    end
   end




Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
require 'test_helper'

   class UsersControllerTest < ActionController::TestCase
    test "entering a bad user shows the form with errors" do
      post :create             # missing email
      assert_template(:new)        # showed the new form
      assert_not_nil(flash[:error]) # with errors
    end

    test "you are taken to the show page when a user is created" do
     post :create, :user => {:email => "james@graysoftinc.com"}
     user = User.find_by_email("james@graysoftinc.com")
     assert_not_nil(user)            # a User was created
     assert_redirected_to(user_path(user)) # sent to show page
    end
   end




Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
require 'test_helper'

   class UsersControllerTest < ActionController::TestCase
    test "entering a bad user shows the form with errors" do
      post :create             # missing email
      assert_template(:new)        # showed the new form
      assert_not_nil(flash[:error]) # with errors
    end

    test "you are taken to the show page when a user is created" do
     post :create, :user => {:email => "james@graysoftinc.com"}
     user = User.find_by_email("james@graysoftinc.com")
     assert_not_nil(user)            # a User was created
     assert_redirected_to(user_path(user)) # sent to show page
    end
   end




Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
require 'test_helper'

   class UsersControllerTest < ActionController::TestCase
    test "entering a bad user shows the form with errors" do
      post :create             # missing email
      assert_template(:new)        # showed the new form
      assert_not_nil(flash[:error]) # with errors
    end

    test "you are taken to the show page when a user is created" do
     post :create, :user => {:email => "james@graysoftinc.com"}
     user = User.find_by_email("james@graysoftinc.com")
     assert_not_nil(user)            # a User was created
     assert_redirected_to(user_path(user)) # sent to show page
    end
   end




Test Failure and Success
I have added a couple of tests that validate the
success and failure scenarios of create
More Passing Tests
We have now started some coverage for our
controllers as well
More Passing Tests
We have now started some coverage for our
controllers as well
Even More Tests
Rails doesn’t stop there
Other Tests Supported
Other Tests Supported
Integration tests are used to write system wide tests
that cross controllers/actions (like a login system)
Other Tests Supported
Integration tests are used to write system wide tests
that cross controllers/actions (like a login system)
You can also test helpers
Other Tests Supported
Integration tests are used to write system wide tests
that cross controllers/actions (like a login system)
You can also test helpers
  I usually don’t bother with simple view logic, but
  complex systems should be tested
Other Tests Supported
Integration tests are used to write system wide tests
that cross controllers/actions (like a login system)
You can also test helpers
  I usually don’t bother with simple view logic, but
  complex systems should be tested
Rails supports basic performance profiling
Other Tests Supported
Integration tests are used to write system wide tests
that cross controllers/actions (like a login system)
You can also test helpers
  I usually don’t bother with simple view logic, but
  complex systems should be tested
Rails supports basic performance profiling
  This can be handy when you are tuning
Test Driven Development
Development practices focused on testing
The System
The System
Add a test
The System
Add a test
Run all tests and see if there is a failure
The System
Add a test
Run all tests and see if there is a failure
Write code to make the failing test pass
The System
Add a test
Run all tests and see if there is a failure
Write code to make the failing test pass
Run all tests to see them succeed
The System
Add a test
Run all tests and see if there is a failure
Write code to make the failing test pass
Run all tests to see them succeed
Refactor code as needed
The System
Add a test
Run all tests and see if there is a failure
Write code to make the failing test pass
Run all tests to see them succeed
Refactor code as needed
Repeat
Red / Green / Refactor
TDD Advantages
TDD Advantages
The process creates a very tight feedback loop
TDD Advantages
The process creates a very tight feedback loop
  This helps find problems much faster
TDD Advantages
The process creates a very tight feedback loop
  This helps find problems much faster
  Dramatically reduces debugging time
TDD Advantages
The process creates a very tight feedback loop
  This helps find problems much faster
  Dramatically reduces debugging time
  It makes you more aware of YAGNI
TDD Advantages
The process creates a very tight feedback loop
  This helps find problems much faster
  Dramatically reduces debugging time
  It makes you more aware of YAGNI
Drives the design of the code
TDD Advantages
The process creates a very tight feedback loop
  This helps find problems much faster
  Dramatically reduces debugging time
  It makes you more aware of YAGNI
Drives the design of the code
  Encourages smaller and more modular code
Let’s Test Drive a Feature
Let’s Test Drive a Feature


 We currently check that an email is provided
Let’s Test Drive a Feature


 We currently check that an email is provided
 Let’s add a simple reality check to make sure it looks
 like an email address
Let’s Test Drive a Feature


 We currently check that an email is provided
 Let’s add a simple reality check to make sure it looks
 like an email address
   This isn’t perfect, but it could catch some mistakes
1. Add a Test
I have added the test I expect to fail and my goal
will now be to get it to work
require 'test_helper'

class UserTest < ActiveSupport::TestCase
 # ...

 test "email should be well formed" do
  user = User.new(:email => "not well formed!")
  assert(!user.valid?, "User was valid with a bad email")
  assert(user.errors.invalid?(:email), "Email was invalid but allowed")
 end
end




1. Add a Test
I have added the test I expect to fail and my goal
will now be to get it to work
2. Run all Tests (“Red”)
This shows that our new feature isn’t working
yet, as we expected
2. Run all Tests (“Red”)
This shows that our new feature isn’t working
yet, as we expected
3. Write Code
I am now adding the code to
make the feature work
class User < ActiveRecord::Base
   validates_presence_of :email
   validates_format_of :email,
                 :with => /A[^@s]+@[^@s]+.[^@s]+z/,
                 :message => "was not well formed"

   def full_name
    return nil if first_name.nil? and last_name.nil?
    "#{first_name} #{last_name}".strip
   end
  end




3. Write Code
I am now adding the code to
make the feature work
class User < ActiveRecord::Base
   validates_presence_of :email
   validates_format_of :email,
                 :with => /A[^@s]+@[^@s]+.[^@s]+z/,
                 :message => "was not well formed"

   def full_name
    return nil if first_name.nil? and last_name.nil?
    "#{first_name} #{last_name}".strip
   end
  end




3. Write Code
I am now adding the code to
make the feature work
4. Run all Tests (“Green”)
This shows that I have succeeded,
since my test now passes
4. Run all Tests (“Green”)
This shows that I have succeeded,
since my test now passes
5. Refactor
5. Refactor

Not needed in this case
5. Refactor

Not needed in this case
This step allows you to clean up messes you create to
make a test pass
5. Refactor

Not needed in this case
This step allows you to clean up messes you create to
make a test pass
You can refactor and verify that the tests stay Green
(you didn’t change things)
Questions?
Test Your Application Lab
Your book has instructions for how to start
increasing the test coverage for your application

Weitere ähnliche Inhalte

Was ist angesagt?

Javazone 2019 - Mutants to the rescue: How effective are your unit tests?
Javazone 2019 - Mutants to the rescue: How effective are your unit tests?Javazone 2019 - Mutants to the rescue: How effective are your unit tests?
Javazone 2019 - Mutants to the rescue: How effective are your unit tests?Paco van Beckhoven
 
Mutation Testing DevoxxUK 2021
Mutation Testing DevoxxUK 2021Mutation Testing DevoxxUK 2021
Mutation Testing DevoxxUK 2021Paco van Beckhoven
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails AppsRabble .
 
Unit Test in Ruby on Rails by Minitest
Unit Test in Ruby on Rails by MinitestUnit Test in Ruby on Rails by Minitest
Unit Test in Ruby on Rails by MinitestHosang Jeon
 
AngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and JasmineAngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and Jasminefoxp2code
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJSPeter Drinnan
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript TestingThomas Fuchs
 
Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013Hazem Saleh
 
AngularJS Unit Test
AngularJS Unit TestAngularJS Unit Test
AngularJS Unit TestChiew Carol
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptRyan Anklam
 
Principles and patterns for test driven development
Principles and patterns for test driven developmentPrinciples and patterns for test driven development
Principles and patterns for test driven developmentStephen Fuqua
 
React.js enlightenment
React.js enlightenmentReact.js enlightenment
React.js enlightenmentArtur Szott
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsFITC
 
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]Iakiv Kramarenko
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mudseleniumconf
 

Was ist angesagt? (20)

Javazone 2019 - Mutants to the rescue: How effective are your unit tests?
Javazone 2019 - Mutants to the rescue: How effective are your unit tests?Javazone 2019 - Mutants to the rescue: How effective are your unit tests?
Javazone 2019 - Mutants to the rescue: How effective are your unit tests?
 
Mutation Testing DevoxxUK 2021
Mutation Testing DevoxxUK 2021Mutation Testing DevoxxUK 2021
Mutation Testing DevoxxUK 2021
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Angular Unit Test
Angular Unit TestAngular Unit Test
Angular Unit Test
 
Unit Test in Ruby on Rails by Minitest
Unit Test in Ruby on Rails by MinitestUnit Test in Ruby on Rails by Minitest
Unit Test in Ruby on Rails by Minitest
 
AngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and JasmineAngularJS Unit Testing w/Karma and Jasmine
AngularJS Unit Testing w/Karma and Jasmine
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Qunit Java script Un
Qunit Java script UnQunit Java script Un
Qunit Java script Un
 
Testing in AngularJS
Testing in AngularJSTesting in AngularJS
Testing in AngularJS
 
Adventures In JavaScript Testing
Adventures In JavaScript TestingAdventures In JavaScript Testing
Adventures In JavaScript Testing
 
Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013Efficient JavaScript Unit Testing, March 2013
Efficient JavaScript Unit Testing, March 2013
 
AngularJS Unit Test
AngularJS Unit TestAngularJS Unit Test
AngularJS Unit Test
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Principles and patterns for test driven development
Principles and patterns for test driven developmentPrinciples and patterns for test driven development
Principles and patterns for test driven development
 
React.js enlightenment
React.js enlightenmentReact.js enlightenment
React.js enlightenment
 
Php tests tips
Php tests tipsPhp tests tips
Php tests tips
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
 
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
Selenide alternative in Python - Introducing Selene [SeleniumCamp 2016]
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
Building Quality with Foundations of Mud
Building Quality with Foundations of MudBuilding Quality with Foundations of Mud
Building Quality with Foundations of Mud
 

Andere mochten auch

ERTMS Solutions : TrackCircuit LifeCheck
ERTMS Solutions : TrackCircuit LifeCheckERTMS Solutions : TrackCircuit LifeCheck
ERTMS Solutions : TrackCircuit LifeCheckERTMS Solutions
 
What test coverage mean to us
What test coverage mean to usWhat test coverage mean to us
What test coverage mean to usJoseph Yao
 
railway failure and its type
railway failure and its typerailway failure and its type
railway failure and its typeYash Patel
 
Top 8 digital project manager resume samples
Top 8 digital project manager resume samplesTop 8 digital project manager resume samples
Top 8 digital project manager resume samplesporijom
 
Effective test coverage Techniques
Effective test coverage TechniquesEffective test coverage Techniques
Effective test coverage TechniquesPhanindra Kishore
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionAlex Su
 
railway presentation Ppt
railway presentation Pptrailway presentation Ppt
railway presentation PptSachin Singh
 
railway ppt for civil engg.
 railway ppt for civil engg. railway ppt for civil engg.
railway ppt for civil engg.ashrafdgrt
 
Rails, Types, Joints, Creep, Failure of Rails and Welding of Rails
Rails, Types, Joints, Creep, Failure of Rails and Welding of RailsRails, Types, Joints, Creep, Failure of Rails and Welding of Rails
Rails, Types, Joints, Creep, Failure of Rails and Welding of Railssrinivas2036
 

Andere mochten auch (10)

ERTMS Solutions : TrackCircuit LifeCheck
ERTMS Solutions : TrackCircuit LifeCheckERTMS Solutions : TrackCircuit LifeCheck
ERTMS Solutions : TrackCircuit LifeCheck
 
What test coverage mean to us
What test coverage mean to usWhat test coverage mean to us
What test coverage mean to us
 
railway failure and its type
railway failure and its typerailway failure and its type
railway failure and its type
 
Top 8 digital project manager resume samples
Top 8 digital project manager resume samplesTop 8 digital project manager resume samples
Top 8 digital project manager resume samples
 
Effective test coverage Techniques
Effective test coverage TechniquesEffective test coverage Techniques
Effective test coverage Techniques
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage Introduction
 
railway presentation Ppt
railway presentation Pptrailway presentation Ppt
railway presentation Ppt
 
Railway engineering
Railway engineeringRailway engineering
Railway engineering
 
railway ppt for civil engg.
 railway ppt for civil engg. railway ppt for civil engg.
railway ppt for civil engg.
 
Rails, Types, Joints, Creep, Failure of Rails and Welding of Rails
Rails, Types, Joints, Creep, Failure of Rails and Welding of RailsRails, Types, Joints, Creep, Failure of Rails and Welding of Rails
Rails, Types, Joints, Creep, Failure of Rails and Welding of Rails
 

Ähnlich wie Test Rails Model Validations and Methods

We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentAll Things Open
 
Rails Testing
Rails TestingRails Testing
Rails Testingmikeblake
 
Ruby on rails integration testing with minitest and capybara
Ruby on rails integration testing with minitest and capybaraRuby on rails integration testing with minitest and capybara
Ruby on rails integration testing with minitest and capybaraAndolasoft Inc
 
TDD super mondays-june-2014
TDD super mondays-june-2014TDD super mondays-june-2014
TDD super mondays-june-2014Alex Kavanagh
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD WorkshopWolfram Arnold
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test communityKerry Buckley
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slidesericholscher
 
SELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfSELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfEric Selje
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLSteven Feuerstein
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Railsbenlcollins
 
Java Unit Test - JUnit
Java Unit Test - JUnitJava Unit Test - JUnit
Java Unit Test - JUnitAktuğ Urun
 
Test Drive Development in Ruby On Rails
Test Drive Development in Ruby On RailsTest Drive Development in Ruby On Rails
Test Drive Development in Ruby On RailsNyros Technologies
 
Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Holger Grosse-Plankermann
 
Automated Testing in Django
Automated Testing in DjangoAutomated Testing in Django
Automated Testing in DjangoLoek van Gent
 
Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Holger Grosse-Plankermann
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpecDarren Craig
 

Ähnlich wie Test Rails Model Validations and Methods (20)

Rtt preso
Rtt presoRtt preso
Rtt preso
 
We Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End DevelopmentWe Are All Testers Now: The Testing Pyramid and Front-End Development
We Are All Testers Now: The Testing Pyramid and Front-End Development
 
Rails Testing
Rails TestingRails Testing
Rails Testing
 
Ruby on rails integration testing with minitest and capybara
Ruby on rails integration testing with minitest and capybaraRuby on rails integration testing with minitest and capybara
Ruby on rails integration testing with minitest and capybara
 
TDD super mondays-june-2014
TDD super mondays-june-2014TDD super mondays-june-2014
TDD super mondays-june-2014
 
TDD & BDD
TDD & BDDTDD & BDD
TDD & BDD
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
Token Testing Slides
Token  Testing SlidesToken  Testing Slides
Token Testing Slides
 
SELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdfSELJE_Database_Unit_Testing.pdf
SELJE_Database_Unit_Testing.pdf
 
Rspec
RspecRspec
Rspec
 
utPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQLutPLSQL: Unit Testing for Oracle PL/SQL
utPLSQL: Unit Testing for Oracle PL/SQL
 
Introduction to testing in Rails
Introduction to testing in RailsIntroduction to testing in Rails
Introduction to testing in Rails
 
Java Unit Test - JUnit
Java Unit Test - JUnitJava Unit Test - JUnit
Java Unit Test - JUnit
 
Test Drive Development in Ruby On Rails
Test Drive Development in Ruby On RailsTest Drive Development in Ruby On Rails
Test Drive Development in Ruby On Rails
 
Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018Das Frontend richtig Testen – mit Jest @Developer Week 2018
Das Frontend richtig Testen – mit Jest @Developer Week 2018
 
Rspec
RspecRspec
Rspec
 
Automated Testing in Django
Automated Testing in DjangoAutomated Testing in Django
Automated Testing in Django
 
Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018Jest: Frontend Testing leicht gemacht @EnterJS2018
Jest: Frontend Testing leicht gemacht @EnterJS2018
 
Software Testing & PHPSpec
Software Testing & PHPSpecSoftware Testing & PHPSpec
Software Testing & PHPSpec
 

Mehr von James Gray

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A KeynoteJames Gray
 
Regular expressions
Regular expressionsRegular expressions
Regular expressionsJames Gray
 
Counting on God
Counting on GodCounting on God
Counting on GodJames Gray
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your MindJames Gray
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)James Gray
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHubJames Gray
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And RenderingJames Gray
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with RailsJames Gray
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in RailsJames Gray
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersJames Gray
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails InterfaceJames Gray
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model BasicsJames Gray
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on RailsJames Gray
 

Mehr von James Gray (18)

A Dickens of A Keynote
A Dickens of A KeynoteA Dickens of A Keynote
A Dickens of A Keynote
 
I Doubt That!
I Doubt That!I Doubt That!
I Doubt That!
 
Regular expressions
Regular expressionsRegular expressions
Regular expressions
 
Counting on God
Counting on GodCounting on God
Counting on God
 
In the Back of Your Mind
In the Back of Your MindIn the Back of Your Mind
In the Back of Your Mind
 
Unblocked
UnblockedUnblocked
Unblocked
 
Module Magic
Module MagicModule Magic
Module Magic
 
API Design
API DesignAPI Design
API Design
 
Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)Amazon's Simple Storage Service (S3)
Amazon's Simple Storage Service (S3)
 
Git and GitHub
Git and GitHubGit and GitHub
Git and GitHub
 
Rails Routing And Rendering
Rails Routing And RenderingRails Routing And Rendering
Rails Routing And Rendering
 
Sending Email with Rails
Sending Email with RailsSending Email with Rails
Sending Email with Rails
 
Associations in Rails
Associations in RailsAssociations in Rails
Associations in Rails
 
DRYing Up Rails Views and Controllers
DRYing Up Rails Views and ControllersDRYing Up Rails Views and Controllers
DRYing Up Rails Views and Controllers
 
Building a Rails Interface
Building a Rails InterfaceBuilding a Rails Interface
Building a Rails Interface
 
Rails Model Basics
Rails Model BasicsRails Model Basics
Rails Model Basics
 
Ruby
RubyRuby
Ruby
 
Wed Development on Rails
Wed Development on RailsWed Development on Rails
Wed Development on Rails
 

Kürzlich hochgeladen

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 

Kürzlich hochgeladen (20)

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 

Test Rails Model Validations and Methods

  • 3. Rails Developers Test Rails has testing support baked in
  • 4. Rails Developers Test Rails has testing support baked in In fact, it supports many different kinds of testing
  • 5. Rails Developers Test Rails has testing support baked in In fact, it supports many different kinds of testing The Rails culture and community are very pro-testing
  • 6. Rails Developers Test Rails has testing support baked in In fact, it supports many different kinds of testing The Rails culture and community are very pro-testing Many practice Test Driven Development (TDD)
  • 7. Rails Developers Test Rails has testing support baked in In fact, it supports many different kinds of testing The Rails culture and community are very pro-testing Many practice Test Driven Development (TDD) You should too!
  • 9. Testing Advantages Tests can serve as your memory
  • 10. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code
  • 11. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code They will remember for 6 months
  • 12. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code They will remember for 6 months They will remember for other developers
  • 13. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code They will remember for 6 months They will remember for other developers Upgrades and changes are easier
  • 14. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code They will remember for 6 months They will remember for other developers Upgrades and changes are easier It can help prevent regressions (especially for bugs)
  • 15. Testing Advantages Tests can serve as your memory They will remember 30,000 lines of code They will remember for 6 months They will remember for other developers Upgrades and changes are easier It can help prevent regressions (especially for bugs) It increases confidence that your code works
  • 17. Testing Doubts Testing slows you down (writing more code)
  • 18. Testing Doubts Testing slows you down (writing more code) Myth: remember to add troubleshooting and debugging time when not testing
  • 19. Testing Doubts Testing slows you down (writing more code) Myth: remember to add troubleshooting and debugging time when not testing Testing doesn’t produce perfect code
  • 20. Testing Doubts Testing slows you down (writing more code) Myth: remember to add troubleshooting and debugging time when not testing Testing doesn’t produce perfect code Truth: but it is a tool for producing better code
  • 21. Unit Tests Tests for your models
  • 23. The Goal Ideally you want 100% coverage
  • 24. The Goal Ideally you want 100% coverage That means changing a line of code should break at least one test
  • 25. The Goal Ideally you want 100% coverage That means changing a line of code should break at least one test That’s rarely achieved
  • 26. The Goal Ideally you want 100% coverage That means changing a line of code should break at least one test That’s rarely achieved Be practical
  • 27. The Goal Ideally you want 100% coverage That means changing a line of code should break at least one test That’s rarely achieved Be practical Tests are about managing risks
  • 28. The Goal Ideally you want 100% coverage That means changing a line of code should break at least one test That’s rarely achieved Be practical Tests are about managing risks Is the risk worth it? (think screen scraping code)
  • 30. Avoid Fixtures Rails has a feature called “fixtures” for loading data into the database for testing
  • 31. Avoid Fixtures Rails has a feature called “fixtures” for loading data into the database for testing Rails clears the test database before each test
  • 32. Avoid Fixtures Rails has a feature called “fixtures” for loading data into the database for testing Rails clears the test database before each test This features creates at least as many problems as it solves and is best avoided
  • 33. Avoid Fixtures Rails has a feature called “fixtures” for loading data into the database for testing Rails clears the test database before each test This features creates at least as many problems as it solves and is best avoided I’ll show how to avoid them manually, but there’s a plugin, called Factory Girl, that is even better
  • 34. What not to Test
  • 35. What not to Test You need to test your code, not Rails itself
  • 36. What not to Test You need to test your code, not Rails itself In other words, don’t test:
  • 37. What not to Test You need to test your code, not Rails itself In other words, don’t test: new(), create(), save(), …
  • 38. What not to Test You need to test your code, not Rails itself In other words, don’t test: new(), create(), save(), … find(), first(), all(), …
  • 39. What not to Test You need to test your code, not Rails itself In other words, don’t test: new(), create(), save(), … find(), first(), all(), … …
  • 40. A Simple Model We are going to add tests for this model
  • 41. $ ruby script/generate model user email:string first_name:string last_name:string A Simple Model We are going to add tests for this model
  • 42. $ ruby script/generate model user email:string first_name:string last_name:string class User < ActiveRecord::Base validates_presence_of :email def full_name return nil if first_name.nil? and last_name.nil? "#{first_name} #{last_name}".strip end end A Simple Model We are going to add tests for this model
  • 43. We Already Have Tests!
  • 44. We Already Have Tests! require 'test_helper' Rails creates a test file class UserTest < ActiveSupport::TestCase # Replace this with your real tests. for each model or test "the truth" do assert true controller it builds end end
  • 45. We Already Have Tests! require 'test_helper' Rails creates a test file class UserTest < ActiveSupport::TestCase # Replace this with your real tests. for each model or test "the truth" do assert true controller it builds end end Run tests with: rake Loaded suite /Users/james/Desktop/ road_tested/test/unit/ user_test Started . Finished in 0.076431 seconds. 1 tests, 1 assertions, 0 failures, 0 errors
  • 46. We Already Have Tests! require 'test_helper' Rails creates a test file class UserTest < ActiveSupport::TestCase # Replace this with your real tests. for each model or test "the truth" do assert true controller it builds end end Run tests with: rake Loaded suite /Users/james/Desktop/ These don’t really test road_tested/test/unit/ user_test anything, but at least Started . Finished in 0.076431 seconds. they are all wired up 1 tests, 1 assertions, 0 failures, 0 errors
  • 47. Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 48. require 'test_helper' class UserTest < ActiveSupport::TestCase test "email is required" do user = User.new # no email assert(!user.valid?, "User was valid without an email") assert(user.errors.invalid?(:email), "Email was missing but valid") end end Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 49. require 'test_helper' class UserTest < ActiveSupport::TestCase test "email is required" do user = User.new # no email assert(!user.valid?, "User was valid without an email") assert(user.errors.invalid?(:email), "Email was missing but valid") end end Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 50. require 'test_helper' class UserTest < ActiveSupport::TestCase test "email is required" do user = User.new # no email assert(!user.valid?, "User was valid without an email") assert(user.errors.invalid?(:email), "Email was missing but valid") end end Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 51. require 'test_helper' class UserTest < ActiveSupport::TestCase test "email is required" do user = User.new # no email assert(!user.valid?, "User was valid without an email") assert(user.errors.invalid?(:email), "Email was missing but valid") end end Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 52. require 'test_helper' class UserTest < ActiveSupport::TestCase test "email is required" do user = User.new # no email assert(!user.valid?, "User was valid without an email") assert(user.errors.invalid?(:email), "Email was missing but valid") end end Test the Validation We are not testing that Rails validations work, we are testing that User requires an email address
  • 53. One Aspect of full_name() It’s important to test just one thing at a time
  • 54. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "full name is nil if first and last name are nil" do user = User.new # no first_name or last_name assert_nil(user.full_name) end end One Aspect of full_name() It’s important to test just one thing at a time
  • 55. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "full name is nil if first and last name are nil" do user = User.new # no first_name or last_name assert_nil(user.full_name) end end One Aspect of full_name() It’s important to test just one thing at a time
  • 56. full_name() Edge Cases Always try to test every edge case you can think up
  • 57. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "full name will use just the first name if needed" do user = User.new(:first_name => "James") # no last_name assert_equal(user.first_name, user.full_name) end test "full name will use just the last name if needed" do user = User.new(:last_name => "Gray") # no first_name assert_equal(user.last_name, user.full_name) end end full_name() Edge Cases Always try to test every edge case you can think up
  • 58. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "full name will use just the first name if needed" do user = User.new(:first_name => "James") # no last_name assert_equal(user.first_name, user.full_name) end test "full name will use just the last name if needed" do user = User.new(:last_name => "Gray") # no first_name assert_equal(user.last_name, user.full_name) end end full_name() Edge Cases Always try to test every edge case you can think up
  • 59. full_name() Normal Usage Also test the normal intended usage
  • 60. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "full name will combine first and last name if possible" do user = User.new(:first_name => "James", :last_name => "Gray") assert_equal("#{user.first_name} #{user.last_name}", user.full_name) end end full_name() Normal Usage Also test the normal intended usage
  • 61. Passing Tests I ran these tests in my code editor (⌘R in TextMate)
  • 62. Passing Tests I ran these tests in my code editor (⌘R in TextMate)
  • 63. Functional Tests Tests for your controllers
  • 64. What not to Test
  • 65. What not to Test It’s OK to decide not to test some things (controversial)
  • 66. What not to Test It’s OK to decide not to test some things (controversial) I don’t test views (controversial)
  • 67. What not to Test It’s OK to decide not to test some things (controversial) I don’t test views (controversial) They change too frequently
  • 68. What not to Test It’s OK to decide not to test some things (controversial) I don’t test views (controversial) They change too frequently They may be changed by designers
  • 69. What not to Test It’s OK to decide not to test some things (controversial) I don’t test views (controversial) They change too frequently They may be changed by designers They shouldn’t contain complex logic anyway
  • 70. What not to Test It’s OK to decide not to test some things (controversial) I don’t test views (controversial) They change too frequently They may be changed by designers They shouldn’t contain complex logic anyway You should still verify that your controllers work
  • 71. A Simple Controller We will add tests for the create action of this controller
  • 72. class UsersController < ApplicationController def new @user = User.new end def create @user = User.new(params[:user]) if @user.save flash[:notice] = "User created." redirect_to user_path(@user) else flash[:error] = "User could not be created." render :action => :new end end def show @user = User.find(1) end end A Simple Controller We will add tests for the create action of this controller
  • 73. Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 74. require 'test_helper' class UsersControllerTest < ActionController::TestCase test "entering a bad user shows the form with errors" do post :create # missing email assert_template(:new) # showed the new form assert_not_nil(flash[:error]) # with errors end test "you are taken to the show page when a user is created" do post :create, :user => {:email => "james@graysoftinc.com"} user = User.find_by_email("james@graysoftinc.com") assert_not_nil(user) # a User was created assert_redirected_to(user_path(user)) # sent to show page end end Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 75. require 'test_helper' class UsersControllerTest < ActionController::TestCase test "entering a bad user shows the form with errors" do post :create # missing email assert_template(:new) # showed the new form assert_not_nil(flash[:error]) # with errors end test "you are taken to the show page when a user is created" do post :create, :user => {:email => "james@graysoftinc.com"} user = User.find_by_email("james@graysoftinc.com") assert_not_nil(user) # a User was created assert_redirected_to(user_path(user)) # sent to show page end end Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 76. require 'test_helper' class UsersControllerTest < ActionController::TestCase test "entering a bad user shows the form with errors" do post :create # missing email assert_template(:new) # showed the new form assert_not_nil(flash[:error]) # with errors end test "you are taken to the show page when a user is created" do post :create, :user => {:email => "james@graysoftinc.com"} user = User.find_by_email("james@graysoftinc.com") assert_not_nil(user) # a User was created assert_redirected_to(user_path(user)) # sent to show page end end Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 77. require 'test_helper' class UsersControllerTest < ActionController::TestCase test "entering a bad user shows the form with errors" do post :create # missing email assert_template(:new) # showed the new form assert_not_nil(flash[:error]) # with errors end test "you are taken to the show page when a user is created" do post :create, :user => {:email => "james@graysoftinc.com"} user = User.find_by_email("james@graysoftinc.com") assert_not_nil(user) # a User was created assert_redirected_to(user_path(user)) # sent to show page end end Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 78. require 'test_helper' class UsersControllerTest < ActionController::TestCase test "entering a bad user shows the form with errors" do post :create # missing email assert_template(:new) # showed the new form assert_not_nil(flash[:error]) # with errors end test "you are taken to the show page when a user is created" do post :create, :user => {:email => "james@graysoftinc.com"} user = User.find_by_email("james@graysoftinc.com") assert_not_nil(user) # a User was created assert_redirected_to(user_path(user)) # sent to show page end end Test Failure and Success I have added a couple of tests that validate the success and failure scenarios of create
  • 79. More Passing Tests We have now started some coverage for our controllers as well
  • 80. More Passing Tests We have now started some coverage for our controllers as well
  • 81. Even More Tests Rails doesn’t stop there
  • 83. Other Tests Supported Integration tests are used to write system wide tests that cross controllers/actions (like a login system)
  • 84. Other Tests Supported Integration tests are used to write system wide tests that cross controllers/actions (like a login system) You can also test helpers
  • 85. Other Tests Supported Integration tests are used to write system wide tests that cross controllers/actions (like a login system) You can also test helpers I usually don’t bother with simple view logic, but complex systems should be tested
  • 86. Other Tests Supported Integration tests are used to write system wide tests that cross controllers/actions (like a login system) You can also test helpers I usually don’t bother with simple view logic, but complex systems should be tested Rails supports basic performance profiling
  • 87. Other Tests Supported Integration tests are used to write system wide tests that cross controllers/actions (like a login system) You can also test helpers I usually don’t bother with simple view logic, but complex systems should be tested Rails supports basic performance profiling This can be handy when you are tuning
  • 88. Test Driven Development Development practices focused on testing
  • 91. The System Add a test Run all tests and see if there is a failure
  • 92. The System Add a test Run all tests and see if there is a failure Write code to make the failing test pass
  • 93. The System Add a test Run all tests and see if there is a failure Write code to make the failing test pass Run all tests to see them succeed
  • 94. The System Add a test Run all tests and see if there is a failure Write code to make the failing test pass Run all tests to see them succeed Refactor code as needed
  • 95. The System Add a test Run all tests and see if there is a failure Write code to make the failing test pass Run all tests to see them succeed Refactor code as needed Repeat
  • 96.
  • 97. Red / Green / Refactor
  • 99. TDD Advantages The process creates a very tight feedback loop
  • 100. TDD Advantages The process creates a very tight feedback loop This helps find problems much faster
  • 101. TDD Advantages The process creates a very tight feedback loop This helps find problems much faster Dramatically reduces debugging time
  • 102. TDD Advantages The process creates a very tight feedback loop This helps find problems much faster Dramatically reduces debugging time It makes you more aware of YAGNI
  • 103. TDD Advantages The process creates a very tight feedback loop This helps find problems much faster Dramatically reduces debugging time It makes you more aware of YAGNI Drives the design of the code
  • 104. TDD Advantages The process creates a very tight feedback loop This helps find problems much faster Dramatically reduces debugging time It makes you more aware of YAGNI Drives the design of the code Encourages smaller and more modular code
  • 105. Let’s Test Drive a Feature
  • 106. Let’s Test Drive a Feature We currently check that an email is provided
  • 107. Let’s Test Drive a Feature We currently check that an email is provided Let’s add a simple reality check to make sure it looks like an email address
  • 108. Let’s Test Drive a Feature We currently check that an email is provided Let’s add a simple reality check to make sure it looks like an email address This isn’t perfect, but it could catch some mistakes
  • 109. 1. Add a Test I have added the test I expect to fail and my goal will now be to get it to work
  • 110. require 'test_helper' class UserTest < ActiveSupport::TestCase # ... test "email should be well formed" do user = User.new(:email => "not well formed!") assert(!user.valid?, "User was valid with a bad email") assert(user.errors.invalid?(:email), "Email was invalid but allowed") end end 1. Add a Test I have added the test I expect to fail and my goal will now be to get it to work
  • 111. 2. Run all Tests (“Red”) This shows that our new feature isn’t working yet, as we expected
  • 112. 2. Run all Tests (“Red”) This shows that our new feature isn’t working yet, as we expected
  • 113. 3. Write Code I am now adding the code to make the feature work
  • 114. class User < ActiveRecord::Base validates_presence_of :email validates_format_of :email, :with => /A[^@s]+@[^@s]+.[^@s]+z/, :message => "was not well formed" def full_name return nil if first_name.nil? and last_name.nil? "#{first_name} #{last_name}".strip end end 3. Write Code I am now adding the code to make the feature work
  • 115. class User < ActiveRecord::Base validates_presence_of :email validates_format_of :email, :with => /A[^@s]+@[^@s]+.[^@s]+z/, :message => "was not well formed" def full_name return nil if first_name.nil? and last_name.nil? "#{first_name} #{last_name}".strip end end 3. Write Code I am now adding the code to make the feature work
  • 116. 4. Run all Tests (“Green”) This shows that I have succeeded, since my test now passes
  • 117. 4. Run all Tests (“Green”) This shows that I have succeeded, since my test now passes
  • 119. 5. Refactor Not needed in this case
  • 120. 5. Refactor Not needed in this case This step allows you to clean up messes you create to make a test pass
  • 121. 5. Refactor Not needed in this case This step allows you to clean up messes you create to make a test pass You can refactor and verify that the tests stay Green (you didn’t change things)
  • 123. Test Your Application Lab Your book has instructions for how to start increasing the test coverage for your application

Hinweis der Redaktion