Archive

Archive for the ‘Quality’ Category

TestNG or JUnit

7 August, 2011 7 comments

For many years now, I have always found myself going back to TestNG whenever it comes to doing Unit Testing with Java Code. Everytime, I picked up TestNG, people have asked me why do I go over to TestNG especially with JUnit is provided by the default development environment like Eclipse or Maven. Continuing the same battle, yesterday I started to look into Spring’s testing support. It is also built on top of JUnit. However, in a few minutes of using the same, I was searching for a feature in JUnit that I have always found missing. TestNG provides Parameterized Testing using DataProviders. Given that I was once again asking myself a familiar question – TestNG or JUnit, I decided to document this so that next time I am sure which one and why.

Essentially the same

If you are just going to do some basic Unit Testing, both the frameworks are basically the same. Both the frameworks allow you to test the code in a quick and effective manner. They have had tool support in Eclipse and other IDE. They have also had support in the build frameworks like Ant and Maven. For starters JUnit has always been the choice because it was the first framework for Unit Testing and has always been available. Many people I talk about have not heard about TestNG till we talk about it.

Flexibility

Let us look at a very simple test case for each of the two.

package com.kapil.itrader;
import java.util.Arrays;
import java.util.List;
import junit.framework.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

public class FibonacciTest
{
    private Integer input;
    private Integer expected;

    @BeforeClass
    public static void beforeClass()
    {
        // do some initialization
    }

    @Test
    public void FibonacciTest()
    {
        System.out.println("Input: " + input + ". Expected: " + expected);
        Assert.assertEquals(expected, Fibonacci.compute(input));
        assertEquals(expected, Fibonacci.compute(input));
    }
}

Well, this is example showcases I am using a version 4.x+ and am making use of annotations. Priori to release 4.0; JUnit did not support annotations and that was a major advantage that TestNG had over its competitor; but JUnit had quickly adapted. You can notice that JUnit also supports static imports and we can do away with more cumbersome code as in previous versions.

package com.kapil.framework.core;
import junit.framework.Assert;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

public class BaseTestCase
{
    protected static final ClassPathXmlApplicationContext context;

    static
    {
        context = new ClassPathXmlApplicationContext("rootTestContext.xml");
        context.registerShutdownHook();
    }

    @BeforeSuite
    private void beforeSetup()
    {
       // Do initialization
    }

    @Test
    public void testTrue()
    {
        Assert.assertTrue(false);
    }
}

A first look at the two code, would infer that both are pretty much the same. However, for those who have done enough unit testing, will agree with me that TestNG allows for more flexibility. JUnit requires me to declare my initialization method as static; and consequently anything that I will write in that method has to be static too. JUnit also requires me to have my initialization method as public; but TestNG does not. I can use best practices from OOP in my testing classes as well. TestNG also allows me to declare Test Suite, Groups, Methods and use annotations like @BeforeSuite, @BeforeMethod, @BeforeGroups in addition to @BeforeClass. This is very helpful when it comes to writing any level of integration testing or unit test cases that need to access common data sets.

Test Isolations and Dependency Testing

Junit is very effective when it comes to testing in isolation. It essentially means that there is you can not control the order of execution of tests. And, hence if you have two tests that you want to run in a specific order because of any kind of dependency, you can not do that using JUnit. However, TestNG allows you to do this very effectively. In Junit you can make workaround this problem, but it is not neat and that easy.

Parameter based Testing

A very powerful feature that TestNG offers is “Parameterized Testing”. JUnit has added some support for this in 4.5+ versions, but it is not as effective as TestNG. You may have worked with FIT you would know what I am talking about. However, the support added in JUnit is very basic and not that effective. I have modified my previous test case to include parameterized testing.

package com.kapil.itrader;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.List;

import junit.framework.Assert;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class FibonacciTest
{
    private Integer input;
    private Integer expected;

    @Parameters
    public static List data()
    {
        return Arrays.asList(new Integer[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
    }

    @BeforeClass
    public static void beforeClass()
    {
        System.out.println("Before");
    }

    public FibonacciTest(Integer input, Integer expected)
    {
        this.input = input;
        this.expected = expected;
    }

    @Test
    public void FibonacciTest()
    {
        System.out.println("Input: " + input + ". Expected: " + expected);
        Assert.assertEquals(expected, Fibonacci.compute(input));
        assertEquals(expected, Fibonacci.compute(input));
    }

}

You will notice that I have used @RunWith annotation to allow my test case to be parameterized. In this case, the inline method – data() which has been annotated with @Parameters will be used to provide data to the class. However, the biggest issue is that the data is passed to class constructor. This allows me to code only logically bound test cases in this class. And, I will end up having multiple test cases for one service because all the various methods in the Service wil require different data sets. The good thing is that there are various open source frameworks which have extended this approach and added their own “RunWith” implementations to allow integration with external entities like CSV, HTML or Excel files.

TestNG provides this support out of the box. Not support for reading from CSV or external files, but from Data Providers.

package com.kapil.itrader.core.managers.admin;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.uhc.simple.common.BaseTestCase;
import com.uhc.simple.core.admin.manager.ILookupManager;
import com.uhc.simple.core.admin.service.ILookupService;
import com.uhc.simple.dataprovider.admin.LookupValueDataProvider;
import com.uhc.simple.dto.admin.LookupValueRequest;
import com.uhc.simple.dto.admin.LookupValueResponse;

/**
 * Test cases to test {@link ILookupService}.
 */
public class LookupServiceTests extends BaseTestCase
{

    @Test(dataProvider = "LookupValueProvider", dataProviderClass = LookupValueDataProvider.class)
    public void testGetAllLookupValues(String row, LookupValueRequest request, LookupValueResponse expectedResponse)
    {
        ILookupManager manager = super.getLookupManager();
        LookupValueResponse actualResponse = manager.getLookupValues(request);
        Assert.assertEquals(actualResponse.getStatus(), expectedResponse.getStatus());
    }
}

The code snippet above showcases that I have used dataProvider as a value to the annotations and then I have provided a class which is responsible for creating the data that is supplied to the method at the time of invocation. Using this mechanism, I can easily write test cases and its data providers in a de-coupled fashion and use it very effectively.

Why I choose TestNG

For me the Parameterized Testing is the biggest reason why I choose TestNG over Junit. However, everything that I have listed above is the reason why I always want to spend a few minutes in setting up TestNG in a new Eclipse setup or maven project. TestNG is very useful when it comes to running big test suites. For a small project or a training exercise JUnit is fine; because anyone can start with it very quickly; but not for projects where we need 1000s of test cases and in most of those test cases you will have various scenarios to cover.

http://kapilvirenahuja.com/tech/2011/08/07/testng-or-junit/

Quality has new meaning – it is shit

I do not find that title implied to me; but see it almost everyday being implied to others.

This is in a continuation to a post a while back. In that post, I talked about a project team and their view point on quality. Here is an addition to the same set of people. The conversation goes like

Project Manager: I was just checking on the defect count and noticed we have 24 open P1 and P2 in system. How are we are going to go live tomorrow. What just happened?

QA Manager 1: Nothing, it is just that my team currently does not have any work for Release 2. They had some time on their hands and hence pro-actively they started to test in R1 and logged these defects.

Project Manager 1: so what are you going to do?

QA Manager 1: Nothing, these are not R1 defects. Testing is closed. We wrapped that last week and all these have tobe logged in R2. These are not R1 defects.

Everyone else in the room which included Analyst, and Project Managers laughed about it and joked that this is funny and defects have to go away.

This was the last point of discussion in the meeting and I was shell shocked to say anything. Not that it would have mattered to these guys. I am responsible for the delivery of a different project and not the modules they were talking about. So, amongst all politics and shock I did not say anything. But, I was thinking what happened to quality here.

One of them was the QA Manager, who is responsible for quality of the project and she said “Testing is closed”. How would we feel if Toyota or Honda or any car manufacturer would say that decide to fix problems in the next batch or version of the car.

And what amuses me is that these discussions reach people who are Director IT and Vice President IT and they are in agreement of the fact that “Testing is closed”

 

Categories: Quality Tags: , , ,

Noah: Development Environment

Some time back I posted about various development tools that I would like to have in my

Development Environment ~ Eclipse

Development Environment ~ Eclipse

development environment. Well back then, I was unable to get that list in place; but here I have started doing it for Noah. To kick it off, I have attached the tools that I am going to use in the development environment. This is not an exhaustive list, and I may add more things to it as I go about development.

The document detailing the Development Environment can be located here: TS_Development_Environment

Mobile Web – In a different way

This presentation talks about how mobile web should be thought about and does talks about some numbers too. I like three things about the presentation:

 

1. The creativity with whcih it has been built and;

2. Talks about the core of the problem and;

3. Touches upon how we can go about fixing it.

The Architect’s Eye – Communicating Errors

In many of my projects, I have found architects guilty of preparing a design that leaves the error messages out of the question. And now, I come across an article that shows us 35 creative designs of showing a 404 page (http://www.onextrapixel.com/2011/03/09/the-secret-of-a-successful-error-page-with-35-amazing-404-page-designs/). As I was browsing some of these designs, I recall a designer I worked with – Beth. I learnt so much from her about design and especially Information Architecture. I have always found her looking at things differently be it work or a status update she did.

Coming back to error messages, in most applications I have noticed that error messages are cryptic like “An error has occurred, please check again and get back to System Administrator”. The user is needed to log a report with the call center and report what they were doing. Many a times a user would just ignore to do all that because it takes their time to do such stuff and they say we will come back and try another time – of course if it is not urgent. I see two issues here:

1. A user has been asked to do something that an application designer – An Architect could have done by designing the system right

2. The Application team has lost an opportunity of knowing where their application failed because a user chooses not to report it. They lost an opportunity to fix something pro-actively.

 

Categories: Design, Expert, Quality Tags: , ,

Who the hell needs Quality?

10 March, 2011 2 comments

I Do; you do; our customers do; Period

Well we all know the answer, but is it really what we believe in? The more important question is how do we choose to deliver quality when we can not measure it?

A few months back, I was sitting in a meeting where the conversation went something like

Business Person: So we need 24000 hours to deliver the scope of the release?

IT Person: Yes. But this does not include the hours needed to fix defects that we will have in the application at the end of development lifecycle.

Business Person: So how many defects we had in last release – I assume about 700?

IT Person: Yeah.

Business Person: So I can expect 2000 in this release? How much time do you need to fix one defect?

IT Person: About 16 hours per defect

I will let you do the math, but what made me fell out of my chair was the fact that everyone in the room was accepting the fact that even before we were developing the application we would have 66% of the time spent in fixing defects. Not even once did anyone asked, how can we ensure that we do not have so many defects in the application. Now even once did anyone asked if we already have Unit testing how come we still have these many number of defects.

Well, this is not the first time I heard this conversation and I am sure not the last time. But, I wonder how do people reach Architects, Project Managers, Program Managers and Directors IT if they have these discussions.

I did not say anything in the meeting, because I was supposed to sit there and listen which is another sad story. I could not even say anything to my IT team once the meeting was over; I was just not supposed to. Maybe, if someone who was in that meeting reads this and can co-relate I would be in a big shit of trouble; but I am going to risk it – do not know why.

I am someone who can not start writing a piece of code without having a unit test before it (Test Driven Development). But, then the projects I have been working lately do not even automated unit testing let along TDD. Their unit testing is done because they have to compliant with the Quality Process and at times it is done with a set of people who never coded it. The unit testing team works like a QA team but is withing the realms of the development team itself. And then there are times when Unit testing happens in parallel to System Testing.

This is a rant, where I hope I can pass a message around importance of testing.

 

Dilbert - Quality

Dilbert - Quality

 

 

 

 

 

 

 

 

Related Articles

Development Kit – your wishlist

11 January, 2011 1 comment

Today after a while I decided to get back to development and started to setup my Laptop with variety of development tools and my fetch my projects from hard drives. As I sit down to get started once again, I am thinking of what all should I get to get back to development. Also, this time I am not making something to sell or showcase but for something that I am going to now do for a hobby (I already have many project in office to take care off). And this time I want to do it like it is my baby. I will think over in next few days on what I have to build, but while I do it, I still need to decide on what all software I need to make that happen. I have been a Java guy for a long time and hence I am going to compile a list frameworks / software on the same platform.

What would you like to add?

Unit Testing

Unit testing is a way of testing a small unit of functionality. A unit is the smallest testable unit of program usually referred by a function, procedure etc which is a part of a class. Ideally, a unit test is independent of any other unit tests.

Benefits

The primary goal of a unit test is to isolate a smallest unit of a program and prove that it works correctly. A unit test can be referred to a requirement that a function should satisfy. This is the primary reason it has several benefits; one of the key benefit to find bugs early on in the development.

Facilitates Change

Unit testing allows a developer to refactor code at a later stage in the application development phase or in maintenance phase. It provides an umbrella ensuring that all the modules work correctly and as expected after that change. It is a great way identifying regression errors. The correct process if to write a unit test case for all methods and functions; so that if a change has introduced a defect it can be identified and quickly.

A good unit test suite ensures that all the paths in the code are covered including if-conditions and loops.

Simplifies Integration

Unit testing helps to eliminate defects and ambiguity in the functions themselves. This leads to a much simple integration approach when we want to test all the functions together. If we have all the methods do what they are expected to do, doing an integration testing automatically becomes easy.

Documentation

In last few years, how we document a code is changing. In past years, the community has been moving away from writing word documents and using Java Docs and inline comments. Unit testing can also provide a document to the system. Developers looking to ramp up on an application can use the unit testing to have a basic understanding of the application.

Unit test for a method encompass all testing scenarios. While positive test case provides information on how to use the method, a negative test case provided scenarios how not to use the method and what to expect.

While a normal textual document has a high likelihood of drifting away from the actual implementation, unit tests will remain aligned to the implementation. However, developers should not reply solely on unit tests for documentation.

Design

If you use Test Driven Development to develop software, Unit test can be used to provide a formal design. Each unit test can be looked at design specification providing information on interfaces, classes, methods, return types, error conditions. Let us look at the code sample below:

A test case that specifies there has to be a static class called MathUtil with a method called divide. This method takes two parameters of type int and returns a parameter of type double. In addition, you can expect an exception from the method.

public class TestMathUtil
{
Public void testDivide()
{
Double result = MathUtil.divide(10, 2);
assertTrue(result, 5);

try
{
Double resultError = MathUtil.divide(10, 0);
assertFail(“We expect an exception);
}
catch(Exception ex)
{
assertTrue(ex.getMessage(), “Divide by zero”);
}
}

You can clearly see that how looking at this test case a developer (consumer) of the MathUtil class understands the requirements. One significant advantage of using Unit testing as design element over UML based design is ensuring that the implementation adheres to the design. A developer reading a UML diagram can potentially name the class MathUtilities, which will instantly make the design disharmonious with implementation.
However, now we have code generation tools available for all major languages that eliminate such inconsistencies.

Limitations of Unit Testing

We can expect to catch all errors during testing – it is impossible to evaluate all possible paths for all but trivial scenarios. This is as applicable to unit testing as it is applicable to other forms of testing.

Unit testing by definition, tests only units of functionality and does not guarantee catching integration errors; it only facilitates integration. Unit testing may not catch integration errors across multiple units.

Effort needed

Software testing is combinational problem. For every decision case, we need at-least two test cases. If you have complex conditional logics, the complexity of unit test cases will increase exponentially. As a result, there will be times when the code written for test cases will be mush more than the code itself.

Discipline

To achieve the most from unit testing activity, a team needs rigorous sense of discipline throughout the software development lifecycle. It is most essential to keep a record of failing test cases. A very close eye has to be kept on when test cases fail. There should be a process in place ensuring review of test case failures every day and addressing them actively.

Use of a Continuous Integration tool is a most common practice in the software development lifecycle to through out test cases results post a build cycle.

A Team should also consider using a version control for the development process so that they can look at various baseline versions for changes in code to identify regression scenarios.

Writing unit test is an art

It is very easy to get overwhelmed when starting to write unit test cases. The best way is to create unit test cases for new code. Although, it is possible to create unit test cases for existing code but it is not worth the effort. Start with the new code added to the application, get familiar with the process and then revisit the decision to write test cases for existing code.

Mastering the technique for unit test cases if 95% mental and 5% technical. You have to be patient with the Java Compiler. When creating a new test cases you should assume that the class or the method exist. Stick to the various syntax errors that are displayed. When you write your class things will come to order.

Getting developers to think like testers will be your greatest challenge. Many projects that I have seen fail unit testing, fail for this reason.

Walking the fine line

Very often it is not clear when a test cases is actually a functional test case. TO be honest, it is not clear to me if I know the line myself. However, I try to stick to the following guidelines. A unit test case might be a functional test case:

  • If a unit test cases crosses class boundaries;
  • If a unit test case is becoming complicated
  • If a unit test case becomes fragile
  • If a unit test case is harder to write than the code itself
  • If a unit test case has lots of asserts

Remember, there are no rules. If you find another approach that works for you, best feel free to use it. Be careful to document it so that the entire team can use it consistently.

Categories: Beginner, Intermediate, Quality Tags:

Managing Code

Do you write code locally for personal use/reference? If the answer is yes, then this post is for you. For others, it may be worth still to read it.

I have been working on a set of projects for last few weeks. Today, I wanted to make some major and possibly destructive changes to the code base. Before I started to change code, I took a backup of the local folder into another folder so that I have a revert point. At this point it hit me – I am missing version control, that I enjoy in my corporate world.

I dropped everything and started to setup my laptop with the version control. I did the following:

1. Downloaded SmartSVN or TortoiseSVN as subversion client and install on your machine.’

2. Download Subversion client for windows from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=8100

3. Downoad Apache HTTP server to front-end the subversion server from http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91

4. Install svn client and apache. Steps are simple and can be found with the downloads.

5. Configure Apache wotk with SVN. Read the post http://svnbook.red-bean.com/en/1.0/ch06s04.html

6. Start Apache and hit http://localhost:80/svn/. Provide a different port number in case you changed the apache configurations.

7. Create a local repository on your hard disk by using the command line “svnadmin create foo”. This will create a repository in the same folder from where you ran the command.

8. Open a browser and type http://localhost:80/svn/foo. This will show a repository view to you.

Whola, you have your code base in repository. Enjoy it!!

Is Defect a defect when not defined in a Test Script?

18 April, 2008 3 comments

This question came up during an email thread that I had with some testers. Most of the testers had the view that a defect can be a defect even if it has not been defined in a test script, while I said that this is not true. The conversation went like this:

Tester: We can not put every scenario in a test script

ME: Yes you can

Tester: Can not because we can not think of scenarios while writing test scripts

ME: Then you should. Testers also think when they are testing, so what stops them from thinking when they are creating test scripts

Tester: It is not possible and also it is not feasible

ME: Not possible, I will disagree. Let us focus on the Not Feasible part

Tester: It becomes very difficult to document everything as then the scripts will run into multiple pages and maintaining them would be an overhead

ME That is not reason enough not to capture all that can be in a test script. You have to accept the fact that a test script can be incorrect. For a defect to be a defect, it has to be mapped against a missing requirement that should come from a document that can a client would have provided. If you can not provide a document/reference for the missing functionality, then there is not reason you can call it a defect. It is fine to log it as a TAR and discuss as a change request, but a defect i do not agree to.

Beyond this point, I started finding testers fumbling for words. No one out there could give me a solid answer to convince me. What are your views on the same? I blogged about why do i do unit testing and why do i feel we can cover all the scope in a test script. We developers do that for Unit testing, why can testers not?

Categories: Quality Tags:
Follow

Get every new post delivered to your Inbox.