The question that always arises is that why we should test a software/code? can't developers code like we need not to write test cases for it to ensure its correctness and quality.
The answer to above question is straight and simple and i.e Software developer is also a human being and he/she can also commit mistakes, we all commit mistakes, but some of those mistakes are unimportant and some of them are expensive or dangerous. So we need to cross check or test our code before committing it.
I'am sure after this above discussion you will never ask the same question that you were asking before that "Why we need to test software"
Testing With Rails:
So now as we know the answer of "Why we need to test software" we can move forward to have a quick look on the approaches with which we can test our code. Because i'am from rails background so i will discuss only in Context of Rails.
Ruby on Rails and automated testing go hand in hand. Ruby on Rails comes with a built-in test framework and its up to you to use it or prefer some other like Rspec, cucumber etc...
Basically there are two types of popular testing approaches Test-Driven Development(TDD) and Behaviour-Driven Development(BDD), both approaches are very much popular in rails community and helped lots of developers to make bug free softwares.
We will discuss both approaches with basic example in two separate blocks -:
Test-Driven Developmen(TDD) -:
Test-Driven Development is a developer practice that involves writing tests before writing the code being tested. Begin by writing a very small test for code that does not yet exist. Run the test, and, naturally, it fails. Now write just sufficient code to make that test pass.
As Once passes the test after that just notice the resulting design and refactor any duplication you see.
TDD basically test the object's internal structure means testing what an object is.
Not going into much details right now i will show you a simple example of TDD(Rspec) test case to get just an idea how it looks.
describe Order do
context "when first created" do
it "is empty" do
order = Order.new
The it() method creates an example of the behavior of a Order, with the context being that the Order was just created. The expression Order.should be_empty is self-explanatory
Running this code in a shell with the rspec command(which will see later) yields the following specification:
Order when first created
Add some more contexts and examples, and the resulting output looks even more like a specification for a Order object.
Order when first created
Order with 1 item
is not empty
includes that item
Rspec here does not mean a system, but specification of an object. With Rspec, you get the freedom to specify application behavior. Many do. Ideally, however, for specifying application behavior, we want something that communicates in broader strokes. And for that, we use 'Cucumber'.
The problem with testing an object’s internal structure is that we are testing what an object is instead of what it does. What an object does is significantly more important.
In comparison to TDD, BDD is when we write behavior and specification which drives our software development. In order to ensure high efficiency of BDD, it’s important that a software developer and either the product owner or a business analyst work in tandem while writing pending test cases in a plain text.
Once we acknowledge this, it changes the way we think about driving out code. We begin to think more about interactions between people and systems, or between objects than we do about the structure of the objects.
Going by BDD (Cucumber) approach, simple readable language is easier and more effective to describe Test scenarios like shown below:
some event occurs,
I expect some outcome.
Text descriptions of application features with example scenarios are well read by Cucumber. Besides, Cucumber enables automated interaction with the code being developed by using the scenario steps.
Here’s an example:
Feature: Pay electricity bill on-line
I don’t want to stand in a long queue just to pay my electricity bill.
Since I have a checking account with my bank, I would love to pay my electricity bill online and save my time for many other important things.
Scenario: Pay an electricity bill
Given checking account with $90
And a payee named XYZPayee
And an XYZPayee bill for $70
When I pay the XYZPayee bill
Then I should have $20 remaining in my checking account
And the payment of $70 to XYZPayee should be listed in Recent Payments
Now, you must understand that everything listed above is treated as documentation. Steps are being represented by the subsequent lines. Then, occurs interaction between these step definitions and the code being developed.
Cucumber then invokes as it moves ahead with reading in the scenario. If it doesn’t fit to your cognition yet, you must remember that the main motive is to figure out that the behavior of code with examples is well specified by both RSpec and Cucumber. These examples are programmatically tied to that code.
So, Cucumber was used to describe the behavior of application till now, whereas RSpec was used to describe the behavior of objects.