0% found this document useful (0 votes)
13 views60 pages

Unit Testing

The document provides an overview of unit testing using the MS Unit Testing Framework, detailing its importance, best practices, and common challenges. It covers the structure of unit tests, the use of assertions, and the significance of testing for expected and unexpected exceptions. Additionally, it introduces the concept of testing methodologies, including boundary conditions and inverse relationships, to enhance testing effectiveness.

Uploaded by

Pankaj Patil
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)
13 views60 pages

Unit Testing

The document provides an overview of unit testing using the MS Unit Testing Framework, detailing its importance, best practices, and common challenges. It covers the structure of unit tests, the use of assertions, and the significance of testing for expected and unexpected exceptions. Additionally, it introduces the concept of testing methodologies, including boundary conditions and inverse relationships, to enhance testing effectiveness.

Uploaded by

Pankaj Patil
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

Effective Unit Testing with

MS Unit Testing Framework

Pratian Technologies (India) Pvt. Ltd.


[Link]
Introduction to Unit Test

Topics
 What is Unit Testing?
 Typical Unit Testing Problems
 Best Practices for Effective Unit Testing
 Tool Demo
 Asserts
 Exceptions
 What to test for?
 RIGHT BICEP
 Characteristics of good testing
 Mocks and stubs
 Design and Testing

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Unit Testing
 Unit Testing is code that

 Is written by developers, for developers

 Exercises a small, specific area of functionality

 Helps “prove” that a piece of code does what the


developer expects it to do

 For example, you might delete a pattern of


characters from a string and then confirm that they
are gone

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Unit Testing
 Marick’s Four Quadrants of Unit Testing

Business Facing

Customer Exploratory
Tests Tests

Scalability
Programmer Performance
Tests Usability
Security

Technology Facing
Copyright © 2012 Pratian Technologies
[Link]
Unit Testing
Introduction to Unit Test

Unit Testing
 Unit Testing fits into the Programmer tests category
here

 It is not Acceptance Testing [Functional Testing]

 Nor is it Performance or Scalability Testing

 Used to test the code written by the user in-order to


ensure compliance with the requirement

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Unit Testing
 Why Unit Testing ?

 It will make your life easier

 Better code

 Better designs

 Code is easier to maintain later

 Confidence when you code

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Unit Testing
 Common Excuses for not testing

 I’m not a tester!

 It takes too much time.

 It takes too long to run the tests.

 I don’t know how to test it.

 I don’t really know what it is supposed to do, so I can’t test it.

 But it compiles! It doesn’t need tests.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Best Practices - Unit Testing


 Start your development activities by writing down a list of things
you want to test

 You will often think of a test while writing another one. When you
do, add it to the list.

 Review your list frequently

 Test-driven development (TDD) is a proven way of improving


quality*

 TDD’s main objective is to aid programmers and customers


during the development process with unambiguous requirements

 Use good tools

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Unit Testing

DEMO
(Sample implementation of
Microsoft Unit Test with Visual
Studio)

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Structuring Unit Tests


 Test Code follows a standard formula:

 Set up all conditions needed for testing (create any


required objects, allocate any needed resources, etc.)

 Call the method to be tested

 Verify that the tested functionality worked as expected

 Clean up after itself

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Structuring Unit Tests


 You write test code and compile it in the normal
fashion, as you would any other bit of source code in
your project

 When it’s time to execute the code, remember that


you never actually run the production code directly

 Instead, you run the test code, which in turn exercises


the production code under very carefully controlled
conditions

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Structuring Unit Tests


 For Example:

 If we have a method called CreateAccount()

 This method encapsulates the behavior and we can test


the method with a method named CreateSavingsAccount()

 Next test method can be CreateCurrentAccount()

 Tests have to be organized on the behaviors and not


necessarily individual methods

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Asserts
 There are some helper methods that assist us in
determining whether a method under test is performing
correctly or not

 Generically, we call all these helper methods assertions

 They let us assert that some condition is true; that two bits
of data are equal, or not, and so on

 These methods will report


• failures [that’s when the assertion is false]
• errors [that’s when we get an unexpected exception]

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Asserts
 Asserts are the fundamental building block for unit
tests;

 Unit library provides a number of different forms of


assert as static methods in the Assert class

 AreEqual
[Link](expected, actual [, string message])

 This is the most-often used form of assert


 Expected is a value you hope to see (typically hard-coded)
 Actual is a value actually produced by the code under test
 Message is optional that will be reported in case of failure

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Exceptions and Exception Testing


 We might be interested in two different kinds of
exceptions:
 Expected exceptions resulting from a test
 Unexpected exceptions from something that’s
gone horribly wrong

 Sometimes in a test, we want the method under test


to throw an exception

 Consider a method which will help us divide two


numbers

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Exceptions and Exception Testing


 If the second number is a zero, code is going to throw
an error informing us about DivideByZeroException

 If the method already has the code checking for the


second number being 0 and if so throw
DivideByZeroException, then we would like to check if
the method is throwing the same properly

 If exception is thrown, we can identify that in MSUnit


and the test would pass for given values [num2=0]

 In short – we are checking if a method is throwing the


expected exceptions

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Exceptions and Exception Testing


 If the method throws any other exception apart from
the one handled, then the test would give a negative
result

 Once the expected exception fires, any remaining


code in the test method will be skipped

 Unexpected exceptions, Unit Test will take care


accordingly

 It will give us the entire stack trace right down to the


bug itself

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Setup and Teardown


 Per-method Setup and Teardown

 Each test should run independently of every other test; this


allows you to run any individual test at any time, in any
order

 To accomplish this feat, you may need to reset some parts


of the testing environment in between tests, or clean up
after a test has run

 Unit Test lets you specify two methods to set up and then
tear down the environment per test using attributes

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Question time
Please try to limit the questions to the topics discussed during the session. Thank you.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Lab
 A person has properties to access their age, full
name, and cash balance.
 When instantiating a person, we should be able to
provide the first and last name, along with the age.
 The person's full name property should return the
specified first and last names with a space in-
between.
 When instantiating a person the cash balance should
be 100,000.
 The cash balance should be reduced by the amount
spent on car purchase.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Now that you know how to test, we need to look at
what to test; or more precisely, the kinds of things that
might need testing

 It can be hard to look at a method or a class and try to


come up with all the ways it might fail and to
anticipate all the bugs

 With enough experience, you start to get a feel for


those things that are “likely to break,” and can
effectively concentrate on testing in those areas

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 There are six specific areas to test that will help
strengthen your testing skills

 RIGHT BICEP

 Right — Are the results right?


 B — Are all the boundary conditions CORRECT?
 I — Can you check inverse relationships?
 C — Can you cross-check results using other means?
 E — Can you force error conditions to happen?
 P — Are performance characteristics within bounds?

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Right Result

 The first and most obvious area to test is simply to


see if the expected results are right—to validate the
results.

 You can use data from file or XML or database to


check

 If requirements are unclear, it can be verified with the


stake holders

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Boundary Conditions

 Identifying boundary conditions is one of the most valuable


parts of unit testing, because this is where most bugs
generally live—at the edges

 Some conditions you might want to think about:


 Totally bogus or inconsistent input values, such as a file
name of "!*W:X\&Gi/w>g/h#WQ@“

 Badly formatted data that is missing delimeters or


terminators, such as an e-mail address without a top-level
domain ("fred@foobar.")

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Empty or missing values (such as 0, 0.0, an empty string, an
empty array, or null), or missing in a sequence (such as a
missing TCP packet)

 Values far in excess of reasonable expectations, such as a


person’s age of 10,000 years or a password string with
10,000 characters in it

 Duplicates in lists that shouldn’t have duplicates

 Ordered lists that aren’t, and vice-versa. Try handing a pre-


sorted list to a sort algorithm, for instance—or even a
reverse-sorted list

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 An easy way to think of possible boundary conditions is to
remember the acronym CORRECT

Conformance - Does the value conform to an expected format?


For Example:
Email id has to be in the correct format
Password has to be minimum 6 characters and one alphabet

Ordering - Is the set of values ordered or unordered as appropriate?


For Example
If while registering an order for a new customer, customer details
have to be added and then order has to be registered and finally
order items have to be stored

Range — Is the value within reasonable minimum and maximum


values?
For Example
Check if the value entered for age is between 1 and a maximum
value of 150
To check for min and max budget to on a shopping cart portal
Copyright © 2012 Pratian Technologies
[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


Reference — Does the code reference anything external
that isn’t under direct control of the code itself?
For Example
In a web application before we show the account
summary, user has to be signed in

Existence — Does the value exist (e.g., is non-null,


nonzero,
present in a set, etc.)?
For Example
Verify if user account exists after logging in
Verify if account object is not null, for a withdrawal
operation

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


Cardinality — Are there exactly enough values? Zero –
one – n rule
For Example
Quiz will have questions. Min of 2 and max of 20
Quiz will have several of question references

Time (absolute and relative) — Is everything happening


in order? At the right time? In time?
For Example
Concurrency and synchronization to be taken care
Transfer of funds to outside banks only between
business hours

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Check Inverse Relationships

 Some methods can be checked by applying their logical


inverse

 For instance, you might check a method that


calculates a square root by squaring the result, and
testing that it is tolerably close to the original number:

[Test]
public void SquareRootUsingInverse() {
double x = [Link](4.0);
[Link](4.0, [Link](x*x).Within(0.0001));
}

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Check Inverse Relationships

 You might check that some data was successfully


inserted into a database, then search for it, and then
delete it.

 You might transfer money into an account, then


transfer the same amount out of the account.

 For any of these operations apply an “inverse” to see


if you get back to an original state

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Cross-check Using Other Means

 You might also be able to cross-check results of your


method using different means

 Usually there is more than one way to calculate some


quantity

 One would be used for production and we might pick the


other for testing

 This technique is especially helpful when there’s a proven,


known way of accomplishing the task that happens to be
too slow or too inflexible to use in production code

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Cross-check Using Other Means

[Test]
public void SquareRootUsingStd() {
double number = 3880900.0;
double root1 = [Link](number);
double root2 = [Link](number);
[Link](root2, [Link](root1).Within(0.0001));
}

 Separate pieces of data may be reported by objects of


different classes, but they still have to agree, and so
can be used to cross-check one another

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Force Error Conditions

 In the real world, errors happen

 Disks fill up, network lines drop, e-mail goes into a


black hole, and programs crash.

 You should be able to test that your code handles all


of these real world problems by forcing errors to occur

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Force Error Conditions

 Here are a few environmental things you could think


of
 Running out of memory
 Running out of disk space
 Issues with wall-clock time
 Network availability and errors
 Insufficient File or Path permissions
 System load
 Very high or very low video resolution

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

What do we Test for?


 Performance Characteristics

 One area that might prove beneficial to examine is


performance characteristics

 Not performance itself, but trends as input sizes grow, as


problems become more complex, and so on

 For example we might want to find out the time taken to


read from an xml file and update database for about 10000
employees

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Question time
Please try to limit the questions to the topics discussed during the session. Thank you.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Characteristics of good testing


 A-TRIP
 Automatic
 They should be automated
 Running continuously to test the code checked-in
 Avoid intervention of manual process
 Thorough
 Good unit tests are thorough
 Test everything that can break your code
 Estimate the depth of your test needed
 Repeatable
 Every test should be able to run over and over again, in
any order, and produce the same results
 Isolate the external dependencies like databases, global
variables

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Characteristics of good testing


 A-TRIP
 Independent
 Tests need to be kept neat and tidy
 Tightly focused, and independent from the environment
and each other [Other developers can also run the test]
 Testing only one thing at a time
 Tests should be on behavior and not the method
 One method can have many test cases
 Professional
 Maintained to same standards as your production code
 Test code is real code
 Might need larger code base than production code

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Characteristics of good testing


 Testing the tests

 Testing code to make sure it works is a great idea

 What happens when there are bugs in our test code ?

 Two things you can do to help ensure that the test code
is correct:
 Improve tests when fixing bugs
 Prove tests by introducing bugs

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Characteristics of good testing


 When a bug is found “in the wild” and reported back, that
means there’s a hole in the safety net—a missing test

 Four simple steps to tackle this


 Identify the bug, or bugs, that caused the errant behavior

 Write a test that fails, for each individual bug, to prove the
bug exists

 Fix the code such that the test now passes

 Verify that all tests still pass (i.e., you didn’t break anything
else as a result of the fix).

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Question time
Please try to limit the questions to the topics discussed during the session. Thank you.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Mocks and Stubs


 The objective of unit testing is to exercise just one
behavior at a time, but what happens when the method
containing that behavior depends on other things

 Hard-to-control things such as the network, or a database,


or even specialized hardware

 There’s a testing pattern that can help: mock objects

 A mock object is simply a testing replacement for a real-


world object

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Mocks and Stubs


 There are a number of situations that come up where
mock objects can help us

 The real object has nondeterministic behavior (it produces


unpredictable results, like a stock-market quote feed.)

 The real object is difficult to set up, like requiring a certain file
system, database, or network environment

 The real object has behavior that is hard to trigger (for example,
a network error)

 The real object is slow or doesn’t exist

 The real object has (or is) a user interface

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Mocks and Stubs


 Using mock objects, we can get around all of these
problems

 The three key steps to using mock objects for testing are:

 Use an interface to describe the relevant methods on the


object

 Implement the interface for production code

 Implement the interface in a mock object for testing

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Mocks and Stubs


 What we need to do is stub out

 In many cases, stubs just implement an interface and


return dummy values for the methods in said interface

 In even simpler cases, all the implemented methods in the


stub just throw a NotImplementedException

 A common scenario is when there is a class that


encapsulates database access, but we don’t want to
actually configure and populate a database to run simple
tests

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Question time
Please try to limit the questions to the topics discussed during the session. Thank you.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Unit testing offers several opportunities to improve the
design and architecture of your code as well

 Few important areas to consider are


 Designing for testability
 Refactoring for testing
 Testing the class invariant
 TDD – Test Driven Design
 Testing for invalid parameters

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Designing for testability

 “Separation of Concerns” is probably the single most


important concept in software design and implementation

 For example, suppose you are writing a method that


will sleep until the top of the next hour

public void SleepUntilNextHour() {


int howLong;
howLong= xxxxxxxxx;
Xxxxxxxxxx;
Xxxxxxxxxxxxxxx;
[Link](howLong);
return;
}
Copyright © 2012 Pratian Technologies
[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Designing for testability

 How do we test this?

 Do we wait for an hour? Set a timer and then call the


method and wait for it to return

 Instead of combining the calculation of how many


milliseconds to sleep with the Sleep() method itself,
split them up:
public void SleepUntilNextHour() {
int howlong = MilliSecondsToNextHour([Link]);
[Link](howlong);
return;
}

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Designing for testability

 Now we can test the methods separately

 MilliSecondsToNextHour() can be tested if it is giving the right


value

 SleepUntilNextHour() can be tested to see if the thread is put to


sleep mode properly

 [Link](10000, MilliSecondsToNextHour(DATE_1));

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Refactoring for testing

 Many a times we re-factor the code once it is tested or


even to accommodate unit testing

 If there is a method which is internally implementing many


different pieces of logic, then it becomes difficult to test

 When a test is run, it becomes difficult to know which piece


of code is actually resulting in an error

 We then give scope for re-factoring of code

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Refactoring for testing

 Consider a method to process an order RegisterOrder()


and has to send the total amount back for an invoice to be
generated

 If this method also has to calculate the discount based on


the type of member placing the order, then it would be
difficult to test for incorrect calculations for members

 So we divide the method into 2 RegisterOrder() and


GetDiscountForCustomer()

 Now these methods can be independently tested

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Testing the class Invariant

 A class invariant is an assertion, or some set of assertions, about


objects of a class

 For an object to be valid, all of these assertions must be true.


They cannot vary

 For instance, a class that implements a sorted list may have the
invariant that its contents are in sorted order

 That means that no matter what else happens, no matter what


methods are called, the list must always be in sorted order

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Testing the class Invariant

 Within a method, of course, the invariant may be momentarily


violated as the class performs whatever housekeeping is
necessary

 But by the time the method returns, or the object is otherwise


available for use (as in a multi-threaded environment), the
invariant must hold true or else it indicates a bug

 Possible areas where class invariants might apply


 Structural
 Mathematical
 Data Consistency

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Testing the class Invariant

 Structural
 The most common invariants are structural in nature
 For instance, in an order-entry system you might have
invariants such as:
 Every line item must belong to an order
 Every order must have one or more line items

 Mathematical
 Other constraints are more mathematical in nature
 Debits and credits on a bank account match the balance
 Amounts measured in different units match after conversion

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Testing the class Invariant

 Often an object may present the same data in different ways

 A list of items in a shopping cart

 The total amount of the sale and the total number of


items in the cart are closely related

 From a list of items with details, you can derive the other
two figures

 It must be an invariant, that these figures are consistent

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Test Driven Development - TDD

 Test-driven development is a valuable technique where you


always write the tests themselves before writing the methods
that they test

 You start with what user wants and that results in writing
classes that you need and not just because statements in
your requirement doc says

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Testing and Design


 Testing Invalid Parameters

 Is your class supposed to validate its parameters?

 Who’s responsible for validating input data?

 Depends on the project. If UI layer is handing at the


boundaries, you don’t need to at class level

 If not, then we need to handle at the class level

 Mission critical applications and confidential systems may


think about validating at both ends

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing
Introduction to Unit Test

Question time
Please try to limit the questions to the topics discussed during the session. Thank you.

Copyright © 2012 Pratian Technologies


[Link]
Unit Testing

You might also like