Test driven development (TDD), a software development method, helps build high quality applications faster. Life-cycle, usefulness, limitations and similar techniques of TDD have been presented in this slide deck.
2. What is TDD?
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, then
produces the minimum amount of code to pass that test, and finally refactors the new
code to acceptable standards. Kent Beck, who is credited with having developed or
'rediscovered' the technique, stated in 2003 that TDD encourages simple designs and
inspires confidence.
4. Development style
Keep the unit small
For TDD, a unit is most commonly defined as a class, or a group of related functions
often called a module. Keeping units relatively small is claimed to provide critical
benefits, including:
Reduced debugging effort – When test failures are detected, having smaller units aids
in tracking down errors.
Self-documenting tests – Small test cases are easier to read and to understand.
5. Similar Procedures
Acceptance test-driven development
Acceptance Test-Driven Development (ATDD) is a development methodology based
on communication between the business customers, the developers, and the testers.
ATDD encompasses many of the same practices as Specification by Example, Behavior
Driven Development (BDD), Example-Driven Development (EDD) and Story Test-
Driven Development (SDD). All these processes aid developers and testers in
understanding the customer’s needs prior to implementation and allow customers to
be able to converse in their own domain language.
6. Similar Procedures
Specification by example
Specification by example (SBE) is a collaborative approach to defining requirements
and business-oriented functional tests for software products based on capturing and
illustrating requirements using realistic examples instead of abstract statements. It is
applied in the context of agile software development methods, in particular behavior-
driven development. This approach is particularly successful for managing
requirements and functional tests on large-scale projects of significant domain and
organisational complexity.
7. Best practices
Test structure
Effective layout of a test case ensures all required actions are completed, improves the readability of the test case,
and smooths the flow of execution. Consistent structure helps in building a self-documenting test case. A commonly
applied structure for test cases has (1) setup, (2) execution, (3) validation, and (4) cleanup.
Setup: Put the Unit Under Test (UUT) or the overall test system in the state needed to run the test.
Execution: Trigger/drive the UUT to perform the target behavior and capture all output, such as return values and
output parameters. This step is usually very simple.
Validation: Ensure the results of the test are correct. These results may include explicit outputs captured during
execution or state changes in the UUT & UAT.
Cleanup: Restore the UUT or the overall test system to the pre-test state. This restoration permits another test to
execute immediately after this one.
8. Best practices
Practices to avoid or anti-patterns
● Having test cases depend on system state manipulated from previously executed test cases.
● Dependencies between test cases. A test suite where test cases are dependent upon each other is
brittle and complex. Execution order should not be presumed. Basic refactoring of the initial test
cases or structure of the UUT causes a spiral of increasingly pervasive impacts in associated tests.
● Interdependent tests. Interdependent tests can cause cascading false negatives. A failure in an early
test case breaks a later test case even if no actual fault exists in the UUT, increasing defect analysis
and debug efforts.
● Testing implementation details.
● Slow running tests.
9. Benefits
● Writing more tests leads to higher productivity.
● Programmers using Pure TDD rarely felt the need to invoke debugger.
● TDD can also drive the design of a program.
● Offers Ability to take small steps handling exceptions and error handling separately.
● Even though it requires more code, it limits defect throughout the application.
● Leads to more modularized, flexible and extensive code.
● It encourages to covers all branches and flows of an application to be thoroughly tested.
10. Limitations
● Can not provide sufficient testing for scenario such as user interfaces, programs that work
with databases, and some that depend on specific network configurations.
● Management support is essential.
● Misunderstanding requirements may lead to wrong test codes.
● A high number of passing unit tests may bring a false sense of security, resulting in fewer
additional software testing activities.
● Writing and maintaining an excessive number of tests costs time.
● The level of coverage and testing detail achieved during repeated TDD cycles cannot easily
be re-created at a later date.
11. Useful gems used for TDD in Rails
● Rspec
● FactoryGirl
● Fabricator
● Faker
● Shoulda Matchers
● Capybara
● Simplecov
12. Useful link for RSpec
● https://relishapp.com/rspec
● http://cheatrags.com/rspec-matchers
● http://cheatrags.com/capybara
● https://github.com/Tawhid007/Bookstore-Application-TDD (Application still in
progress)