所以我试图运行并行参数化测试。我有一个解决方案,其中相同的测试可以与提供的参数并行运行,例如,我有以下内容:
@Test
public void someTest1(){
}
@Test
public void someTest2(){
}
我可以让someTest1()同时运行所有参数,但someTest2()在执行之前仍然需要等待someTest1()完成所有参数。我想知道是否有人知道一个解决方案能够同时运行带有所有参数的someTest1()和带有所有参数的someTest2()?我已经尝试了tempus-fugit concurrent test runner,这对于没有参数化的测试非常有用......
以下是我目前并行运行每个参数测试的代码。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.runners.Parameterized;
import org.junit.runners.model.RunnerScheduler;
/**
* Class used from the following source:
* http://jankesterblog.blogspot.com/2011/10
* /junit4-running-parallel-junit-classes.html
*
* @author Jan Kester
*
*/
public class Parallelized extends Parameterized {
private static class ThreadPoolScheduler implements RunnerScheduler {
private ExecutorService executor;
public ThreadPoolScheduler() {
String threads = System.getProperty("junit.parallel.threads", "16");
int numThreads = Integer.parseInt(threads);
executor = Executors.newFixedThreadPool(numThreads);
}
public void finished() {
executor.shutdown();
try {
executor.awaitTermination(12, TimeUnit.HOURS);
} catch (InterruptedException exc) {
throw new RuntimeException(exc);
}
}
public void schedule(Runnable childStatement) {
executor.submit(childStatement);
}
}
/**
* Instantiates a new parallelized.
*
* @param klass
* the klass
* @throws Throwable
* the throwable
*/
public Parallelized(Class<?> klass) throws Throwable {
super(klass);
setScheduler(new ThreadPoolScheduler());
}
}
以下代码是一个示例测试,BaseSuite不包含任何重要的内容。这些与selenium一起使用,所以它只是设置webDriver。 getAllButOpera()方法返回包含Internet Explorer,Firefox和Chrome的浏览器类型集合。这些参数用于在firefox上同时运行相同的测试,即和chrome。我想同时在课堂上进行两个测试,这是我遇到的麻烦。
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.Collection;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized.Parameters;
import org.openqa.selenium.WebDriver;
/**
* The Class SampleSuite1.
*
* @author Reid McPherson
*/
@RunWith(Parallelized.class)
public class SampleSuite1 {
WebDriver driver;
/**
* Data.
*
* @return the collection
*/
@Parameters
public static Collection<Object[]> data(){
List<Object[]> browsers = new ArrayList<Object[]>();
browsers.add(new String[]{"Firefox"});
browsers.add(new String[]{"Chrome"});
browsers.add(new String[]{"IE"});
return browsers;
}
/**
* Instantiates a new sample suite1.
*
* @param type
* the type
*/
public SampleSuite1(String type){
switch (type) {
case "FIREFOX":
driver = new FirefoxDriver();
break;
case "IE":
driver = new InternetExplorerDriver();
break;
case "CHROME":
System.setProperty("webdriver.chrome.driver", PATHTOCHROMEEXE);
driver = new ChromeDriver();
break;
case "OPERA":
driver = new OperaDriver();
break;
default:
throw new RuntimeException("Browser type unsupported");
}
// Set the timeout.
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
}
/**
* Sets the up.
*/
@Before
public void setUp() {
driver.get("http://www.google.com");
}
/**
* Test navigation succeeded.
*/
@Test
@TestDescription("Navigation Test")
public void navigationShouldSucceed() {
String pageSource = driver.getPageSource();
assertTrue(pageSource.contains("Google"));
}
/**
* Test title.
*/
@Test
@TestDescription("This method tests the web page title.")
public void titleShouldBeGoogle() {
assertEquals(driver.getTitle(), "Google");
}
@After
public void finished(){
driver.close();
}
}
答案 0 :(得分:5)
正如我所说,问题在于JUnit的实现。
你可以看到:
Parallelized extends Parametrized extends Suite extends ParentRunner
另一方面:
ConcurrentTestRunner extends BlockJUnit4ClassRunner extends ParentRunner
因此它们来自不同的继承层次。
现在你要看的是:
的实现org.junit.runners.ParentRunner#getChildren
方法。对于org.junit.runners.BlockJUnit4ClassRunner,它是:
protected List<FrameworkMethod> computeTestMethods() {
return getTestClass().getAnnotatedMethods(Test.class);
}
生成带注释的所有方法。但是对于org.junit.runners.Parameterized它是:
for (int i= 0; i < parametersList.size(); i++)
runners.add(newtestClassRunnerForParameters(getTestClass().getJavaClass(),
parametersList, i));
最后一个只提供课程。
提案:使用org.junit.runners.ParentRunner#getChildren from BlockJUnit4ClassRunner
的定义覆盖您的Parallelized类。
答案 1 :(得分:1)
感谢您的帮助,除了运行并发套件之外,我最终还使用了here中的代码,它使我能够同时运行测试,但它不会同时运行相同的测试。
答案 2 :(得分:0)
我也在使用Jeeunit的代码......但即便版本1.0也有错误。
在ConcurrentRunnerScheduler中必须实施已完成的方法。
所以我只是拉了代码并像suiteFinished()方法一样实现它:
@Override
public void finished() {
try {
while (!tasks.isEmpty())
tasks.remove(completionService.take());
}
catch (InterruptedException e) {
System.out.println("suite fin");
Thread.currentThread().interrupt();
}
finally {
while (!tasks.isEmpty())
tasks.poll().cancel(true);
executorService.shutdownNow();
}
}
答案 3 :(得分:-1)
这是我尝试过的,对我来说效果非常好。
public class ParallelTests {
static ExecutorService eService ;
public static void main(String[] args) {
testA() ;
testB() ;
testC() ;
}
public static void testA() {
eService = Executors.newCachedThreadPool() ;
for (int i = 0 ; i < 10 ; i++) {
TestA testA = new TestA() ;
eService.execute(testA) ;
}
eService.shutdown() ;
while(!eService.isShutDown()) {
}
}
//same for testB and testC
}
public class TestA implements Runnable {
public TestA() {
}
@Test
public myTest throws Throwable {
}
}