2011-04-15 13 views
9

मेरे पास जुनीट टेस्ट सूट में आयोजित परीक्षणों का एक समूह है। ये परीक्षण वेब अनुप्रयोग का परीक्षण करने के लिए सेलेनियम का बहुत उपयोग कर रहे हैं। तो, सेलेनियम के लिए स्वाभाविक, इन परीक्षणों का रनटाइम काफी लंबा है। चूंकि सुइट्स में टेस्ट क्लासेस समानांतर नहीं चल सकते हैं क्योंकि परीक्षण डेटाबेस में कुछ ओवरलैप होते हैं, इसलिए मैं सूट समानांतर चलाने के लिए चाहता हूं।सुइट लेवल पर समानांतर में जुनीट टेस्ट चला रहा है?

जुनीट समांतर कंप्यूटर केवल समानांतर में कक्षा या विधि स्तर पर परीक्षण निष्पादित कर सकता है, क्या जुनीट के सूट के साथ ऐसा करने के लिए कोई मानक तरीका है?

यदि मैं सिर्फ जूनिट धावक को सूट कक्षाएं पास करता हूं और कंप्यूटर स्तर को समानांतर करने के लिए कंप्यूटर को कॉन्फ़िगर करता हूं, तो यह परीक्षण कक्षाओं को स्वयं करता है, सूट नहीं।

br फ्रैंक

उत्तर

1

के बाद से सुइट एक कक्षा व्याख्या करते हैं, तो JUnitCore.runClasses(ParallelComputer.classes(), cls) तरह से सूट-एनोटेट वर्ग को चलाने के लिए प्रयोग किया जाता है। cls सूट-एनोटेटेड कक्षाएं हैं।

@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
Test1.class, 
Test2.class}) 
public class Suite1 { 
} 

@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
Test3.class, 
Test4.class}) 
public class Suite2 { 
} 
... 
JUnitCore.runClasses(ParallelComputer.classes(), new Class[]{Suite1.class, Suite2.class}) 
+0

हाय, प्रश्नोत्तरी उत्तर के लिए धन्यवाद। अफसोस की बात यह है कि यह मेरे इरादे से परीक्षण नहीं चलाता है। जैसा कि मैंने अपने प्रश्न के अंत में लिखा था, यह स्वीट सूट के अंदर परीक्षण कक्षाओं को चलाता है, न कि सूट स्वयं। – Frank

+0

आपका उदाहरण निम्न तरीके से निष्पादित करता है: टेस्ट 1 और टेस्ट 2 समानांतर चलते हैं, वास्तव में व्यवहार को मुझे रोकना चाहिए। – Frank

+0

आपका स्वागत है! अगर मेरा कोड आपकी मदद नहीं कर सकता है, तो आप अपने सूट चलाने के लिए बहु थ्रेड लिख सकते हैं (यदि कोई बेहतर समाधान नहीं है)। –

8

यहां कुछ कोड है जो मेरे लिए काम करता है। मैंने यह नहीं लिखा था। यदि आप @RunWith(Suite.class) के बजाय @RunWith(ConcurrentSuite.class) का उपयोग करते हैं तो इसे काम करना चाहिए। एक एनोटेशन है जिसे नीचे भी पाया जाता है।

package utilities.runners; 

import org.junit.internal.builders.AllDefaultPossibilitiesBuilder; 
import org.junit.runner.Runner; 
import org.junit.runners.Suite; 
import org.junit.runners.model.InitializationError; 
import org.junit.runners.model.RunnerBuilder; 
import org.junit.runners.model.RunnerScheduler; 

import utilities.annotations.Concurrent; 

import java.util.Arrays; 
import java.util.LinkedList; 
import java.util.List; 
import java.util.Queue; 
import java.util.concurrent.CompletionService; 
import java.util.concurrent.ExecutorCompletionService; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.concurrent.ThreadFactory; 
import java.util.concurrent.atomic.AtomicInteger; 

/** 
* @author Mathieu Carbou ([email protected]) 
*/ 
public final class ConcurrentSuite extends Suite { 
    public ConcurrentSuite(final Class<?> klass) throws InitializationError { 
     super(klass, new AllDefaultPossibilitiesBuilder(true) { 
      @Override 
      public Runner runnerForClass(Class<?> testClass) throws Throwable { 
       List<RunnerBuilder> builders = Arrays.asList(
         new RunnerBuilder() { 
          @Override 
          public Runner runnerForClass(Class<?> testClass) throws Throwable { 
           Concurrent annotation = testClass.getAnnotation(Concurrent.class); 
           if (annotation != null) 
            return new ConcurrentJunitRunner(testClass); 
           return null; 
          } 
         }, 
         ignoredBuilder(), 
         annotatedBuilder(), 
         suiteMethodBuilder(), 
         junit3Builder(), 
         junit4Builder()); 
       for (RunnerBuilder each : builders) { 
        Runner runner = each.safeRunnerForClass(testClass); 
        if (runner != null) 
         return runner; 
       } 
       return null; 
      } 
     }); 
     setScheduler(new RunnerScheduler() { 
      ExecutorService executorService = Executors.newFixedThreadPool(
        klass.isAnnotationPresent(Concurrent.class) ? 
          klass.getAnnotation(Concurrent.class).threads() : 
          (int) (Runtime.getRuntime().availableProcessors() * 1.5), 
        new NamedThreadFactory(klass.getSimpleName())); 
      CompletionService<Void> completionService = new ExecutorCompletionService<Void>(executorService); 
      Queue<Future<Void>> tasks = new LinkedList<Future<Void>>(); 

      @Override 
      public void schedule(Runnable childStatement) { 
       tasks.offer(completionService.submit(childStatement, null)); 
      } 

      @Override 
      public void finished() { 
       try { 
        while (!tasks.isEmpty()) 
         tasks.remove(completionService.take()); 
       } catch (InterruptedException e) { 
        Thread.currentThread().interrupt(); 
       } finally { 
        while (!tasks.isEmpty()) 
         tasks.poll().cancel(true); 
        executorService.shutdownNow(); 
       } 
      } 
     }); 
    } 

    static final class NamedThreadFactory implements ThreadFactory { 
     static final AtomicInteger poolNumber = new AtomicInteger(1); 
     final AtomicInteger threadNumber = new AtomicInteger(1); 
     final ThreadGroup group; 

     NamedThreadFactory(String poolName) { 
      group = new ThreadGroup(poolName + "-" + poolNumber.getAndIncrement()); 
     } 

     @Override 
     public Thread newThread(Runnable r) { 
      return new Thread(group, r, group.getName() + "-thread-" + threadNumber.getAndIncrement(), 0); 
     } 
    } 

} 

और एनोटेशन निम्नानुसार है।

package utilities.annotations; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

/** 
* @author Mathieu Carbou ([email protected]) 
*/ 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ ElementType.TYPE }) 
public @interface Concurrent { 
    int threads() default 5; 
} 
+1

ऐसा लगता है कि इस कोड की एक प्रति इस यूआरएल पर उपलब्ध है http://mycila.googlecode.com/svn/sandbox/src/main/java/com/mycila/sandbox/junit/runner/ –

+0

हां, मुझे शामिल होना चाहिए था सम्बन्ध। धन्यवाद। –

+0

यह एक अतिरिक्त निर्माता को जोड़ने के बाद काम किया: \t सार्वजनिक ConcurrentSuite (कक्षा klass, RunnerBuilder बिल्डर) फेंकता InitializationError { \t \t इस (klass); \t} –