Translate

Testing Frameworks

There are many testing frameworks available (both commercial and free). The most
commonly used frameworks are xUnit family of frameworks, most notably NUnit, xUnit.net, and MbUnit. Nunit is most widely used as it has been available longer in market and because of its extensibility (it supports plug-ins). We can easily download any of these frameworks from NuGet (http://nuget.org). Visual Studio allows us to use any of these frameworks within the IDE. So, that we have a familiar interface to work with.

In addition to basic testing frameworks, there are also mocking frameworks, purpose of which is to provide mock objects. Mock objects simulate the functionality of real objects. With mock objects w can simulate nonexistent functionality and external resources. It provides means to write unit test following the principle of isolation.

There are many mocking frameworks available free such as Moq, Nunit.Mocks and RhinoMocks. We can download any directly from NuGet. Some of the commercial ones are JustMock from Telerik (http://bit.ly/JustMock) and Isolator from Typemock (http://bit.ly/TypemockIsolator). Microsoft Test Framework has a feature called Fakes which is equivalent of the mock object.

We generally use Microsoft Test Framework as it is included in Visual Studio and does not require any setup or configuration. But not all the features of Microsoft Test Framework are
available in all versions of Visual Studio. For example, Fakes feature to create mocking objects is available in Visual Studio 2012 Premium and Ultimate. That's why, for mocking objects, we use a mocking framework called Moq.

Moq Introduction

Moq is a mocking framework which very simple and easy to use. It has no dependency and we just need Moq.dll. It is open source and free too. We can use it in all editions of Visual Studio including the free ones.

Moq was designed to take advantage of C# 3.0 but it works very well with the most recent version of C# too. It supports mocking interfaces and classes both. Internally, Moq uses Castle DynamicProxy (http://bit.ly/DynamicProxy) as a mechanism to enable mocking. Which means DynamicProxy helps Moq to create .NET proxy on-the-fly at run time. Using this proxy Moq is able to intercept objects without modifying code of class. Once Moq intercepts the object, it can determine its behavior and it can add functionality to the object without modifying code of the object.

By using proxy mechanism mock objects is simple and fast but it has a some limitation: If both interfaces and classes are proxied then only virtual members can be intercepted and mocked. In other words, if we have static classes or members then they can not be mocked with Moq.

Setting Up Moq


Easy way to set up Moq in our application is to install it via NuGet. To open NuGet, go to Tools => Library Package Manager => Manage NuGet Packages for Solution as shown in Figure 1:


Figure 1. Opening the NuGet Package Manager


Once NuGet Package Manager window is opened, type moq in the search box and results will appear as shown in Figure 2:



Figure 2. Installing Moq from NuGet

Click on “Install” button for Moq. In the Select Projects dialog that opens, check the box for the Tests project as shown in Figure 3 and click “OK” and it will set up Moq in our test project and we now ready to use it.



Figure 11-3. Selecting the project in which to install Moq


Benefits of Unit Testing

Following are the main benefits of using unit testing:

Finds problems early: Well written unit tests enables you to easily and quickly pinpoint
problems of the code early in development process. It is particularly true when
implementing test driven development (TDD). With TDD we first write test cases and then write code to pass the tests.

Facilitates change: Unit test helps to ensure that any future changes in the code do not break application. If any change cause a test to fail then the test failure will give us a clear pointer where we need to fix the code.

Simplifies integration: As unit test focuses on testing small pieces of code and for testing
complete module becomes easier - we know that at least the components of the module work properly.

Provides documentation: Unit test provides nice source of documentation about functionality of the application. So, naming the classes and unit tests correctly becomes increasingly important.

Unit Testing

Unit testing is not a new concept. The basic idea is to create a program which will make certain assumptions for a specific piece of code in our application and determine, based on those assumptions, the code produces an expected result or not.

Defining a Unit Test

The program which will perform test is called unit test. An excellent definition of a unit test is:

Unit test is an automated piece of code which invokes method or class being tested and then checks some assumptions about logical behavior of that method or class. Unit test is almost always written using a unit-testing framework. It can be written easily and runs quickly. It is fully automated, trustworthy, readable and maintainable.

A key concept in above definition is that each unit test must test one and only one, behavior of the functionality being tested. For example, a method which returns an object based on the id. The method can behave in either of two ways - If it finds the object with the specified id then it should return the object. If it does not find the object then it should return null. As the method has two behaviors, we would write two unit tests: first to test the case where it finds the object and second to test when it returns null. It can lead for writing many unit tests for a single piece of code. It is okay to have many unit tests, in fact, it is expected. Unit tests are executed automatically and are very fast. So, it does not matter how many test cases we have.

Also, we should not delete unit test just because it succeeds. We should delete a unit test only if we have removed from the application the corresponding functionality being tested. It will ensure that we can run the test each time we add new functionality or make any change in the application by ensuring nothing has been broken by the addition or change.

With Microsoft Test Framework, we can create unit tests as methods which are decorated with the [TestMethod] attribute. The methods must be in a class which is decorated with the [TestClass] attribute.

Structure of Unit Tests

One of the most common patterns which should be followed when writing unit tests is the AAA pattern, in which we write our unit test in three parts:

Arrange: Set up the unit test. For example, we initialize variables and objects so that they are ready to pass in code to be tested.

Act: Invokes the code we want to test. It means invoking a particular method which we are trying to test.

Assert: Analyzes result produced in the Act part. We might verify the return value and any output parameters are what we expected.

Isolation

Another important aspect of unit testing is that it should properly locate the source of problem when it arises. By using unit testing, although we are testing only small pieces of code, we should do the tests in an isolated environment. It is very important to isolate our code from external resources out of our control (databases, web services and file system etc.) as

The resources might fail for unpredictable reasons.

The data yielded by such external resources might be unpredictable and non-repeatable (which really ruins the unit tests).

The resources might not actually be available yet in our development project.

Additional benefit of testing in isolation is that we can test our code even if the external resources are not ready to interact with it yet. Suppose we are working as a team and our piece of code has a dependency on some piece of code from a colleague but that colleague has not completed the piece of code yet. Or suppose our code has a dependency on a completely external component (from a third party or trading partner).

In either case, by isolating our code, we do not need to worry about those dependencies. We can move forward with our development and be ready to go when the rest of team is ready.

Naming Unit Tests

An ignored aspect of creating a good unit test is its name. Nothing prevents us from naming our unit test something as generic as Test1(), it will hardly give us any useful information. A common practice is to name our unit test in a manner which gives developers as much information as possible when the test gets fail. A good pattern of naming unit tests is to concatenate the name of method being tested, the key assumptions and expected result. For example, UploadFile_ValidFileSpecificied_SizeOnServerOverZeroKb().


Properly naming the test classes is also best practice. We should use same name as the class to be tested and suffix Test. For example, HomeControllerTest - which raises an interesting MVC-related point: we can perform unit tests on controller classes.

Cross-Site Scripting Prevention

Cross-site scripting is vulnerability in web applications which allows hackers to inject JavaScript code in the form fields whose values are not sanitized properly. These values are either saved in database or executed later when they used in other areas of application or displayed immediately in page. As defined by Open Web Application Security Project (OWASP), there are two types of attacks classified as stored XSS and reflected XSS, respectively.


To understand XSS better, let us take an example. We allow users to send messages to pet owners. At this point, if user tries to add HTML tags to the message then the user gets an error as shown in Figure 1. This error is throwing because ASP.NET verifies all input fields to prevent XSS and by default does not allow users to post any HTML tag to server.


Figure 1. ASP.NET prevents XSS mechanism and disallows HTML post to server

Now, if we really need to allow the users to post the HTML tags to server then we can modify behavior by adding ValidateInput as false to the send action method as shown in Figure 2. The problem is that it will disable all the XSS validation for all fields.


Figure 2. Disabling All XSS Validation

Better approach is allowing the HTML tags in specific fields. In this example, only field in which we allow HTML tags is the Message field. To achieve this, we need to remove ValidationInput = false attribute from action method and add AllowHtml attribute to the field in the view model as shown in Figure 3. We have modified the send view to show the values posted after user sent the message. When user sends the message then we get result shown in Figure 2.


Figure 3. Allowing HTML Tags in Message Field

The application has opened one door to let users enter HTML tags, including <script> tags. The user can enter <script type="text/javascript">alert("Evil Script");</script> in the field and the result will be as shown in Figure 4.


Figure 4. JavaScript injected in Message field

WebKit based browsers like Google Chrome and Safari have integrated XSS validation module which is called XSS Auditor which can prevent execution of <script> tags. The Chromium Blog article “Security in Depth: New Security Features” describes behavior of XSS Auditor at the time known as XSS filter as follows:

XSS filter is similar to the ones found in Internet Explorer 8 and NoScript. Instead of layered on top of browser like those filters, the XSS filter is integrated into WebKit, which Google Chrome uses for rendering the webpages. Integrating XSS filter into rendering engine has two benefits:

1. The filter can catch scripts right before they executed, making easier detection some tricky attack variations.
2. The filter can be used by all WebKit based browser, including Safari and Epiphany.

Google Chrome also acknowledges that there are some other ways of bypassing the XSS filters. However, it is always improving the technology, so over time these scenarios should be avoided.

For example, In Google Chrome, message entered previously produces an error in developer tool console as shown in Figure 5.


Figure 5. XSS Auditor module in Google Chrome