Search code examples
javamultithreadingmaventestngproducer-consumer

TestNG tests synchronization on outer object


My situation in short: I want to perform parallel tests. Lets say I have 4 credential pairs and 32 tests that will be run in 8 parallel threads (on parallel method level). So I have standart producer-consumer situation but beetween parallel tests.

My idea is to have list of credential objects (on which I will synchronize test threads in "beforeMethod" phase). First 4 threads will get their credentials and remove them from list. All other threads will see empty list and wait ON it.

First test that will finish its execution and will add used credentials back to list on "afterMethod" phase and invoke notify on this list, and so on. But the problem is that I dont have any proper place where I can locate this list of credentials + I want to use simple "mvn test" for starting this process. Any ideas how can I add such synchronization? If there is some similar functionality in TestNG - please tell.


Solution

  • Solved. Main problem was to override TestNG lifecycle + save maven test management. So I started to dig TestNG source code and came to next solution:

    1. Extend IExecutionListener which will store needed data (queue) as a public static final member.
    2. Same interface IExecutionListener participates in TestNG lifecycle: it has lifecycle callbacks onExecutionStart and onExecutionFinish. First one were used to populate queue with credentials from file, and second one is to ease GC work - clean this queue.
    3. Populated queue was used inside of init method annotated with @BeforeMethod. Note: do not store value from queue as a plain member as you'll face overwriting of this member from different threads that performs tests from same class but different tests. Use ThreadLocal to provide thread isolation of this variable.
    4. Special data structure that serves good for my case is BlockingQueue (in LinkedBlockingQueue implementation) with take and put as getter/setter.
    5. Also do not forget to add your custom listener to your xml