1

我有一个用于 Web 测试的应用程序(基于 Selenium,但这在这里应该无关紧要),它连续执行了相当多的测试用例。完成需要几个小时,并且测试用例的数量会增加,所以我想使用多个 Web 浏览器实例来并行执行多个测试用例。测试用例之间没有依赖关系。

非常简化它看起来像这样:

TestExecutor executor = new TestExecutor(new FirefoxDriver());
for (TestCase test: tests) {
    executor.execute(test);
    // use results here
}

现在我不知道如何并行化它。我可以轻松地创建几个连接到多个 Web 浏览器的 TestExecutor 作为 Callables,并使用 Executors、CompletitionServices 和其他不错的帮助类,但我该怎么做:

  • 一旦准备好之前的TestCase,将新的TestCase 传递给TestExecutor?Callable 中的 call() 方法不接受任何参数,因此我可能必须在我的 TestExecutor 类中实现一些 setNextTestCase() 来实现这一点,我觉得这不是很好。有没有更好的选择?

  • 重用 TestExecutor 实例来执行下一个测试用例?由于每个 TestExecutor 实例都需要一个 Web 浏览器实例,因此初始化它需要很长时间,并且如果我为每个测试用例创建一个新的 TestExecutor 会导致许多窗口在屏幕上闪烁。

4

2 回答 2

5

一旦准备好之前的TestCase,将新的TestCase 传递给TestExecutor?

如果我理解你的话,这是一个常见的问题。您在线程池中有许多线程,但每个线程都有一些上下文 - 在本例中是“Web 浏览器”。您不想为每个提交到线程池的作业启动一个新的浏览器。

以下是有关如何完成此任务的一些想法。

  • 拥有一个BlockingQueue对象TestCase。然后,您的每个线程都初始化它们的浏览器,然后从TestCase对象队列中出列,直到队列为空或某些关闭布尔值设置为 true。您可以将TestExecutor对象提交到线程池中,但他们会TestCase通过您自己的队列对对象进行自己的出队。您不会将其提交TestCase到线程池。

    BlockingQueue<TestCase> testCaseQueue = new LinkedBlockingQueue<>();
    for (TestCase test: tests) {
        testCaseQueue.add(test);
    }
    // now make your executors and run them in a thread-pool
    TestExecutor testExecutor =
         new TestExecutor(new FirefoxDriver(), testCaseQueue);
    ExecutorService threadPool = Executors.newCachedThreadPool();
    threadPool.submit(testExecutor);
    ...
    // once you've submitted your last executor, you shutdown the pool
    threadPool.shutdown();
    
    ...
    // inside of the executor, they dequeue tests from `testCaseQueue`
    while (!shutdown) {
        TestCase testCase = testCaseQueue.poll(0, TimeUnit.MILLISECONDS);
        if (testCase == null) {
           break;
        }
        ...
    } 
    
  • 另一个想法是将 提交TestCase到线程池并使用 aThreadLocal来获取先前配置的浏览器进行测试。这不是最优的,因为它使得在测试完成时很难适当地终止浏览器。

于 2013-09-23T13:45:06.303 回答
0

我建议设置Queue/ Listof TestExecutors。然后创建一个Callable/Runnable来包装TestCase. 您ExecutorService将拥有与您相同数量的List线程TestExecutors。的第一步RunnableTestExecutorQueue. 它将利用执行程序进行测试,然后在完成后将其放回队列中。

于 2013-09-23T13:42:28.340 回答