Unit Testing Fundamentals and NUnit Svetlin Nakov National Academy for Software Development academy.devbg.org Veselin Georgiev National Academy for Software.

Slides:



Advertisements
Similar presentations
11-Jun-14 The assert statement. 2 About the assert statement The purpose of the assert statement is to give you a way to catch program errors early The.
Advertisements

Introduction to Unit Testing Svetlin Nakov Telerik Corporation
What is Unit Testing? How TDD Works? Tsvyatko Konov Telerik Corporation
FIT FIT1002 Computer Programming Unit 19 Testing and Debugging.
Well-behaved objects 4.0 Testing. 2 Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling Main concepts to.
JUnit. What is unit testing? A unit is the smallest testable part of an application. A unit test automatically verifies the correctness of the unit. There.
JUnit, Revisited 17-Apr-17.
JUnit. Why is testing good? Due to psychological factors, programmers are bad testers. A computer can test much faster than a human Philosophy: “If it.
Unit testing C# classes “If it isn’t tested it doesn’t work” Unit testing C# classes1.
14-Jul-15 JUnit 4. Comparing JUnit 3 to JUnit 4 All the old assertXXX methods are the same Most things are about equally easy JUnit 4 makes it easier.
Test-Driven Development With Visual Studio 2005 Erno de Weerd Info Support.
TDD,BDD and Unit Testing in Ruby
Unit Testing & Defensive Programming. F-22 Raptor Fighter.
Introduction 01_intro.ppt
Test Driven Development TDD. Testing ”Testing can never demonstrate the absence of errors in software, only their presence” Edsger W. Dijkstra (but it.
SENG 403, Winter 2012 SENG 403 – Winter  Exploring unit-testing frameworks in.NET  Writing our first test with NUnit  Unit Testing in Visual.
Testing. What is Testing? Definition: exercising a program under controlled conditions and verifying the results Purpose is to detect program defects.
Introduction to Unit Testing Jun-Ru Chang 2012/05/03.
Computer Science and Engineering College of Engineering The Ohio State University JUnit The credit for these slides goes to Professor Paul Sivilotti at.
Unit and Functional Testing Your Flex Applications Mike Nimer Dir. Of Engineering nomee.com.
Unit Testing and Mocking
Chapter 1: A First Program Using C#. Programming Computer program – A set of instructions that tells a computer what to do – Also called software Software.
Testing CSE 140 University of Washington 1. Testing Programming to analyze data is powerful It’s useless if the results are not correct Correctness is.
Unit Testing Continuous Integration PYUNIT AND JENKINS FRAMEWORK Presenter Rachita Agasthy.
Code Correctness, Readability, Maintainability Telerik Software Academy Telerik School.
Building Rock-Solid Software Nikolay Kostov Telerik Software Academy academy.telerik.com Senior Software Developer and Technical Trainer
Test Driven Development Arrange, Act, Assert… Awesome Jason Offutt Software Engineer Central Christian Church
Dr. Tom WayCSC Testing and Test-Driven Development CSC 4700 Software Engineering Based on Sommerville slides.
Testing in NetBeans. SWC Testing The ideal test: When the test is passed, the product is ready for delivery! Ideal – but (almost) impossible –Number of.
DEBUGGING. BUG A software bug is an error, flaw, failure, or fault in a computer program or system that causes it to produce an incorrect or unexpected.
Unit Testing Building Rock-Solid Software SoftUni Team Technical Trainers Software University
Unit Testing 101 Black Box v. White Box. Definition of V&V Verification - is the product correct Validation - is it the correct product.
1.  Writing snippets of code that try to use methods (functions) from your program.  Each snippet should test one (and only one) function......by calling.
Well-behaved objects Main concepts to be covered Testing Debugging Test automation Writing for maintainability Objects First with Java - A Practical.
A Practical Guide To Unit Testing John E. Boal TestDrivenDeveloper.com.
(1) Unit Testing and Test Planning CS2110: SW Development Methods These slides design for use in lab. They supplement more complete slides used in lecture.
Unit Testing with JUnit and Clover Based on material from: Daniel Amyot JUnit Web site.
Unit Tests Руслан Трифонов Omegasoft Ltd.. Съдържание 1.Въведение 2.Unit test patterns 2.1. Pass/fail patterns 2.2. Collection management patterns 2.3.
1 CSCD 326 Data Structures I Software Design. 2 The Software Life Cycle 1. Specification 2. Design 3. Risk Analysis 4. Verification 5. Coding 6. Testing.
CPSC 873 John D. McGregor Session 9 Testing Vocabulary.
1 Presentation Title Test-driven development (TDD) Overview David Wu.
Unit Testing in JavaScript with Mocha, Chai and Karma SoftUni Team Technical Trainers Software University
Testing CSE 160 University of Washington 1. Testing Programming to analyze data is powerful It’s useless (or worse!) if the results are not correct Correctness.
CPSC 871 John D. McGregor Module 8 Session 1 Testing.
Unit Testing Building Rock-Solid Software Svetlin Nakov Technical Trainer Software University
Unit testing Java programs1 Unit testing Java programs Using JUnit 4 “If it isn't tested, it doesn’t work”
PROGRAMMING TESTING B MODULE 2: SOFTWARE SYSTEMS 22 NOVEMBER 2013.
Unit Testing. F-22 Raptor Fighter Manufactured by Lockheed Martin & Boeing How many parts does the F-22 have?
Well-behaved objects Main concepts to be covered Testing Debugging Test automation Writing for maintainability Objects First with Java - A Practical.
Defensive Programming. Good programming practices that protect you from your own programming mistakes, as well as those of others – Assertions – Parameter.
CS223: Software Engineering Lecture 19: Unit Testing.
Northwest Arkansas.Net User Group Jay Smith Tyson Foods, Inc. Unit Testing nUnit, nUnitAsp, nUnitForms.
Microsoft Visual C# 2010 Fourth Edition Chapter 3 Using GUI Objects and the Visual Studio IDE.
Unit testing with NUnit Anne Lam & Chris James CMPS 4113 – Software Engineering April 15, 2015.
Software Engineering Lecture 11 Software Testing Presenter: Josef Hallberg 1.
CPSC 372 John D. McGregor Module 8 Session 1 Testing.
Unit Testing.
Building Rock-Solid Software
Test-driven development
John D. McGregor Session 9 Testing Vocabulary
Introduction to Unit Testing in JavaScript
Test Driven Development 1 November Agenda  What is TDD ?  Steps to start  Refactoring  TDD terminology  Benefits  JUnit  Mocktio  Continuous.
Testing and Debugging.
John D. McGregor Session 9 Testing Vocabulary
Unit testing C# classes
John D. McGregor Session 9 Testing Vocabulary
Component Testing (Unit Testing)
Testing and Test-Driven Development CSC 4700 Software Engineering
CS 240 – Advanced Programming Concepts
Defensive Programming
Presentation transcript:

Unit Testing Fundamentals and NUnit Svetlin Nakov National Academy for Software Development academy.devbg.org Veselin Georgiev National Academy for Software Development academy.devbg.org

ContentsContents 1.Unit Testing Fundamentals Some factsSome facts Why unit tests?Why unit tests? 2.Unit Testing Patterns 3.NUnit Testing Framework AssertionsAssertions AttributesAttributes NUnit GUI ApplicationNUnit GUI Application Unit Testing Best PracticesUnit Testing Best Practices 1.Unit Testing Fundamentals Some factsSome facts Why unit tests?Why unit tests? 2.Unit Testing Patterns 3.NUnit Testing Framework AssertionsAssertions AttributesAttributes NUnit GUI ApplicationNUnit GUI Application Unit Testing Best PracticesUnit Testing Best Practices

DefinitionDefinition A unit test is a piece of code written by a developer that exercises a very small, specific area of functionality of the code being tested. “Program testing can be used to show the presence of bugs, but never to show their absence!” - Edsger Dijkstra, [1972]

Unit Test Example int Sum(int[] array) { sum = 0; for (int i=0; i<array.Length; i++) sum += array[i]; return sum; } void TestSum() { if (Sum(new int[]{1,2}) != 3) throw new TestFailedException("1+2 != 3"); if (Sum(new int[]{-2}) != -2) throw new TestFailedException("-2 != -2"); if (Sum(new int[]{}) != 0) throw new TestFailedException("0 != 0"); }

Some Facts Tests are specific pieces of codeTests are specific pieces of code Unit testing framework is neededUnit testing framework is needed NUnit, MbUnit, VS Unit Testing FrameworkNUnit, MbUnit, VS Unit Testing Framework Unit tests are written by developers for developersUnit tests are written by developers for developers Unit tests are released into the code repository along with the code they testUnit tests are released into the code repository along with the code they test

All classes should be testedAll classes should be tested All methods should be testedAll methods should be tested Trivial code may be omittedTrivial code may be omitted E.g. property getters and settersE.g. property getters and setters Ideally all unit tests should pass before check-inIdeally all unit tests should pass before check-in All classes should be testedAll classes should be tested All methods should be testedAll methods should be tested Trivial code may be omittedTrivial code may be omitted E.g. property getters and settersE.g. property getters and setters Ideally all unit tests should pass before check-inIdeally all unit tests should pass before check-in More Facts

Write code Write unit test Run and succeed Code and Test Approach Time flow

Pick а test Compile and Fail Write code to pass test Write enough code to compile Run test and fail Create a test list Test Driven Development Time flow Write test Remove duplication

Why Test Driven Development? Helps find design issues early and avoids reworkHelps find design issues early and avoids rework Writing code to satisfy a test is a focused activity – less chance of errorWriting code to satisfy a test is a focused activity – less chance of error Tests will be a more comprehensive than when written after codeTests will be a more comprehensive than when written after code Helps find design issues early and avoids reworkHelps find design issues early and avoids rework Writing code to satisfy a test is a focused activity – less chance of errorWriting code to satisfy a test is a focused activity – less chance of error Tests will be a more comprehensive than when written after codeTests will be a more comprehensive than when written after code

Unit tests dramatically decrease the number of defects in the codeUnit tests dramatically decrease the number of defects in the code Unit tests improve designUnit tests improve design Unit tests are good documentationUnit tests are good documentation Unit tests reduce the cost of changeUnit tests reduce the cost of change Unit tests allow refactoringUnit tests allow refactoring Unit tests decrease the defect-injection rate due to refactoring/changesUnit tests decrease the defect-injection rate due to refactoring/changes Unit tests dramatically decrease the number of defects in the codeUnit tests dramatically decrease the number of defects in the code Unit tests improve designUnit tests improve design Unit tests are good documentationUnit tests are good documentation Unit tests reduce the cost of changeUnit tests reduce the cost of change Unit tests allow refactoringUnit tests allow refactoring Unit tests decrease the defect-injection rate due to refactoring/changesUnit tests decrease the defect-injection rate due to refactoring/changes Why Unit Tests?

Unit Testing Patterns

Unit test patterns cover broad aspects of developmentUnit test patterns cover broad aspects of development May promote unit testing to become a more formal engineering disciplineMay promote unit testing to become a more formal engineering discipline Helps identify the kind of unit tests to write, and its usefulnessHelps identify the kind of unit tests to write, and its usefulness Allows developer to choose how detailed the unit tests need to beAllows developer to choose how detailed the unit tests need to be Unit test patterns cover broad aspects of developmentUnit test patterns cover broad aspects of development May promote unit testing to become a more formal engineering disciplineMay promote unit testing to become a more formal engineering discipline Helps identify the kind of unit tests to write, and its usefulnessHelps identify the kind of unit tests to write, and its usefulness Allows developer to choose how detailed the unit tests need to beAllows developer to choose how detailed the unit tests need to be

Unit Testing Patterns Categorization Pass/fail patternsPass/fail patterns Collection management patternsCollection management patterns Data driven patternsData driven patterns Performance patternsPerformance patterns Process patternsProcess patterns Simulation patternsSimulation patterns Multithreading patternsMultithreading patterns Pass/fail patternsPass/fail patterns Collection management patternsCollection management patterns Data driven patternsData driven patterns Performance patternsPerformance patterns Process patternsProcess patterns Simulation patternsSimulation patterns Multithreading patternsMultithreading patterns

Unit Testing Patterns Categorization (2) Stress test patternsStress test patterns Presentation layer patternsPresentation layer patterns Overview of all patterns can be found at:Overview of all patterns can be found at: ure/autp5.aspx ure/autp5.aspx Stress test patternsStress test patterns Presentation layer patternsPresentation layer patterns Overview of all patterns can be found at:Overview of all patterns can be found at: ure/autp5.aspx ure/autp5.aspx

Unit Testing Frameworks and NUnit

Unit Testing Frameworks JUnit – first Unit Testing FrameworkJUnit – first Unit Testing Framework Based on JavaBased on Java Unit Testing Frameworks have been developed for a broad range of computer languagesUnit Testing Frameworks have been developed for a broad range of computer languages NUnit – for C# and all.NET languagesNUnit – for C# and all.NET languages cppUnit, jsUnit, PhpUnit, PerlUnit,...cppUnit, jsUnit, PhpUnit, PerlUnit,... JUnit – first Unit Testing FrameworkJUnit – first Unit Testing Framework Based on JavaBased on Java Unit Testing Frameworks have been developed for a broad range of computer languagesUnit Testing Frameworks have been developed for a broad range of computer languages NUnit – for C# and all.NET languagesNUnit – for C# and all.NET languages cppUnit, jsUnit, PhpUnit, PerlUnit,...cppUnit, jsUnit, PhpUnit, PerlUnit,...

AssertionsAssertions Predicate is a true–false statementPredicate is a true–false statement Assertion is a predicate placed in a program codeAssertion is a predicate placed in a program code Indicates that the developer thinks that the predicate is always true at that placeIndicates that the developer thinks that the predicate is always true at that place If an assertion fails, the method call does not return and an error is reportedIf an assertion fails, the method call does not return and an error is reported Predicate is a true–false statementPredicate is a true–false statement Assertion is a predicate placed in a program codeAssertion is a predicate placed in a program code Indicates that the developer thinks that the predicate is always true at that placeIndicates that the developer thinks that the predicate is always true at that place If an assertion fails, the method call does not return and an error is reportedIf an assertion fails, the method call does not return and an error is reported

NUnit – Features Test code is annotated using custom attributesTest code is annotated using custom attributes Two execution interfacesTwo execution interfaces GUI: nunit-gui.exeGUI: nunit-gui.exe Console: nunit-console.exeConsole: nunit-console.exe NUnit provides:NUnit provides: Creating and running tests as NUnit Test ProjectsCreating and running tests as NUnit Test Projects Visual Studio supportVisual Studio support Test code is annotated using custom attributesTest code is annotated using custom attributes Two execution interfacesTwo execution interfaces GUI: nunit-gui.exeGUI: nunit-gui.exe Console: nunit-console.exeConsole: nunit-console.exe NUnit provides:NUnit provides: Creating and running tests as NUnit Test ProjectsCreating and running tests as NUnit Test Projects Visual Studio supportVisual Studio support

NUnit – Attribute Listing [TestFixture][TestFixture] [TestFixtureSetUp][TestFixtureSetUp] [TestFixtureTearDown][TestFixtureTearDown] [Test][Test] [SetUp][SetUp] [TearDown][TearDown] [ExpectedException(typeof(Exception ))][ExpectedException(typeof(Exception ))] [Ignore("message")][Ignore("message")] [TestFixture][TestFixture] [TestFixtureSetUp][TestFixtureSetUp] [TestFixtureTearDown][TestFixtureTearDown] [Test][Test] [SetUp][SetUp] [TearDown][TearDown] [ExpectedException(typeof(Exception ))][ExpectedException(typeof(Exception ))] [Ignore("message")][Ignore("message")]

NUnit – Attributes [TestFixture] – Marks a class that contains tests[TestFixture] – Marks a class that contains tests Should be a public classShould be a public class Must have a default constructorMust have a default constructor [Test] – Marks a method as a unit test[Test] – Marks a method as a unit test [TestFixtureSetUp] – Indicates a setup method that will be ran once before all other tests[TestFixtureSetUp] – Indicates a setup method that will be ran once before all other tests Called before the tests are startedCalled before the tests are started [TestFixture] – Marks a class that contains tests[TestFixture] – Marks a class that contains tests Should be a public classShould be a public class Must have a default constructorMust have a default constructor [Test] – Marks a method as a unit test[Test] – Marks a method as a unit test [TestFixtureSetUp] – Indicates a setup method that will be ran once before all other tests[TestFixtureSetUp] – Indicates a setup method that will be ran once before all other tests Called before the tests are startedCalled before the tests are started

NUnit – Attributes (2) [TestFixtureTearDown] – Indicates a tear down method that will be ran once after all other tests have run[TestFixtureTearDown] – Indicates a tear down method that will be ran once after all other tests have run Called after all the tests have finishedCalled after all the tests have finished [SetUp] – Indicates a setup method that should be ran before each of the tests[SetUp] – Indicates a setup method that should be ran before each of the tests [TearDown] – Indicates a tear down method that should be ran after each of the tests[TearDown] – Indicates a tear down method that should be ran after each of the tests [TestFixtureTearDown] – Indicates a tear down method that will be ran once after all other tests have run[TestFixtureTearDown] – Indicates a tear down method that will be ran once after all other tests have run Called after all the tests have finishedCalled after all the tests have finished [SetUp] – Indicates a setup method that should be ran before each of the tests[SetUp] – Indicates a setup method that should be ran before each of the tests [TearDown] – Indicates a tear down method that should be ran after each of the tests[TearDown] – Indicates a tear down method that should be ran after each of the tests

NUnit – Attributes (3) [ExpectedException(typeof(Except ion))][ExpectedException(typeof(Except ion))] When you expect an exception to be thrownWhen you expect an exception to be thrown Will only pass if exception type was thrownWill only pass if exception type was thrown [Ignore("Not ready")] – Indicates a test that is not ready, or should not be run[Ignore("Not ready")] – Indicates a test that is not ready, or should not be run [ExpectedException(typeof(Except ion))][ExpectedException(typeof(Except ion))] When you expect an exception to be thrownWhen you expect an exception to be thrown Will only pass if exception type was thrownWill only pass if exception type was thrown [Ignore("Not ready")] – Indicates a test that is not ready, or should not be run[Ignore("Not ready")] – Indicates a test that is not ready, or should not be run

NUnit – Attributes (4) Explicit tests (ignored unless run explicitly)Explicit tests (ignored unless run explicitly) [TestFixture, Explicit][TestFixture, Explicit] [Test, Explicit][Test, Explicit] Categories (used for grouping tests)Categories (used for grouping tests) [TestFixture, Category("LongRunning")][TestFixture, Category("LongRunning")] [Test, Category("Long")][Test, Category("Long")] Explicit tests (ignored unless run explicitly)Explicit tests (ignored unless run explicitly) [TestFixture, Explicit][TestFixture, Explicit] [Test, Explicit][Test, Explicit] Categories (used for grouping tests)Categories (used for grouping tests) [TestFixture, Category("LongRunning")][TestFixture, Category("LongRunning")] [Test, Category("Long")][Test, Category("Long")]

SetUp & TearDown Timeline Begin TestsBegin Tests Call TestFixtureSetUpCall TestFixtureSetUp Call SetUpCall SetUp Call ExampleTestOneCall ExampleTestOne Call TearDownCall TearDown Call SetUpCall SetUp Call ExampleTestTwoCall ExampleTestTwo Call TearDownCall TearDown Call TestFixtureTearDownCall TestFixtureTearDown End TestsEnd Tests Begin TestsBegin Tests Call TestFixtureSetUpCall TestFixtureSetUp Call SetUpCall SetUp Call ExampleTestOneCall ExampleTestOne Call TearDownCall TearDown Call SetUpCall SetUp Call ExampleTestTwoCall ExampleTestTwo Call TearDownCall TearDown Call TestFixtureTearDownCall TestFixtureTearDown End TestsEnd Tests

NUnit – Assertions Using NUnit.Framework.Assert classUsing NUnit.Framework.Assert class Assertions check condition and throw exception if condition is not satisfiedAssertions check condition and throw exception if condition is not satisfied Comparing valuesComparing values AreEqual(expected value, calculated value [,message]) – Compare two values for equalityAreEqual(expected value, calculated value [,message]) – Compare two values for equality Comparing objectsComparing objects IsNull(object [,message])IsNull(object [,message]) Using NUnit.Framework.Assert classUsing NUnit.Framework.Assert class Assertions check condition and throw exception if condition is not satisfiedAssertions check condition and throw exception if condition is not satisfied Comparing valuesComparing values AreEqual(expected value, calculated value [,message]) – Compare two values for equalityAreEqual(expected value, calculated value [,message]) – Compare two values for equality Comparing objectsComparing objects IsNull(object [,message])IsNull(object [,message])

NUnit – Assertions (2) IsNotNull(object [,message])IsNotNull(object [,message]) AreSame(expected object, current object [,message]) – Compares object referencesAreSame(expected object, current object [,message]) – Compares object references ConditionsConditions IsTrue(condition)IsTrue(condition) IsFalse(condition)IsFalse(condition) Forced test failForced test fail Fail()Fail() IsNotNull(object [,message])IsNotNull(object [,message]) AreSame(expected object, current object [,message]) – Compares object referencesAreSame(expected object, current object [,message]) – Compares object references ConditionsConditions IsTrue(condition)IsTrue(condition) IsFalse(condition)IsFalse(condition) Forced test failForced test fail Fail()Fail()

NUnit – Example public class Account { private float balance; private float balance; public void Deposit(float amount) public void Deposit(float amount) { balance += amount; balance += amount; } public void Withdraw(float amount) public void Withdraw(float amount) { balance -= amount; balance -= amount; } public void TransferFunds( public void TransferFunds( Account destination, float amount) Account destination, float amount) {... } {... } public float Balance public float Balance {... } {... }}

NUnit – Example (2) using NUnit.Framework; [TestFixture] public class AccountTest { [Test] [Test] public void TransferFunds() public void TransferFunds() { Account source = new Account(); Account source = new Account(); source.Deposit(200.00F); source.Deposit(200.00F); Account dest = new Account(); Account dest = new Account(); dest.Deposit(150.00F); dest.Deposit(150.00F); source.TransferFunds(dest, F); source.TransferFunds(dest, F); Assert.AreEqual(250.00F, dest.Balance); Assert.AreEqual(250.00F, dest.Balance); Assert.AreEqual(100.00F, source.Balance); Assert.AreEqual(100.00F, source.Balance); }}

NUnit – Screen Shots

TestDriven – A Helpful Tool For developers who want to work in the Visual Studio IDE there is the add-onFor developers who want to work in the Visual Studio IDE there is the add-on Tests can be ran with a single click anywhere in your VS solutionTests can be ran with a single click anywhere in your VS solution Supports 'Debugger' context to step into a unit testSupports 'Debugger' context to step into a unit test For developers who want to work in the Visual Studio IDE there is the add-onFor developers who want to work in the Visual Studio IDE there is the add-on Tests can be ran with a single click anywhere in your VS solutionTests can be ran with a single click anywhere in your VS solution Supports 'Debugger' context to step into a unit testSupports 'Debugger' context to step into a unit test

NUnitNUnit Live Demo

Unit Testing Best Practices

Naming Standards for Unit Tests Test name should express a specific requirementTest name should express a specific requirement Test name should includeTest name should include Expected input or stateExpected input or state Expected result output or stateExpected result output or state Name of the tested method or className of the tested method or class Test name should express a specific requirementTest name should express a specific requirement Test name should includeTest name should include Expected input or stateExpected input or state Expected result output or stateExpected result output or state Name of the tested method or className of the tested method or class

Naming Standards for Unit Tests – Example Given the method:Given the method: with requirement to ignore numbers > 100 in the summing process The test name should be:The test name should be:Sum_NumberIgnoredIfBiggerThan100 Given the method:Given the method: with requirement to ignore numbers > 100 in the summing process The test name should be:The test name should be:Sum_NumberIgnoredIfBiggerThan100 public int Sum(params int[] values)

When Should a Test be Changed or Removed? Generally, a passing test should never be removedGenerally, a passing test should never be removed These tests make sure that code changes don’t break working codeThese tests make sure that code changes don’t break working code A passing test should only be changed to make it more readableA passing test should only be changed to make it more readable When failing tests don’t pass, it usually means there are conflicting requirementsWhen failing tests don’t pass, it usually means there are conflicting requirements Generally, a passing test should never be removedGenerally, a passing test should never be removed These tests make sure that code changes don’t break working codeThese tests make sure that code changes don’t break working code A passing test should only be changed to make it more readableA passing test should only be changed to make it more readable When failing tests don’t pass, it usually means there are conflicting requirementsWhen failing tests don’t pass, it usually means there are conflicting requirements

When Should a Test be Changed or Removed? (2) Example:Example: New features allows negative numbersNew features allows negative numbers Example:Example: New features allows negative numbersNew features allows negative numbers [ExpectedException(typeof(Exception), "Negatives not allowed")] void Sum_FirstNegativeNumberThrowsException() { Sum (-1,1,2); Sum (-1,1,2);}

New developer writes the following test:New developer writes the following test: Earlier test fails due to a requirement changeEarlier test fails due to a requirement change New developer writes the following test:New developer writes the following test: Earlier test fails due to a requirement changeEarlier test fails due to a requirement change When Should a Test be Changed or Removed? (3) void Sum_FirstNegativeNumberCalculatesCorrectly() { int sumResult = sum(-1, 1, 2); int sumResult = sum(-1, 1, 2); Assert.AreEqual(2, sumResult); Assert.AreEqual(2, sumResult);}

Two course of actions:Two course of actions: 1.Delete the failing test after verifying if it’s valid 2.Change the old test: Either testing the new requirementEither testing the new requirement Or test the older requirement under new settingsOr test the older requirement under new settings Two course of actions:Two course of actions: 1.Delete the failing test after verifying if it’s valid 2.Change the old test: Either testing the new requirementEither testing the new requirement Or test the older requirement under new settingsOr test the older requirement under new settings When Should a Test be Changed or Removed? (4)

Tests Should Reflect Required Reality What’s wrong with the following test?What’s wrong with the following test? A failing test should prove that there is something wrong with the production codeA failing test should prove that there is something wrong with the production code Not with the unit test codeNot with the unit test code What’s wrong with the following test?What’s wrong with the following test? A failing test should prove that there is something wrong with the production codeA failing test should prove that there is something wrong with the production code Not with the unit test codeNot with the unit test code int Sum(int a, int b) –> returns sum of a and b public void Sum_AddsOneAndTwo() { int result = Sum(1,2); int result = Sum(1,2); Assert.AreEqual(4, result, "Bad sum"); Assert.AreEqual(4, result, "Bad sum");}

What Should Assert Messages Say? Assert message in a test is one of the most important thingsAssert message in a test is one of the most important things Tells us what we expected to happen but didn’t, and what happened insteadTells us what we expected to happen but didn’t, and what happened instead Good assert message helps us track bugs and understand unit tests more easilyGood assert message helps us track bugs and understand unit tests more easily Assert message in a test is one of the most important thingsAssert message in a test is one of the most important things Tells us what we expected to happen but didn’t, and what happened insteadTells us what we expected to happen but didn’t, and what happened instead Good assert message helps us track bugs and understand unit tests more easilyGood assert message helps us track bugs and understand unit tests more easily

Express what should have happened and what did not happenExpress what should have happened and what did not happen “ Verify() did not throw any exception”“ Verify() did not throw any exception” “ Connect() did not open the connection before returning it”“ Connect() did not open the connection before returning it” Do not:Do not: Provide empty or meaningless messagesProvide empty or meaningless messages Provide messages that repeat the name of the test caseProvide messages that repeat the name of the test case Express what should have happened and what did not happenExpress what should have happened and what did not happen “ Verify() did not throw any exception”“ Verify() did not throw any exception” “ Connect() did not open the connection before returning it”“ Connect() did not open the connection before returning it” Do not:Do not: Provide empty or meaningless messagesProvide empty or meaningless messages Provide messages that repeat the name of the test caseProvide messages that repeat the name of the test case What Should Assert Messages Say? (2)

Avoid Multiple Asserts in a Single Unit Test Disadvantages of multiple asserts in one test case:Disadvantages of multiple asserts in one test case: If the first assert fails, the test execution stops for this test caseIf the first assert fails, the test execution stops for this test case Affect future coders to add assertions to test rather than introducing a new oneAffect future coders to add assertions to test rather than introducing a new one void Sum_AnyParamBiggerThan1000IsNotSummed() { Assert.AreEqual(3, Sum(1001, 1, 2); Assert.AreEqual(3, Sum(1, 1001, 2); Assert.AreEqual(3, Sum(1, 2, 1001); }

Mock Objects Usage Q: When should mock objects be used? A: Mock objects are used when one needs to replace or remove dependencies from code under test Example:Example: Class LoginManager manages user logins with the following responsibility:Class LoginManager manages user logins with the following responsibility: When login fails, class reports to a logger classWhen login fails, class reports to a logger class

Mock Objects Usage (2) The unit test should test the class logic without having to configure or rely on the availability of the loggerThe unit test should test the class logic without having to configure or rely on the availability of the logger So we replace the logger class with a "fake" oneSo we replace the logger class with a "fake" one

Unit Testing – The Challenge The concept of Unit Testing has been around for many yearsThe concept of Unit Testing has been around for many years New methodologies in particular XP, have turned unit testing into a cardinal foundation of software developmentNew methodologies in particular XP, have turned unit testing into a cardinal foundation of software development Writing good & effective Unit Tests is hard!Writing good & effective Unit Tests is hard! This is where supporting integrated tools and suggested guidelines enter the pictureThis is where supporting integrated tools and suggested guidelines enter the picture The ultimate goal is tools that generate unit tests automaticallyThe ultimate goal is tools that generate unit tests automatically The concept of Unit Testing has been around for many yearsThe concept of Unit Testing has been around for many years New methodologies in particular XP, have turned unit testing into a cardinal foundation of software developmentNew methodologies in particular XP, have turned unit testing into a cardinal foundation of software development Writing good & effective Unit Tests is hard!Writing good & effective Unit Tests is hard! This is where supporting integrated tools and suggested guidelines enter the pictureThis is where supporting integrated tools and suggested guidelines enter the picture The ultimate goal is tools that generate unit tests automaticallyThe ultimate goal is tools that generate unit tests automatically

Useful Links NUnit – – Extreme Programming – Programming – XP Programming – Programming – Advanced Unit Testing– Unit Testing– Continuous Integration – egration.htmlContinuous Integration – egration.html egration.html egration.html NUnit – – Extreme Programming – Programming – XP Programming – Programming – Advanced Unit Testing– Unit Testing– Continuous Integration – egration.htmlContinuous Integration – egration.html egration.html egration.html

Unit Testing Fundamentals and NUnit Questions?Questions?

ExercisesExercises 1. Write two classes: Student and Course. Students should have name and faculty number. Name can not be empty and Faculty number is between and Each course contain set of students. Students in a course should be less than 30 and can join and leave courses.

Exercises (2) 2.Write NUnit tests for these two classes Use 2 class library projects in Visual Studio: School.csproj and TestSchool.csprojUse 2 class library projects in Visual Studio: School.csproj and TestSchool.csproj 3.Execute the tests using GUI and console variants of NUnit 2.Write NUnit tests for these two classes Use 2 class library projects in Visual Studio: School.csproj and TestSchool.csprojUse 2 class library projects in Visual Studio: School.csproj and TestSchool.csproj 3.Execute the tests using GUI and console variants of NUnit