Ruby on Rails - How to (Finally) Learn Test-Driven Development - ruby on rails tutorial - rails guides - rails tutorial - ruby rails



Test-driven development:

  • Test-driven development (TDD) is a software development process that relies on the repetition of a very short development cycle
  • First the developer writes an (initially failing) automated test case that defines a desired improvement or new function.
  • And then produces the minimum amount of code to pass that test, and finally refactors the new code to acceptable standards.

Advantages:

  • It can help you write better software by encouraging simple, durable design.
  • You can quickly verify that your program works as intended.
  • It takes much less time spent debugging frustrating problems.

Red, Green, Refactor Explained:

Hqdefault In Ruby On Rails
Learn Ruby On Rails Tutorials - Hqdefault In Ruby On Rails - Ruby On Rails Examples
  • The hallmark of test-driven development as a practice is following the red, green, refactor workflow, often described as follows:
    1. Write a failing test.
    2. Make it pass.
    3. Refactor your code.

Unit tests:

  • Here’s a small example. Let’s say we making a little game in the Ruby programming language. (we are not using a game development library like Gosu for this, just plain old Ruby.)
  • When a ‘Player’ scores a goal, we want their @goals instance variable to increase by 1.
require 'player'

describe Player do
  describe '#score_goal' do
    it 'increments player goal tally by 1' do
      player = Player.new

      player.score_goal

      expect(player.goals).to eq 1
  end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • At the time, we write this test, the score_goal method on the Player object doesn’t even exist!
  • We writing a test based on how we want the code to work.
  • When we run this test, it will quickly fail with a ‘No method’ error about the score_goal method I’ve tried to call on the player object.
Ruby On Rails Test Drive Developement
Learn Ruby On Rails Tutorials - Ruby On Rails Test Drive Developement - Ruby On Rails Examples
  • As a next step, we can implement this method, but make it do nothing at first.
class Player
  attr_accessor :goals

  def initialize(goals = 0)
    @goals = goals
  end

  def score_goal
  end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
  • The next time we run the test we’ll get a better failure:
Ruby On Rails Test Drive Developement2
Learn Ruby On Rails Tutorials - Ruby On Rails Test Drive Developement2 - Ruby On Rails Examples
  • A good failure is a test that fails due to its expectation not being met, rather than due to a parse error inside the test.
  • If possible, you should try to get to a ‘good’ failure before beginning to implement the functionality you are testing.
  • Now we can implement just enough code to make the test pass.
def score_goal
  @goals = 1
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
Ruby On Rails Test Drive Developement3
Learn Ruby On Rails Tutorials - Ruby On Rails Test Drive Developement3 - Ruby On Rails Examples
  • We now have a passing test. The final step in the process is refactoring, which means taking the time to make it easier to understand what the code does without changing what it does.
  • In this case, the method is so simple that we probably don’t need a refactoring here, but often, you will.
  • But wait! You may have noticed that this code is problematic. If the same player scores another goal, the player’s goal count will remain stuck at 1.
  • This is a good thing, because it drives us to write another test that will, in turn, lead to a more robust implementation of our score_goalfeature.
describe Player do
  describe '#score_goal' do
    it 'increments player goal tally by 1' do
      player = Player.new

      player.score_goal

      expect(player.goals).to eq 1
    end

    it 'adds to goal tally when additional goals are scored' do
      player = Player.new
      player.goals = 2

      player.score_goal

      expect(player.goals).to eq 3
    end
  end
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
Ruby On Rails Test Drive Developement4
Learn Ruby On Rails Tutorials - Ruby On Rails Test Drive Developement4 - Ruby On Rails Examples
  • Now we can update our method with a better implementation, and both tests should still pass:
def score_goal
  @goals += 1
end
Clicking "Copy Code" button will copy the code into the clipboard - memory. Please paste(Ctrl+V) it in your destination. The code will get pasted. Happy coding from Wikitechy - ruby on rails tutorial - rails guides - ruby rails - rubyonrails - learn ruby on rails - team
Ruby On Rails Test Drive Developement5
Learn Ruby On Rails Tutorials - Ruby On Rails Test Drive Developement5 - Ruby On Rails Examples
  • The tests we’ve been writing so far are examples of unit tests. Unit tests exercise small bits of your application code in isolation.
  • A great way to practice test-driven development is to create a simple command line app, an app that runs in your Terminal (on OS X), or your Command Prompt (on Windows).
  • Try to write unit tests for the app, from start to finish. Each time you want to add a behavior to the app, try to write a failing test first.

Here are a few ideas for the kinds of apps you could create:

  • A random generator for something (names, towns, characters)
  • Tic Tac Toe
  • A cash register
  • An app to record things you’ve lent out and borrowed from friends

Once you’ve used test-driven development to design a command line application, your next challenge is applying these same principles to a web application.

Test-driven development on the web:

  • Unit tests are just one kind of automated test, and are suited to almost all kinds of programs.
  • Because web applications are complex, and often involve many pieces working together, other types of tests are often necessary to make sure that users are experiencing your software in the best possible way.

End-to-end tests:

  • Also known as acceptance tests, integration tests, E2E tests.
  • There are two dominant approaches to this kind of testing:
    1. User-journey based approach.
    2. Acceptance criteria based.

A user-journey based approach:

  • A user journey is a sequence of actions a user is likely to undertake when interacting with your application.
  • Examples, You are login into your email, leaving a comment on Facebook, or making a transaction in your online banking account.
  • Each application is made up of dozens, or hundreds, of potential user journeys.
  • User-journey based end-to-end tests try to simulate your app’s most important user journeys by controlling a browser (or a simulated browser) with code.
  • Browser automation tools like Selenium actually open up a browser instance and trigger click events and other interactions on elements on the page, according to your instructions.
  • Other E2E tests run in headless mode, where interactions with your app happen in the background and are not displayed via the GUI.
  • When writing end-to-end tests, you will be writing code to fill in forms, click buttons, and check that certain HTML elements are visible on the page.
  • When a comprehensive suite of end-to-end tests runs successfully, you should be confident that all the most important user journeys in your app are hanging together.

Pros:Provides an extra level of certainty that all your functionality works

Cons:Likely to go into more detail than user-journey based tests and, as such, be somewhat slower

View tests:

  • View tests have become more common with the rise of frameworks like Jasmine.
  • View tests help you to ensure that all the pages in your application render correctly, by making assertions about the state of the page’s HTML structure given a set of circumstances and data.
  • For example, you might verify that when you make a user’s profile data available to the view, that it is displayed in the way you expect, with the markup you expect.
  • View tests will help you make sure that your pages look good to users, and let you know when something is missing that should be displayed (or displayed when it shouldn’t be!).

Pros:Gives you a nice way to drive out features by asserting against what the user should see and experience in your app

Cons:Can sometimes be a little tricky to manipulate and assert against HTML nodes rather than data directly

Controller tests:

  • Across many web frameworks, particularly those that follow the MVC model, controllers are responsible for serving data to your views.
  • The role of controllers is often contested among developers. Some view them as mere messengers that should be kept simple, their only task to pipe data from the backend API to the view with minimal interference and complication.
  • Others view them as a powerful extra layer in your application, capable of performing necessary transformations on data before serving them up to the user.

Pros:Help ensure that the data being passed to or received from the view is correct

Cons:Some argue that controller tests should be limited because controller logic should be limited. This is commonly seen in the ‘fat models, skinny controllers’ argument

Integration tests:

  • Integration tests sit at the level above unit tests. Let’s say you have a function that performs some complex transformations on data.
  • You might have several unit tests to verify smaller functions you’ve written to help with the data transformation.
  • An integration test could be used to check the final result of these functions working in tandem, to verify that the output of all your work is correct.
  • Where unit tests strive to test things in isolation (a single method or function, for example), integration tests aim to test the end result of several functions, objects or classes working together to produce a result.
  • In part two of this series, I’ll dive into one of the most often misunderstood aspects of automated testing: mocks and stubs.

This ruby on rails tutorial page provides you the following key areas such as ruby , rail , ruby on rails , rail forum , ruby on rails tutorial , ruby tutorial , rails guides , rails tutorial , learn ruby , rails form_for , ruby rails , ruby class , what is ruby on rails , rails installer , ruby online , learn ruby on rails , ruby on rails jobs , rails find_by , install rails , easyrail , rubyonrails , link_to rails , ruby on rails developer , learn ruby the hard way , railscasts , ruby on rails examples , ruby on rails vs php , rails 4 , rails activerecord , rails generate , ruby and rails , ruby on rails download , install ruby on rails , ruby net http , what is rails , ruby app , ruby vs ruby on rails , ruby on rails windows , rails for zombies , ruby on rails book , ruby on rails development , ruby on rails ide , ruby on rails tutorial pdf

Related Searches to How to (Finally) Learn Test-Driven Development