TestNG - parallel test execution - example - unique ID generator

Today I played with unique IDs generator. While doing this, I have found how very useful is one of the features of TestNG framework - its ability to run tests in parallel.

You will find much more about testing in my book
"Practical Unit Testing
with TestNG and Mockito"

Some info

At the time of writing this post the latest version of TestNG is 5.9, and for jUnit it is 4.6.

At the end of this text you'll find source code. See the readme.txt file and read javadocs.

First version

Somewhere in project X I encountered a code like this:

public interface IdGenerator {

Long nextId();

}

public class NaiveIdGenerator implements IdGenerator {

// TODO change it
public Long nextId() {
return System.currentTimeMillis();
}
}

Please notice the source code attached at the end of this text.

There were no real tests for this piece of code (grrrr.....) which made me very suspicious, so I decided to take a closer look.
The other reason for my interest in this snippet of code was, that I knew that System.currentTimeMillis can't be really trusted for such a job (see here or search the web for more info).

My first test looked like this:

@Test
public class NaiveIdGeneratorTest {

private IdGenerator idGen = new NaiveIdGenerator();

public void idsAreUnique() {
Long idA = idGen.nextId();
Long idB = idGen.nextId();
assert !idA.equals(idB);
}
}

The test FAILED. Which means, the NaiveIdGenerator is flawed. :(

Second version

Ok, it's time to make the test PASS. Here comes the second attempt:

public class BetterNaiveIdGenerator implements IdGenerator {

private static Long nextId = System.currentTimeMillis();

public Long nextId() {
return nextId++;
}
}

Is it any better ? The test described above PASSED, so it is better, isn't it ?

Second test

Well, not really. It's still working only "sometimes". Why ? Because ++ operations are not atomic ! Apparently there are "more atomic" than previous version, because this test sometimes will pass, but it's not enough for the unique IDs generator, right ?

To reveal the bug, I used a nice feature of TestNG framework - running tests in parallel.

public class BetterNaiveIdGeneratorParallelTest {

private IdGenerator idGen = new BetterNaiveIdGenerator();
private Set<Long> ids = new HashSet<Long>(100);

@Test(threadPoolSize = 7, invocationCount = 100)
public void idsAreUnique() {
assertTrue(ids.add(idGen.nextId()));
}
}

Important - this test will sometimes PASS and sometimes will FAIL (at least that what happens on my machine).

As you can see I use Set API to check if generated ID is unique.

Third version

Finally, I came to the following solution (I copied & pasted it from somewhere, to be honest):

public class JVMUniqueIdGenerator implements IdGenerator {

private static final AtomicLong nextId = new AtomicLong(System
.currentTimeMillis());

public Long nextId() {
return nextId.getAndIncrement();
}
}

This one PASSES all tests I could imagine.

But what about jUnit ?

Once again TestNG has offered feature that I needed. I tried to find the similar solution for jUnit, but I couldn't. Well, there is a separate project parallel-junit, but come on, I have it out-of-the-TestNG-box, so why should I bother ?

AttachmentSize
testng-parallel-0.1-SNAPSHOT-src.zip8.38 KB

TestNG capabilities

Hi,
TestNG parallel execution of tests is awesome but I have encountered a problem with this framework. When I tried to test some code, dependent of a repository, it seems that there were no transactions started and the tests failed because of concurrent repository changes. Do you have a solution for this problem?

With regards,
Nikola Geneshki.

testng runnung tests in parallel

Can you please let me know how to use this feature of testng- running tests in parallel.

I tried following the documentation and used this tag in testng.xml and it errors out.

Am I missing something here.

Thanks
C

no details - no help :)

Hello Anonymous,

can't help you with this level of details that you provided, sorry.

It would be much better if you write to testng users list http://groups.google.com/group/testng-users but please include all the information that can help to solve your problem - testng.xml and error at least.

--
Cheers,
Tomek Kaczanowski

try mailing list

Hello Nikola,

sorry, I can't help you with this one. I think you should ask on TestNG mailing list. Surely someone there will know how to help you.

--
Cheers,
Tomek Kaczanowski

good discussion

Hi Guys, this is an excellent example on transaction and parallel programming. I recommend one book Transaction Processing written by Jim Gray. In this book, you will find the basic knowledge of transaction, as well as parallel programming. This is an important coding skill, especially if you do database programming or distributed programming. I have read the book, very nice. - bmr calculator | bmi calculator | calories burned by heart rate

 
 
 
This used to be my blog. I moved to http://tomek.kaczanowscy.pl long time ago.

 
 
 

Please comment using