TEST DRIVEN DEVELOPMENT John Walsh
May 06, 2015
TEST DRIVEN DEVELOPMENTJohn Walsh
2
Outline
Outline
1. Development Approaches
2. What is TDD
3. Code Refactoring
4. Steps to start TDD
5. What can be tested
6. How Does TDD Help
7. Unit Tests
8. Unit Test – Definitions
9. Code Coverage
10. Example
11. Visual Studio Unit Tests Walkthrough
3
Development Approaches
Ad hoc development Writing pseudo code first Model Driven Development (MDD) Test Driven Development (TDD)
4
What is TDD
Test-Driven Development (TDD) is a software development technique that involves
(repeatedly) first writing a test case and then implementing the code necessary to
excercise the test
(Test case First, Then Code)
In TDD:
Requirements => Tests => developement Code
Requirements drive the tests.
Tests drive the development of the application code.
No application code is written without writing a failing test first.
Tests are collected in a suite and the suite is run frequently, like every time after code is
written.
Test and code are written in elementary increments.
Refactoring is a continuous operation, and is supported by a passing battery of tests.
5
What is TDD
1. The developer writes an (initially failing) automated test case
2. that defines a desired requirement (improvement or new function) .
3. He then produces the minimum amount of code to pass that test
4. and finally refactors the new code to acceptable standards
6
What is TDD
TDD = Test First Development + Refactoring
• Add a Test + ensure it fails
• Write minimum amount of code to get it to pass
• Refractor code , all the while re-running tests to ensure they pass
Test should Initially Fail (and for expected reason)
7
Code Refactoring
Refactoring is a disciplined technique for restructuring an existing body of code, altering its internal structure without changing its external behaviour. Code Improvement
Refactoring Removes ‘code smell’ long methods,
duplicate code,
large classes
Refactoring techniques Breaking large methods up into smaller, reusable, more logical units
By breaking down code in smaller pieces, it is more easily understandable => less buggy + should be
Move part of code to new class
create more general types to allow for more code sharing
8
Steps to start TDD
1) Analyze the requirements + write the list of tasks or features
2) Pick a task or feature Brainstorm a list of tests for the task or feature
Review the tests list and pick a test
3) Write the test case
1) Write only enough code that the test case compiles
4) Run the test and see running the code fails
5) Write only enough code to just pass the test
6) Refactor the production code and eliminate duplication
7) Repeat
9
What can be tested
Valid inputs Invalid inputs Errors, exceptions, and events Boundary conditions Everything that could possibly break!
10
How Does TDD Help
Ensures that your design is clean by focusing on creation of operations that are callable
and testable
Shortens the programming feedback loop
Provides detailed specification through tests
Provides concrete evidence that your software works
The suite of unit tests provides constant feedback that each component is still working.
Supports evolutionary development.
The unit tests act as documentation that cannot go out-of-date, unlike separate
documentation, which can and frequently does.
The software tends to be better designed, that is, loosely coupled and easily maintainable,
because the developer is free to make design decisions and refactor at any time with
confidence that the software is still working. This confidence is gained by running the tests.
The need for a design pattern may emerge, and the code can be changed at that time.
11
TDD Advantages
TDD is good because it: Aids in understanding (and even defining) requirements
It’s a practice that adds reliability to the development process
Tests Improve Design
Testing Makes Development Faster, because less time is spent chasing bugs.
catch defects early in the development cycle (earlier is better)
Improves code quality because of the increased modularity, and continuous and relentless refactoring.
Decreases maintenance costs because the code is easier to follow.
Testing is “automated”
If the test fails, it's obvious where to look for the problem (if test written correctly i.e test one thing)
Reduces the number of bugs by orders of magnitude,
QA will receive functioning code (they can focus more on end to end and integration)
TDD promotes “small steps”, and lots of them
TDD is risk averse programming, investing work in the near term to avoid failures later on”Munjal Budhabhatti, The Architecture Journal 14
12
Unit Tests
General Definition:
A method of testing the correctness of a particular module of source code -Wikipedia
Testing a method in a class you are writing – while you are writing that class. Chris Donnan
13
Unit Test - Definitions
Test Fixture/ Test Class – A class with some unit tests in it.
Test (or Test Method) – a test implemented in a Test Class
Test Suite - A set of test grouped together
Test Harness/ Runner – The tool that actually executes the tests.
14
Code Coverage
Code Coverage is an approach or technique that sees you executing
[all] the statements and paths through your code-base
Which code has been touched by a test.
Identifies code that your tests missed
Thus, you should find bugs you may not otherwise have found, code coverage
“gives you clues”
Identifies code that does not have a test case exercising it
Code coverage can be a useful metric, but it must be used with care
Determine whether high code coverage is a good thing
Simply “touching” every line of code might not be suitable
Do not be sucked into “writing quick tests” just to improve coverage
15
The tools
NUnit 2.4.6 Testing framework for .NET
Graphical front-end (clear “black/white” pass/fail indicator)
NCover 1.5.8 “Do you know how much of your code is being tested”
Command-line
Creates an XML output file, XSL transformation for viewing
NCoverExplorer 1.4.0.7 Graphical front-end for NCover
Windows application that uses NCover’s XML output file
TestDriven.NET 2.11.2177 NUnit, NCover, NCoverage integration inside the Visual Studio IDE
Right-click context-sensitive menu
Free “liberal” personal edition; commercial Profession and Enterprise editions
16
Example
We want to develop a method that,
given two Integers,
returns an Integer that is the sum of
parameters.
17
Example (cont.)
Method Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
18
Example (cont.)
Method
public static Object sum(Integer i,
Integer j)
{
return new Object();
}
Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
19
Example (cont.)
Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
if (o instanceof Integer)
return true;
else
return false;
Method
public static Object sum(Integer i,
Integer j)
{
return new Object();
}
20
Example (cont.)
Method
public static Integer sum(Integer i,
Integer j)
{
return new Integer();
}
Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
if (o instanceof Integer)
return true;
else
return false;
21
Example (cont.)
Method
public static Integer sum(Integer i,
Integer j)
{
return new Integer();
}
Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
if (o instanceof Integer)
&& ((new Integer(7)).equals(o))
return true;
else
return false;
22
Example (cont.)
Method
public static Integer sum(Integer i,
Integer j)
{
return new Integer( i.intValue() + j.intValue());
);
}
Test
Integer i = new Integer(5);
Integer j = new Integer(2);
Object o = sum(i,j);
if (o instanceof Integer)
&& ((new Integer(7)).equals(o))
return true;
else
return false;
23
Questions
24
Visual Studio Unit Test WalkThroughUnit Test Overview
You can create unit tests by
1. using a code generation feature that creates the initial source code of the test,
2. or you can write the test completely by hand.
Either way, the test class and all test methods are identified by using programmatic attributes.
Programmatic Attributes (assigned automatically using ‘Code Generation’)• Each test class is marked with the [TestClass()] attribute
• Each unit test is a test method that is marked with the [TestMethod()] attribute.
The Unit Testing Framework provides many additional Assert classes and other classes that give you flexibility in writing unit test. The Microsoft.VisualStudio.TestTools.UnitTesting namespace supplies classes that
provide unit testing support.
Using unit tests, you can test not only public methods but private methods as well.
25
Visual Studio Unit Test WalkThroughCreating Unit Tests – Auto Generate
Select method in class you want to generate test for → Right-click on method name → Select ‘Create Unit Tests’
26
Method will be ‘checked’ in pop-up box (you can select other methods, I’ve also selected Credit method!) and click OK. You can click on settings to update some general setting for Test
(I’ve changed the Test file name to be more descriptive
Visual Studio Unit Test WalkThroughCreating Unit Tests – Auto Generate
27
1.A separate unit test is created for each method that you select in the Create Unit Test dialog box. (here we have unit tests for the Credit and Debit methods.
2.Each unit tests that is generated has empty variables and a placeholder Assert statement (the default is usually the Assert.Inconclusive statement.
•To make the test meaningful, you have to initialize the variables and replace the placeholder with an appropriate Assert statement.
3.When you first generate unit tests, a test project is created in your solution.
4.For each class you are testing, a separate unit test file is created. In this example, both of the methods we are testing belong to the same class. Therefore, there is only one unit test file, BankAccountTest.cs.
Visual Studio Unit Test WalkThroughCreating Unit Tests – Auto Generate
Each test class is marked with the[TestClass()] attribute
Each unit test is a test method that is marked with the [TestMethod()] attribute
28
Visual Studio Unit TestsCreating Unit Tests – Manually
To manually create a test, right click on Test project -> Add -> New Test
29
Visual Studio Unit TestsUpdating A Unit Test
Update Test Method to test desired functionality
Edit Generated Code To
30
Visual Studio Unit Tests Running Unit Tests
View and select test to run
Organise Tests into Groups/Lists
View Results of test run
31
Visual Studio Unit TestsConfigure Code Coverage
To see what proportion of your project's code is actually being tested, use the
code coverage feature of Microsoft Visual Studio 2010.
Double click on “Local.Testing” in the solution explorer, and select “Data And diagnostics”
1.Select ‘Code coverage’
2.Configure Items to include
3.Click Ok and then ‘Save as’ and replace existing ‘local.testing’ file
32
Visual Studio Unit TestsConfigure Code Coverage
Ensure ‘Active Test
Settings’ is set to
‘local.testsettings’
Run Tests in ‘Test List
Editor’
View Coverage Info in
‘Code coverage Results’
Window (viewable from Test-→ Windows →Code
Coverage Results)
33
Visual Studio Unit TestsConfigure Code Coverage
Code Coverage Results Window
34
Appendix – Assert Methods
Unit Test Framework => Microsoft.VisualStudio.TestTools.UnitTesting
Assert Methods
Inconclusive() : Indicates that the assertion cannot be verified.
Inconclusive(String) : Indicates that the assertion cannot be verified & display a message
AreEqual(Object, Object)
AreNotEqual(Object, Object)
AreNotSame(Object, Object) :Ref comparison
IsTrue(Boolean)
IsFalse(Boolean)
IsNull(Object)
IsNotNull(Object)
35
Appendix – Test Attributes
Unit Test Framework => Attributes
[TestClass()] : identify class that contains Test method
[TestMethod()] : identify Test method
[TestInitialize()] : identifies method that will be run before each test
[TestCleanup()] : identifies method that will be run after each test
[ExpectedException(exceptionType)] : Indicates that an exception is expected during test
method execution. (The test method will pass if the expected exception is thrown.)
See “Microsoft.VisualStudio.TestTools.UnitTesting Namespace” for list of attributes http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting(v=vs.100).aspx
36
References Microsoft (VS 2010): Walkthrough: Creating and Running Unit Tests
http://msdn.microsoft.com/en-us/library/ms182532(v=vs.100).aspx
Microsoft (VS 2010) : Walkthrough: Run Tests and View Code Coverage
http://msdn.microsoft.com/en-us/library/ms182534(v=vs.100).aspx
Microsoft (VS 2008) : Walkthrough: Working with Unit Tests
http://msdn.microsoft.com/en-us/library/ms182515(v=vs.90).aspx
Microsoft (VS 2008) : Guidelines for Test-Driven Development
http://msdn.microsoft.com/en-US/library/aa730844(v=VS.80).aspx