0% found this document useful (0 votes)
5 views

07 Test-Driven Development

Test-Driven Development (TDD) is a software development process that emphasizes writing tests before coding, ensuring that unit tests are always functional in deployed code. TDD enhances software quality by promoting responsibility among developers, facilitating better understanding of software behavior, and allowing for quick feedback. The Test Anything Protocol (TAP) is a standard format for managing and reporting test results, making it easier to communicate failures and gaps in testing across different programming languages.

Uploaded by

sahan ruwanga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

07 Test-Driven Development

Test-Driven Development (TDD) is a software development process that emphasizes writing tests before coding, ensuring that unit tests are always functional in deployed code. TDD enhances software quality by promoting responsibility among developers, facilitating better understanding of software behavior, and allowing for quick feedback. The Test Anything Protocol (TAP) is a standard format for managing and reporting test results, making it easier to communicate failures and gaps in testing across different programming languages.

Uploaded by

sahan ruwanga
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Test-Driven Development

302CEM
Test-Driven Development
Test-Driven Development (TDD)
Write the test before you write the code!
Use tests to communicate unusual circumstances in which the code should work.
Unit tests written by the developer.
Unit tests must always work at 100% in deployed code.
What is TDD?
Software Development process
Writing tests before the program
Writing enough code to satisfy the test
Refactoring
This leads to
First think about how to use the component
Next how to implement it
TDD enhances development
Components are easy to test and adapt
Why Use TDD?
Developers taking responsibility for the quality of their code, testing really isn't the
point, the point here is about
Responsibility, when you say it's done... is it done?
Can you go to sleep at night knowing the software that you've finished today
works and will help and isn't going to take anything away from people, that's the
point of developer testing...” (K. Beck, 2008)
Benefit of TDD

Why TDD?
Exam Question

Thinking about what is the goal first and then the implementations
Better understand the software behavior
Get quick feedback whether the software works
There is no code without a test
Use the written test as regression tests
More courage to refactor
Can save lots of time
How TDD Work

The TDD Process Exam question

Each new feature begins with writing a series of tests.


The developer must clearly understand the user story to understand the
requirements and exception conditions.
Tests are typically written in the same language as the code to be tested and are
organised into suites.
Tests are then run using a test harness to make sure they fail.
Code is then written to make the tests pass.
The code is refactored to improve performance and readability.
Need to remember
Blind-Spots
If tests written by the developer of the code being tested:
Share the same blind spots
Increased chance of bugs

Solutions:
Tests written by a different person
Implement pair programming
TDD and Feature Branches
Unit tests are part of the feature development
Keep the tests with the code
Branch should contain both tests and code
Merge will bring both the code and tests into the develop branch
TDD and Bug-Fixing
Is the bug reproducible?
If not it can't be fixed
Write unit tests to reproduce the bug
Once the tests pass the bug is squashed
Merge the new unit tests and fixed code
Resolving Interdependencies
Module Dependency Challenges
Data Fare API
Persistence Calculation Interaction

Data Fare API


Persistence Calculation Interaction
Tests Tests Tests
Testing Mocks
Data Fare API
Persistence Calculation Interaction

Data Fare API


Persistence Calculation Interaction
Tests Tests Tests
Handling Dependencies
Some classes may reference other classes
Means testing a class can frequently spill over into testing another class
A common example of this is classes that depend on a database
Simple solution is for the tester to writes code that interacts with the database
But a unit test should usually not go outside of its own class boundary
Should not cross such process/network boundaries
Crossing such unit boundaries turns unit tests into integration tests
Which component is causing the failure?
Solving Interdependencies
Reduce the net effective coupling:
Create an abstract interface around the dependency
Implement the interface with a mock object
Improves Independence of each module:
can be more thoroughly tested
Results in a higher-quality unit
More maintainable.
Global Data
Remember that the order in which your test methods run is not guaranteed.
If one of your tests changes the values of global variables, those changes may or
may not have been performed when some other test is run.
In order to test successfully, you need to restore all global variables to their initial
state before each test.
The Problem
Unit tests should never connect to a database
They should test a single unit of code each (a method) in total isolation
If they don't, then they are not a unit test.
Benefits of Not Unit Testing Databases
Tests run orders of magnitude faster
Feedback loop becomes instant
Tests can be run in parallel Remember
Tests don't need a running database
Takeaway
It is important to minimise (or ideally eliminate) inter-module dependencies to
ensure that each module can be testing in isolation
Test Anything Protocol (TAP)
Just Reminder
The Challenge
There are a number of test execution engines
These run the tests in the test script repository
Test result data needs to be in a usable format
Need to:
Communicate the failed tests to the developer
Identify where there are gaps in testing
Produce live project documentation.
What is TAP?
There are two steps in unit testing:
Test execution and raw data generation
Test management and reporting
TAP is a standard text data format that can be understood by both steps
Originally developed for unit testing of the Perl interpreter in 1987.
How Does TAP Work
The Test Anything Protocol is language agnostic and separates the test execution
and raw data generation from the test management and reporting
TAP Producer
The test execution engine runs the test scripts and prints the results to stdout
(the screen)
TAP Parser
A tool that parses data in the TAP format this output and generates useful
reports.
Test Execution Engine TAP Support
Most test execution engines can generate TAP output:
Some use this as their native format (such as tape)
Some require a plugin (called a reporter) to convert the default test data
output into the TAP format.
The TAP Format
TAP is a text format
Reports consist of several parts:
The version of TAP being used (normally 13)
Body with one or more lines for each test
Failed tests include a comment block to explain the failure
A footer containing:
The number of tests in the suite
a short summary of the tests.
Using a TAP Parser
Tap producer sends output to stdout (defaults to the shell)
Use Linux pipes to send this to the TAP parser
Most parsers also output to stdout
Can be redirected to a file if needed.
$ node spec/testRunnerTAP.js | node_modules/.bin/faucet > testReport.txt
TAP Support
Python tappy
NodeJS node-tap module
Java tap4j
iOS XCTest
Takeaway
The TAP protocol is a standard text format that allows a TAP producer (typically a
test execution engine to pass data to any TAP parser (to render the results in a
variety of formats)
Most test execution engines can export the TAP format either natively or through
the use of a reporter
By using a standard format, data can be piped from any TAP producer to and TAP
parser regardless of the programming languages used.

You might also like