Testing with Visual Studio 2013

Software testing is what saves the life of any software development project.

Testing applications may be more important than designing good software. Although a developer should always design good software following good architectural principles, the truth is that poorly designed software will work fine if it has hardly been tested and does exactly what the customer needs. On the contrary, it is almost impossible for a never before tested well-designed software to work fine.

Software testing is available at multiple levels. The lower level of testing, the most tightly coupled with our code, is the unit test. Such kinds of tests have the goal of testing a single functional (or sometimes technical) method. If we need to test our Fourier transform method, a unit test is the starting point. When unit testing, it is good practice to give such method data for testing purposes. Such dummy data, called a mockup, is actually useful to point out our code (the subject of the test), isolating its execution from any external inference that real data could bring. In other words, a mockup parameter helps by testing only a method per time, indeed, this is real unit testing. In contrast, by testing multiple methods, we are doing integration testing.

Here is a simple mathematical function to compute the Pow of any Single number, as shown in the following code:

public static float Pow(float a, float b)
{
    return (float)Math.Pow(a, b);
}

Within Visual Studio 2013, we can add a Unit Test Project in the Add New Project window. The preferable naming convention is [TO_BE_TESTED_ASSEMBLY].Test, as shown in the following figure

Once created, we will find a test class, containing all unit tests coupled to a business class or by functional needs. Within such classes, all our unit tests will be available as simple methods, each agnostic against the other, as if each is a simple console application.

Testing with Visual Studio 2013

The unit test project creation

The unit test itself is actually easy, but we should always try to write tests with some ideal case and some real (not ideal) case. When writing a unit test, we should try to break the target method with any unusual parameter, trying to expose our methods to difficulties. For instance, when testing a Pow(a,b) function, we could test its usage by trying to use huge numbers, or negative numbers, or any other number that could bring an exception. Otherwise, a test that's too easy will definitely be useless. Here is an example:

[TestClass]
public class HelperTests
{
    [TestMethod]
    public void PowTest1()
    {
        var a = 10;
        var b = 10;
        var pow = Helpers.Pow(a, b);
        Assert.AreEqual<float>(pow, (float)Math.Pow(a, b));
    }
}

Within our unit test, the Assert static class gives us all the needed prebuilt helpers to signal MsTest (the test engine) that we are asking for some specific verification (or deny it). In the preceding example, we checked the Pow method result against a known value. The input parameters (a and b) are mock values. When dealing with complex input parameters, such as any real business object, a mock framework helps a lot to create dummy objects along with an Inversion of Control container to create mock data or real data, depending on the executing behavior.

The Integration test

An integration test helps to test how different software modules behave when working altogether. Any time we test multiple methods or multiple software modules (with a lot of methods), we are actually doing integration testing. With such testing, mock-up data may also leave space for the real world data coming from other modules.

Creating a unit test within Visual Studio is made with the proper test project. In contrast, there is no wizard or project template regarding integration testing. Such kinds of tests are totally related to the developer's work.

We have the choice of testing different modules by following the use cases step lists precisely, or we can use the software modules in a creative way, trying to find a condition when software hangs.

When dealing with software module integration testing, if we use real world data, an integration test may become a user-acceptance test, with the goal of trying to get the user approval of our development work.

Performance-related tests

Regarding performance, different kinds of tests exist.

We start a performance test if we try to analyze how the system responds regarding different performance aspects, such as scalability, latency, throughput, and so on.

Alternatively, we start a load test if we try to analyze how the application behaves regarding a huge user load, or if we try to identify the higher user load allowed with a static system setup.

Stress testing, although similar to a load test, instead this is more related to understanding how the system recovers from a system fault, or from a huge user load that will create some form of application fault.

All such tests, such as the integration test, are available to the developer as free developing tests. Those kinds of tests, although available within Visual Studio for some application types, are not universally available. For instance, in Visual Studio we have the Web Test (a test of website navigation) and the ability to create a Load Test by executing multiple Web Tests. The same tests are not available for other application types.

TDD

Test-driven development (TDD) is how the sword was centuries ago for fighters. It is not technical knowledge. It gives us the methodology to test in advance, during, and after we develop an application. In other words, it is like developing with the test in mind. The choice of using or not such methodology in your own development project, is related to team needs and wishes. Using TDD increases software quality, but following the TDD way is not the only way to create good tests.

Test and Continuous Integration

When working with complex projects or big teams, implementing the Continuous Integration within our Application Lifecycle Management (ALM) system, such as Team Foundation Server (TFS), will be invaluable.

Continuous integration is the ability to verify that committed changes against our source control compiles without any error. The goal of such features is to verify code quality of the overall team, trying to avoid mistakes in which a developer somehow interfere with the work of another developer.

Within Visual Studio, great integration is available with TFS. This makes setting up Continuous Integration easy. An added feature of TFS is the ability to avoid the committed changes that are definitely committed against the overall source control. Usual Continuous Integration simply tries building our application projects at each check-in to verify code compilation. Within Visual Studio, a more restrictive version exists that is named as Gated Check-in. With this feature, a code that does not build is simply rejected to the developer. This totally avoids bad coding being stored within TFS.

Another great feature available within TFS is the ability to automatically execute all our tests together with the compilation of the Continuous Integration. We then have the ability to notify someone of test results, or prevent the developer committing changes from being saved in the main code, similar to what happens when using the gated check-in feature.

This great feature helps increase the software quality a lot because of the automation of the whole testing job. In addition, we will have historical information about testing success/fail count. This can be a testing report itself, or give the development team a practical regression test result in time.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.7.102