KEMBAR78
An introduction to unit testing | PDF
Intro to Unit Testing
Module Overview
1. Why Tests Are Important
2. The Different Types of Tests
3. What is a Unit Test
4. Your First Unit Test - Hello World
5. What to Unit Test
6. Benefits of Unit Tests
7. What is *not* a Unit Test
Why are people writing unit tests?
 They need to prove they are smart
 They want to charge more
 They want to spend more time
coding before they ship
 They like more lines of code on
their stats
 They want to look good in
code reviews
 ?
 ?
Credit Card Validation (F5)
Credit Card Validation (with Unit Tests)
Save Time: Avoid Debuggerment
Whenever you are tempted to type something into a print statement or a debugger
expression, write it as a test instead. - Fowler
Pay a little now
or
Pay a lot later
Why are people writing unit tests?
Why Write Tests?
Why Tests Are Important
 Tests Reduce Bugs in New Features
 Tests Reduce Bugs in Existing Features
 Tests Are Great Documentation
 Tests Improve Design
 Testing Makes Development Faster
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#WhyUnitTests
The Different Types of Tests
 Smoke Tests
 Unit Tests
 Integration Tests
 Functional / Acceptance Tests
 Load Tests
 Stress Tests
Do You Know the Different Types of
Tests
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTes
ts.aspx#TypesOfTests
What is a Unit Test
Our First Unit Test
[TestMethod]
public void TestCalculation()
{
var orderManager = new OrderManager();
using (var db = new NorthwindDataContext())
{
var order = db.Orders.FirstOrDefault();
var actual = orderManager.GetTotalIncGST(order);
var expected = order.OrderItems.Sum(oi => oi.Qty * price) * 1.1;
Assert.AreEqual(actual, expected);
}
}
“A unit test is a fast, in-memory, consistent, automated and
repeatable test of a functional unit-of-work in the system.”
“A unit of work is any functional scenario in the system that contains
logic. It can be as short as a function, or it can span multiple
classes and functions, and it provides internal or business value to
the system under test.”
“Art of Unit Testing” Roy Osherove
What is a Unit test?
What makes something a UNIT test ?
Small: Validates a single concern / unit of work
Repeatable: You can rerun the same test as many times
as you want.
Consistent: Every time you run it, you get the same
result.
In Memory: It has no “hard” dependencies on anything
not in memory (such as file system, databases, network)
Fast: It should take a fraction of a second to run a unit test.
Readable
 Understand!
 What? Scenario? Expectation?
Maintainable
 We change our application
Trustworthy
 All  The code covered by unit tests works as expected
Attributes of a good Unit test
What is wrong with this test?
[TestMethod]
public void TestCalculation()
{
var orderManager = new OrderManager();
using (var db = new NorthwindDataContext())
{
var order = db.Orders.FirstOrDefault();
var actual = orderManager.GetTotalIncGST(order);
var expected = order.OrderItems.Sum(oi => oi.Qty * price) * 1.1;
Assert.AreEqual(actual, expected);
}
}
Hello Unit Tests – Your First Test
[TestClass]
public class StringValidationTests
{
[TestMethod]
public void IsValidEmailAddress_ForValidEmail_ReturnsTrue()
{
string email = "adam@stephensen.com";
bool result = email.IsValidEmailAddress();
Assert.IsTrue(result);
}
Let’s write a test
public static class StringValidation
{
public static bool IsValidEmailAddress(this string txtEmail)
{
return false;
}
Red
public static class StringValidation
{
public static bool IsValidEmailAddress(this string email)
{
Regex r = new Regex(@"^[w-]+(?:.[w-]+)*@(?:[w-]+.)+[a-zA-Z]{2,7}$");
Match match = r.Match(email);
return match.Success;
}
Green
[TestClass]
public class StringValidationTests_MSTest
{
[TestMethod]
public void IsValidEmailAddress_ForValidEmail_ReturnsTrue()
{
string email = "adam@stephensen.com";
bool result = email.IsValidEmailAddress();
Assert.IsTrue(result);
}
[TestMethod]
public void IsValidEmailAddress_ForEmailWithoutAmpersand_ReturnsFalse()
{
string email = "adamstephensen.com";
var result = email.IsValidEmailAddress();
Assert.IsFalse(result);
}
}
Test Both Ways
NUnit Test Fixtures
[TestFixture]
public class StringValidationTests_Nunit
{
[TestCase("adam@domain.com",Description="Valid simple email")]
[TestCase("adam-stephensen@domain-name.com", Description = "Valid email can contain hyphens")]
[TestCase("adam.stephensen.more@domain.com.au", Description = "Valid email with >1 periods")]
public void IsValidEmailAddress_ForValidEmails_ReturnsTrue(string email)
{
bool result = email.IsValidEmailAddress();
Assert.IsTrue(result);
}
[TestCase("adam@domain&more.com", Description = "Invalid email containing ampersand")]
[TestCase("@domain&other.com", Description = "Invalid email with no text before @")]
[TestCase("adam@", Description = "Invalid email with no text after @")]
[TestCase("adam@domain", Description = "Invalid email with no period after @")]
[TestCase("adam-domain.com", Description = "Email does not contain @")]
[TestCase("adam.@domain.com", Description = "Email cannot contain period directly before @")]
[TestCase("adam@.domain.com", Description = "Email cannot contain period directly after @")]
[TestCase(".adam@domain.com", Description = "Email cannot start with period")]
[TestCase("adam@domain.com.", Description = "Email cannot end with period")]
public void IsValidEmailAddress_ForInvalidEmail_ReturnsFalse(string email)
{
var result = email.IsValidEmailAddress();
Assert.IsFalse(result);
}
}
What to Unit Test
Do You Know What Code To Unit
Test?
Unit tests should be written for:
Fragile Code - e.g. Regular Expressions -
see below
When errors can be difficult to spot - e.g.
Rounding, arithmetic, calculations - see
below
Unit tests should not be written for:
Generated Code
Private methods
Dependencies - e.g. Database Schema,
Datasets, Web Services - see below
Performance - e.g. Slow forms, Time
critical applications - see below
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#HowMany
Test Fragile Code
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#RegEx
Tests for Complex Code
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#Arithmetic
Tests are the Best Documentation
Static
Documentation is
Technical Debt !
Unit Tests add
value!
Test Your JavaScript
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#TestJavascript
Benefits of Unit Tests
 Isolate each part of the program and check that the individual
parts work
 Strict, written contract that the piece of code must satisfy
 Allows you to refactor code and make sure it still works
correctly (regression testing)
Benefits of Unit Tests (1)
 Simplifies integration
 Testing the parts of a program first, and then testing their
integration
 Provides documentation
 Clients and other developers can look at their unit tests to gain
a basic understanding of the APIs and determine how to use
the module to fit their needs
 Improve code quality
 Code that cannot be easily tested is not factored properly
Benefits of Unit Tests (2)
 Code with automated validation reduces the time spent
manually testing, manually debugging, and hunting for errors
 Writing tests as the code is written lets you fail fast (find errors
early). Bugs are cheaper/faster to fix the earlier they are found
 Unit testing lets you refactor safely, finding any regressions as
they are introduced
Unit Tests Save Time
What is NOT a Unit Test
Pop Quiz – What’s NQR ?
[TestMethod]
public void TestCalculation()
{
var orderManager = new OrderManager();
using (var db = new NorthwindDataContext())
{
var order = db.Orders.FirstOrDefault();
var actual = orderManager.GetTotalIncGST(order);
var expected = order.OrderItems.Sum(oi => oi.Qty
* price) * 1.1;
Assert.AreEqual(actual, expected);
}
}
1. What are we testing?
2. Database Access !
It talks to the database
It communicates across the network
It touches the file system
It cannot be run in isolation from any other unit test
It can't run at the same time as any of your other unit tests
You have to do special things to your environment to run it
(e.g. editing config files / registry settings)
You are not testing a class in isolation from other concrete classes
When is a test *not* a Unit test?
http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#DependenciesDB
What is it ?
If it’s not a unit test…..
 Test the Integration of multiple components
 UI, Business Layer, Database
 Not in memory
 Touches
 File system
 Registry
 Database
 Other shared resources
Integration test
Run much slower
 not run in-memory
Less consistent
 Dependent from external resources
Has side effects
Harder to prepare
 E.g. Database setup
Integration test
Great when writing code to integrate to 3rd party APIs
Great for finding out when there is a problem with a large
complex system (is it the code, the database or a dependency)
Great for ensuring availability of external components
(zsValidate)
Integration test
Different Levels of Attention
Unit tests – should ALWAYS pass.
- Should be run on every CI Build
Integration tests – will sometimes be red
- Should be excluded from CI Build
Module Summary
1. Why Tests Are Important
2. The Different Types of Tests
3. What is a Unit Test
4. Your First Unit Test
5. What to Unit Test
6. Benefits of Unit Tests
7. What is NOT a Unit Test
Unit Testing References
 Roy Osherove
 Book http://www.artofunittesting.com/
 Blog http://weblogs.asp.net/ROsherove/
 Unit test definition
http://weblogs.asp.net/ROsherove/archive/2009/09/28/unit-test-definition-2-0.aspx
 Michael Feathers
 Blog http://www.artima.com/weblogs/index.jsp?blogger=mfeathers
 What is not a unit test? http://www.artima.com/weblogs/viewpost.jsp?thread=126923
 Unit Testing Rules
http://www.artima.com/weblogs/viewpost.jsp?thread=126923
 http://www.slideshare.net/nickokiss/unit-testing-best-practices
http://www.nickokiss.com/2009/09/unit-testing.html

An introduction to unit testing

  • 1.
  • 2.
    Module Overview 1. WhyTests Are Important 2. The Different Types of Tests 3. What is a Unit Test 4. Your First Unit Test - Hello World 5. What to Unit Test 6. Benefits of Unit Tests 7. What is *not* a Unit Test
  • 3.
    Why are peoplewriting unit tests?  They need to prove they are smart  They want to charge more  They want to spend more time coding before they ship  They like more lines of code on their stats  They want to look good in code reviews  ?
  • 4.
     ? Credit CardValidation (F5)
  • 7.
    Credit Card Validation(with Unit Tests)
  • 8.
    Save Time: AvoidDebuggerment Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead. - Fowler
  • 9.
    Pay a littlenow or Pay a lot later Why are people writing unit tests?
  • 10.
  • 11.
    Why Tests AreImportant  Tests Reduce Bugs in New Features  Tests Reduce Bugs in Existing Features  Tests Are Great Documentation  Tests Improve Design  Testing Makes Development Faster http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#WhyUnitTests
  • 12.
  • 13.
     Smoke Tests Unit Tests  Integration Tests  Functional / Acceptance Tests  Load Tests  Stress Tests Do You Know the Different Types of Tests http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTes ts.aspx#TypesOfTests
  • 14.
    What is aUnit Test
  • 15.
    Our First UnitTest [TestMethod] public void TestCalculation() { var orderManager = new OrderManager(); using (var db = new NorthwindDataContext()) { var order = db.Orders.FirstOrDefault(); var actual = orderManager.GetTotalIncGST(order); var expected = order.OrderItems.Sum(oi => oi.Qty * price) * 1.1; Assert.AreEqual(actual, expected); } }
  • 16.
    “A unit testis a fast, in-memory, consistent, automated and repeatable test of a functional unit-of-work in the system.” “A unit of work is any functional scenario in the system that contains logic. It can be as short as a function, or it can span multiple classes and functions, and it provides internal or business value to the system under test.” “Art of Unit Testing” Roy Osherove What is a Unit test?
  • 17.
    What makes somethinga UNIT test ? Small: Validates a single concern / unit of work Repeatable: You can rerun the same test as many times as you want. Consistent: Every time you run it, you get the same result. In Memory: It has no “hard” dependencies on anything not in memory (such as file system, databases, network) Fast: It should take a fraction of a second to run a unit test.
  • 18.
    Readable  Understand!  What?Scenario? Expectation? Maintainable  We change our application Trustworthy  All  The code covered by unit tests works as expected Attributes of a good Unit test
  • 19.
    What is wrongwith this test? [TestMethod] public void TestCalculation() { var orderManager = new OrderManager(); using (var db = new NorthwindDataContext()) { var order = db.Orders.FirstOrDefault(); var actual = orderManager.GetTotalIncGST(order); var expected = order.OrderItems.Sum(oi => oi.Qty * price) * 1.1; Assert.AreEqual(actual, expected); } }
  • 20.
    Hello Unit Tests– Your First Test
  • 21.
    [TestClass] public class StringValidationTests { [TestMethod] publicvoid IsValidEmailAddress_ForValidEmail_ReturnsTrue() { string email = "adam@stephensen.com"; bool result = email.IsValidEmailAddress(); Assert.IsTrue(result); } Let’s write a test
  • 22.
    public static classStringValidation { public static bool IsValidEmailAddress(this string txtEmail) { return false; } Red
  • 23.
    public static classStringValidation { public static bool IsValidEmailAddress(this string email) { Regex r = new Regex(@"^[w-]+(?:.[w-]+)*@(?:[w-]+.)+[a-zA-Z]{2,7}$"); Match match = r.Match(email); return match.Success; } Green
  • 24.
    [TestClass] public class StringValidationTests_MSTest { [TestMethod] publicvoid IsValidEmailAddress_ForValidEmail_ReturnsTrue() { string email = "adam@stephensen.com"; bool result = email.IsValidEmailAddress(); Assert.IsTrue(result); } [TestMethod] public void IsValidEmailAddress_ForEmailWithoutAmpersand_ReturnsFalse() { string email = "adamstephensen.com"; var result = email.IsValidEmailAddress(); Assert.IsFalse(result); } } Test Both Ways
  • 25.
    NUnit Test Fixtures [TestFixture] publicclass StringValidationTests_Nunit { [TestCase("adam@domain.com",Description="Valid simple email")] [TestCase("adam-stephensen@domain-name.com", Description = "Valid email can contain hyphens")] [TestCase("adam.stephensen.more@domain.com.au", Description = "Valid email with >1 periods")] public void IsValidEmailAddress_ForValidEmails_ReturnsTrue(string email) { bool result = email.IsValidEmailAddress(); Assert.IsTrue(result); } [TestCase("adam@domain&more.com", Description = "Invalid email containing ampersand")] [TestCase("@domain&other.com", Description = "Invalid email with no text before @")] [TestCase("adam@", Description = "Invalid email with no text after @")] [TestCase("adam@domain", Description = "Invalid email with no period after @")] [TestCase("adam-domain.com", Description = "Email does not contain @")] [TestCase("adam.@domain.com", Description = "Email cannot contain period directly before @")] [TestCase("adam@.domain.com", Description = "Email cannot contain period directly after @")] [TestCase(".adam@domain.com", Description = "Email cannot start with period")] [TestCase("adam@domain.com.", Description = "Email cannot end with period")] public void IsValidEmailAddress_ForInvalidEmail_ReturnsFalse(string email) { var result = email.IsValidEmailAddress(); Assert.IsFalse(result); } }
  • 26.
  • 27.
    Do You KnowWhat Code To Unit Test? Unit tests should be written for: Fragile Code - e.g. Regular Expressions - see below When errors can be difficult to spot - e.g. Rounding, arithmetic, calculations - see below Unit tests should not be written for: Generated Code Private methods Dependencies - e.g. Database Schema, Datasets, Web Services - see below Performance - e.g. Slow forms, Time critical applications - see below http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#HowMany
  • 28.
  • 29.
    Tests for ComplexCode http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#Arithmetic
  • 30.
    Tests are theBest Documentation Static Documentation is Technical Debt ! Unit Tests add value!
  • 31.
  • 32.
  • 33.
     Isolate eachpart of the program and check that the individual parts work  Strict, written contract that the piece of code must satisfy  Allows you to refactor code and make sure it still works correctly (regression testing) Benefits of Unit Tests (1)
  • 34.
     Simplifies integration Testing the parts of a program first, and then testing their integration  Provides documentation  Clients and other developers can look at their unit tests to gain a basic understanding of the APIs and determine how to use the module to fit their needs  Improve code quality  Code that cannot be easily tested is not factored properly Benefits of Unit Tests (2)
  • 35.
     Code withautomated validation reduces the time spent manually testing, manually debugging, and hunting for errors  Writing tests as the code is written lets you fail fast (find errors early). Bugs are cheaper/faster to fix the earlier they are found  Unit testing lets you refactor safely, finding any regressions as they are introduced Unit Tests Save Time
  • 36.
    What is NOTa Unit Test
  • 37.
    Pop Quiz –What’s NQR ? [TestMethod] public void TestCalculation() { var orderManager = new OrderManager(); using (var db = new NorthwindDataContext()) { var order = db.Orders.FirstOrDefault(); var actual = orderManager.GetTotalIncGST(order); var expected = order.OrderItems.Sum(oi => oi.Qty * price) * 1.1; Assert.AreEqual(actual, expected); } } 1. What are we testing? 2. Database Access !
  • 38.
    It talks tothe database It communicates across the network It touches the file system It cannot be run in isolation from any other unit test It can't run at the same time as any of your other unit tests You have to do special things to your environment to run it (e.g. editing config files / registry settings) You are not testing a class in isolation from other concrete classes When is a test *not* a Unit test? http://www.ssw.com.au/ssw/standards/rules/RulesToBetterUnitTests.aspx#DependenciesDB
  • 39.
    What is it? If it’s not a unit test…..
  • 40.
     Test theIntegration of multiple components  UI, Business Layer, Database  Not in memory  Touches  File system  Registry  Database  Other shared resources Integration test
  • 41.
    Run much slower not run in-memory Less consistent  Dependent from external resources Has side effects Harder to prepare  E.g. Database setup Integration test
  • 42.
    Great when writingcode to integrate to 3rd party APIs Great for finding out when there is a problem with a large complex system (is it the code, the database or a dependency) Great for ensuring availability of external components (zsValidate) Integration test
  • 43.
    Different Levels ofAttention Unit tests – should ALWAYS pass. - Should be run on every CI Build Integration tests – will sometimes be red - Should be excluded from CI Build
  • 44.
    Module Summary 1. WhyTests Are Important 2. The Different Types of Tests 3. What is a Unit Test 4. Your First Unit Test 5. What to Unit Test 6. Benefits of Unit Tests 7. What is NOT a Unit Test
  • 45.
    Unit Testing References Roy Osherove  Book http://www.artofunittesting.com/  Blog http://weblogs.asp.net/ROsherove/  Unit test definition http://weblogs.asp.net/ROsherove/archive/2009/09/28/unit-test-definition-2-0.aspx  Michael Feathers  Blog http://www.artima.com/weblogs/index.jsp?blogger=mfeathers  What is not a unit test? http://www.artima.com/weblogs/viewpost.jsp?thread=126923  Unit Testing Rules http://www.artima.com/weblogs/viewpost.jsp?thread=126923  http://www.slideshare.net/nickokiss/unit-testing-best-practices http://www.nickokiss.com/2009/09/unit-testing.html