Unit Testing - University of Calgary

Unit Testing - University of Calgary

SENG 403, Winter 2012 Unit Testing SENG 403 Winter 2012 Agenda Exploring unit-testing frameworks in .NET Writing our first test with NUnit Unit Testing in Visual Studio (Now integrated into

VS 2010) Unit Testing in Java Two examples in VS 2010 and Java SENG 403 Winter 2012 Definition A unit test: is a piece of a code (usually a method) that invokes another piece of code.

checks the correctness of some assumptions afterward. if the assumptions turn out to be wrong, the unit test has failed. A unit is a method or function. SENG 403 Winter 2012 The importance of writing good unit tests Most people who try to unit-test their code either give up at some point or dont actually perform unit tests.

Instead, they either rely on system and integration tests to be performed much later in the product lifecycle or they resort to manually testing the code via custom test applications or by using the end product theyre developing to invoke their code. Thats either too late to correct the error or very difficult to do so. SENG 403 Winter 2012 Properties of a good unit test A unit test should have the following properties: 1.

It should be automated and repeatable. 2. It should be easy to implement. 3. Once its written, it should remain for future use. 4. Anyone should be able to run it. 5. It should run at the push of a button.

6. It should run quickly. SENG 403 Winter 2012 A more comprehensive definition of Unit Test A unit test is an automated piece of code that invokes the method or class being tested. and then checks some assumptions about the logical behavior of that method or class.

A unit test is almost always written using a unittesting framework (e.g. NUnit, JUnit) It can be written easily and runs quickly. Its fully automated, trustworthy, readable, and maintainable. SENG 403 Winter 2012 Unit-testing frameworks are code libraries and modules that help developers unit-test their code, as outlined in the following table. unit-testing frameworks help developers write and execute tests, and

review results Unit-testing practice How the framework helps Write tests easily and in a structured manner. Execute one or all of the unit tests. Review the results of the test runs. Framework supplies the developer with a class library that holds: base classes or interfaces to inherit. attributes to place in your code to note your tests to run. assert classes that have special assert methods you invoke to verify your code. Framework provides a test runner (a console or GUI tool) that : identifies tests in your code.

runs tests automatically. indicates status while running. can be automated by command line. The test-runners will usually provide information such as: how many tests ran. how many tests didnt run. how many tests failed. which tests failed. the reason tests failed. the ASSERT message you wrote. (Well see this after a few slide) the code location that failed. possibly a full stack trace of any exceptions that caused the test to fail, and will let you go to the various method calls inside the call stack. SENG 403 Winter 2012 The xUnit frameworks

There are more than 150 unit-testing frameworks. Practically one for every programming language in public use. A good list can be found at http://www.xprogramming.com. These unit-testing frameworks are called the xUnit frameworks, because their names usually start with the first letters of the language for which they were built. You might have CppUnit for C++, JUnit for Java, NUnit

for .NET, and HUnit for the Haskell programming language. Not all of them follow these naming guidelines, but most of them do. SENG 403 Winter 2012 Example In this example code there is only one class. It is called LogAn project (short for log and notification).

We will be using .Net & Nunit. SENG 403 Winter 2012 Heres the scenario Your company has many internal products that it monitors their applications at customer sites. All these products write log files and place them in a special directory.

The log files are written in a proprietary format that your company has come up with that cant be parsed by any existing third-party tools. Winter 2012 Youre tasked SENG with403building a product, LogAn, that can Download and Install NUnit You can download NUnit from www.NUnit.org or www.NUnit.com. NUnit is free to use and is an open

source product. For continuing with the example in this tutorial download the following source code: http://artofunittesting.com/ Under Downloads click on Source Code. load up the ArtOfUnitTesting.sln solution (In Visual Studio 2008 or above) SENG 403 Winter 2012 NUnit GUI The NUnit GUI is divided into three main parts: the tree listing the tests on the left messages and errors at the top right

and stack trace information at the bottom right. SENG 403 Winter 2012 First Test Well begin by testing the following simple class with one method (the unit were testing) inside it: public class LogAnalyzer { public bool IsValidLogFileName(string fileName) { if(!fileName.EndsWith(".SLF")) { return false;

} return true; } } SENG 403 Winter 2012 These are all done in the source code you have downloaded. Here are the first steps for writing an automated test for the IsValidLogFileName method: 1. Add a new class library project to the solution, which will contain your test classes.

2. To that library, add a new class that will hold your test methods. 3. Add a new method to the preceding test case named IsValidLogFileName. SENG 403 Winter 2012 Naming test classes/methods/projects For example, the name for our LogAn test project would be AOUT.Logan.Tests (with AOUT standing for Art of Unit Testing) . The name for the LogAnalyzer test class would be

LogAnalyzerTests. Our test method name might be IsValidFileName_validFile_ReturnsTrue() SENG 403 Winter 2012 We have not used the NUnit test framework yet, but were close. We still need to add a reference to the project under test for the new testing project.

Do this by right-clicking on the test project and selecting Add Reference. Then select the Projects tab and select the LogAn project. [This is done in the source code you have downloaded] The next thing to learn is how to mark the test method to be loaded and run by NUnit automatically. NUnit uses an attribute scheme to recognize and load tests. Just like bookmarks in a book. SENG 403 Winter 2012

NUnit provides an assembly that contains these special attributes. You just need to add a reference in your test project (not in your production code!) to the NUnit.Framework assembly. You can find it under the .NET tab in the Add Reference dialog box. Type Nunit and youll see several

assemblies starting with that name; add nunit.framework. SENG 403 Winter 2012 NUnit needs at least two attributes to know what to run: 1. [TestFixture] The [TestFixture] attribute denotes a class that holds automated NUnit tests. (If you replace the word Fixture with Class, it makes much more sense.) Put this attribute on your new LogAnalyzerTests class. 2. [Test] The [Test] attribute can be put on a method to denote it as an automated test to

be invoked. Put this attribute on your new test method. [TestFixture] public class LogAnalyzerTests { [Test] public void IsValidFileName_validFile_ReturnsTrue() { } } SENG 403 Winter 2012 How do we test our code? A unit test usually comprises three main actions: Arrange objects, creating and setting them up as

necessary. Act on an object. Assert that something is as expected. SENG 403 Winter 2012 Heres a simple piece of code that does all three actions. The assert part is performed by the NUnit frameworks Assert class: public void IsValidLogFileNameTest() { //arrange LogAnalyzer analyzer = new LogAnalyzer(); //act

bool result = analyzer.IsValidLogFileName("whatever.slf"); //assert Assert.IsTrue(result, "filename should be valid!"); } SENG 403 Winter 2012 The Assert class The Assert class has static methods and is located in the Microsoft.VisualStudio.TestTools.UnitTesting namespace. Its the bridge between your code and the UnitTesting framework, and its purpose is to declare that a specific assumption is supposed to exist.

If the arguments that are passed into the Assert class turn out to be different than what were asserting, UnitTesting will realize the test has failed and will alert us. We can optionally tell the Assert class what message to alert us with, if the assertion fails. (Exception Arguments) The Assert class has many methods, with the main one being Assert.IsTrue (some Boolean expression), which verifies a Boolean condition. (But there is more) [next slides] SENG 403 Winter 2012

The Assert class (contd.) Example 1: Assert.AreEqual(2, 1+1, "Math is broken"); Example 2: This one verifies that the two arguments reference the same object: Assert.AreSame(expectedObject, actualObject, message) Assert.AreSame(int.Parse("1"),int.Parse("1"), "this test should fail"). SENG 403 Winter 2012

Running our first test with NUnit To do that, we need to have a build assembly (a .dll file in this case) that we can give to NUnit to inspect. After you build the project, locate the path to the assembly file that was built. Then, load up the NUnit GUI and select File > Open. Enter the name of your tests assembly. Youll see your single test and the class and namespace hierarchy of your project on the left,

as shown in next slide. Click the Run button to run your tests. As you can see, we have a failing test, which might suggest that theres a bug in the code. Its time to fix the code and see the test pass. SENG 403 Winter 2012 Namespace hierarchy of your project SENG 403 Winter 2012

Test results: SENG 403 Winter 2012 Why test failed? A quick look through the code reveals that were testing for an uppercase filename extension and our test is sending in a lowercase filename extension, which makes our code return false instead of true. SENG 403 Winter 2012 If we fix the if statement in the production code to look like this, we can make the test pass:

if(! fileName. ToLower(). EndsWith(". slf")) But this is a sign that the name of our test may need changing, and that we need another test to make sure that sending in an uppercase extension works. (We know that it works now, but whos to say that some programmer working on this feature wont break it in the future?) A better name for our current test might be: IsValidFileName_validFileLowerCased_ReturnsTrue() . SENG 403 Winter 2012

NUnit detect changes in the original code If you rebuild the solution now, youll find that NUnits GUI can detect that the assembly has changed. It will automatically reload the assembly in the GUI. If you rerun the tests, youll see that the test passes with flying (green) colors. SENG 403 Winter 2012

Initialize and Cleanup (1) For unit tests, its important that any leftover data or instances from previous tests are destroyed and that the state for the new test is recreated as if no tests have been run before. If you have leftover state from a previous test, you might find that your test fails. In NUnit, there are special attributes that allow easier control of setting up and clearing out state before and after

tests. These are the [ SetUp] and [TearDown] action attributes. SENG 403 Winter 2012 NUnit performs setup and teardown actions before each and every test method. We can take control of what happens in the setup and teardown steps by using two NUnit attributes: [SetUp] This attribute can be put on a method, just like a [ Test]attribute, and it causes NUnit to run that setup method

each time it runs any of the tests in your class. [TearDown] This attribute denotes a method to be executed once after each test in your class has executed. SENG 403 Winter 2012 The following show how we can use the [SetUp] and [TearDown] attributes to make sure that each test receives a new instance of LogAnalyzer, while also saving some repetitive typing. public class LogAnalyzerTest { private LogAnalyzer m_analyzer=null; [TestInitialize] public void Setup() { m_analyzer = new LogAnalyzer(); }

[TestMethod] public void IsValidFileName_validFileLowerCased_ReturnsTrue() { bool result = m_analyzer.IsValidLogFileName("whatever.slf"); Assert.IsTrue(result, "filename should be valid!"); } [TestMethod] public void IsValidFileName_validFileUpperCased_ReturnsTrue() { bool result = m_analyzer.IsValidLogFileName("whatever.SLF"); Assert.IsTrue(result, "filename should be valid!"); } [TestCleanup] public void TearDown() { m_analyzer = null; } }

} You can think of the setup and teardown methods as: constructors and destructors for the tests in your class. You can only have one of each in any test class, and each one will be performed once for each test in your class. SENG 403 Winter 2012 ArgumentException One common testing scenario is making sure that the correct exception is

thrown from the tested method when it should be. Lets assume that our method should throw an ArgumentException when we send in an empty filename. public bool IsValidLogFileName(string fileName) { if (String.IsNullOrEmpty(fileName)) { throw new ArgumentException("No filename provided!"); } if (!fileName.ToLower().EndsWith(".slf")) { return false; } return true; }

SENG 403 Winter 2012 ArgumentException Theres a special attribute in NUnit that helps us test exceptions and that is the [ExpectedException] attribute. Heres what a test that checks for the appearance of an exception might look like: [TestMethod] [ExpectedException(typeof(ArgumentException))] public void IsValidFileName_EmptyFileName_ThrowsException() { m_analyzer.IsValidLogFileName(string.Empty); }

SENG 403 Winter 2012 Ignoring tests Sometimes youll have tests that are broken. In those rare cases (and they should be rare! ), you can put an [Ignore] attribute on tests that are broken because of a problem in the test, not in the code. [Test] [Ignore("there is a problem with this test")] public void IsValidFileName_ValidFile_ReturnsTrue() { /// ...

} SENG 403 Winter 2012 Ignoring tests In NUnit, an ignored test is marked in yellow (the middle test), and the reason for not running the test is listed under the Tests Not Run tab on the right. SENG 403 Winter 2012 Unit Testing from within Visual Studio 2010 With the latest release of Visual Studio Test System (VSTS) comes

a full suite of functionality for Visual Studio Team Test (TT). [See the third reference in the last slide]. Team Test is a Visual Studio integrated unit-testing framework that enables: Code generation of test method stubs. Running tests within the IDE. Incorporation of test data loaded from a database. Code coverage analysis once the tests have run.

Now that we know the structure and format of tests in C# and the way they are run by NUnit it is easy to understand how Unit Testing works in VS 2010. SENG 403 Winter 2012 Visual Studio 2010 (Much easier than NUnit) Lets write a test code for the following Solution. First add a new class to your project (Right click on the project name select Add and the select Class Now put the following two methods in it. SENG 403 Winter 2012

Right click inside the scope of the function that you want to be tested and SENG 403 Winter 2012 SENG 403 Winter 2012 Give it a name if you were asked to. SENG 403 Winter 2012 SubtractTest (automatically generated) SENG 403 Winter 2012 Go to the Test View

SENG 403 Winter 2012 Before running the tests, refresh the test list SENG 403 Winter 2012 Test list refreshed (updated) SENG 403 Winter 2012 Unit Testing in Java The commonly used framework for unit testing in Java is JUnit.

You can get it as a jar file from www.junit.org. It is an integrated part of the Eclipse IDE. To write unit tests, we should first create a Java project. It is a good practice to put tests inside a separate folder. SENG 403 Winter 2012 Unit Testing in Java using Eclipse (1)

First create a Java project. Then right click on the project name in the package explorer and create a new folder for tests. SENG 403 Winter 2012 Unit Testing in Java using

Eclipse (2) The test folder must be on the build path. Add it to the build path by selecting Build path>Configure build path. Then go to the Source tab and add the folder. SENG 403 Winter 2012 Unit Testing in Java using Eclipse (3) Create a Class in the src folder. SENG 403 Winter 2012 Unit Testing in Java using

Eclipse (4) Then we need to create a JUnit test by selecting New>Junit Test Case. We should put it in the test folder. SENG 403 Winter 2012 Unit Testing in Java using Eclipse (5) Eclipse will ask us to add JUnit 4 to

the build path. Press OK to add it. SENG 403 Winter 2012 Unit Testing in Java using Eclipse (6) Each test method is marked with @Test annotation. SENG 403 Winter 2012 Unit Testing in Java using Eclipse (7) To run the test right click on

the test file and select Run As > JUnit Test. The test should fail (red/brown line in the JUnit tab). After fixing the problem in the source code, we will get a green line. What do you think the problem is? .SLF vs. .slf SENG 403 Winter 2012 Unit Testing in Java using

Eclipse (8) If we have a set of test cases and want to run all of them with one click, we should create a Test Suite. Select all your test classes, then right click and select New>Other..->JUnit Test Suite. (Does not work for JUnit 4.) SENG 403 Winter 2012

Unit Testing in Java using Eclipse (9) Change the generated file like this. Then run it like a normal JUnit test. SENG 403 Winter 2012 References and Resources The Art of Unit Testing (with Examples in .NET) Roy Osherove, 2009.

An example in both C# and VB http://msmvps.com/blogs/deborahk/archive/2009/10/25/unit-testing-an-introduction.aspx A Unit Testing Walkthrough with Visual Studio Team Test http://msdn.microsoft.com/en-us/library/ms379625(VS.80).aspx ---------------------------------------------------------------------

JUnit Tutorial http://www.vogella.de/articles/JUnit/article.html Test Driven Development: By Example Kent Beck, Addison-Wesley Professional, 2002. SENG 403 Winter 2012

Recently Viewed Presentations

  • American Diabetes Association

    American Diabetes Association

    standards of medical care in diabetes—2015
  • Doping of Semiconductors - Department of Electrical ...

    Doping of Semiconductors - Department of Electrical ...

    Doping of Semiconductors ECE G201 (Adapted from Prof. Hopwood) Review intrinsic semiconductor: no= po= ni n-type doping in silicon Column V elements donate an electron to the conduction band What is the energy level, ED?
  • Rupture, Seismic Waves, and Shaking Earthquake Origins and

    Rupture, Seismic Waves, and Shaking Earthquake Origins and

    Rupture, Seismic Waves, and Shaking ... OR Earth's daily receipt of solar energy Calculating Earthquake Magnitude Moment method Essentially the same as Richter at higher magnitudes May be applicable over a wider range of ground motions than Richter Mo =...
  • THE ANKLE AND FOOT - Eastern Illinois University

    THE ANKLE AND FOOT - Eastern Illinois University

    Times Arial Times New Roman Geneva Default Design THE ANKLE AND FOOT BONES Tibia Tibia Fibula BONES OF THE FOOT Slide 7 Slide 8 Hallux or Great Toe Slide 10 JOINTS JOINTS MOVEMENTS MOVEMENTS MOVEMENTS STRUCTURE OF THE FOOT ARCHES...
  • Antiprotozoal Drugs - IHMC Public Cmaps (3)

    Antiprotozoal Drugs - IHMC Public Cmaps (3)

    Use is limited because of its tendency to induce drug resistance (due to its action on such an early stage of the asexual cycle). (3) Mechanism of action. It halts the development of the sporozoites or trophozoites of coccidia by...
  • Last Things - Fifth Street East

    Last Things - Fifth Street East

    Eschatology (The study of last things) False doctrines Premillennialism: Corruption of the nature of the kingdom and God's promises to Israel. Israel A D Church Age 7 years tribulation R Meeting Rapture Revelation RT J Millennium Satan Loosed Resurrection J....
  • 14.1 - Human Heredity - Mr. Kohn's Website

    14.1 - Human Heredity - Mr. Kohn's Website

    14.1 - Human Heredity . Human Chromosomes. Karyotype - a picture of our chromosomes (each cell would have an identical looking karyotype) How is it made? Photograph cells during mitosis . Cut out the chromosomes and group them together in...
  • Doubles Summary.

    Doubles Summary.

    TMCM What to do? 1. Don't ignore singletons. 2. If you would look for slam over 1M do so over 1m. 3. Agree that 3NT followed by 4NT is natural