Spark 单元测试(在 intellij 中)

Posted

技术标签:

【中文标题】Spark 单元测试(在 intellij 中)【英文标题】:Spark unit tests (in intellij) 【发布时间】:2016-02-18 11:47:44 【问题描述】:

我的 intellij 项目中有一些 Spark 单元测试。当我一个一个(逐个文件)启动它们时,一切正常。当我想测试所有包时,我得到了:

异常或错误导致运行中止:此 JVM 中只能运行一个 SparkContext(请参阅 SPARK-2243)。要忽略此错误,请设置 spark.driver.allowMultipleContexts = true。

我已经读过将 spark.driver.allowMultipleContexts 设置为 true 是危险的:-/

有没有办法告诉 intellij 一个一个地运行测试。

【问题讨论】:

【参考方案1】:

Spark 本身带有使用带有a shared Spark 上下文的特征的单元测试,因此您不必使用多个。您可以复制它并在自己的测试中使用它。

但是,我仍然遇到一些问题,即 IntelliJ 中的测试并行访问上下文。可以让您的所有测试串行运行,但我使用带有锁的以下版本的特征,以便 Spark 测试串行运行,其他测试仍然可以并行运行:

import org.apache.spark.SparkContext, SparkConf
import org.scalatest._

import scala.concurrent.Lock

object Spark 
  val lock = new Lock()


trait Spark extends BeforeAndAfterAll  self: Suite =>
  @transient private var _sc: SparkContext = _

  def sc: SparkContext = _sc

  var conf = new SparkConf(false)

  override def beforeAll() 
    Spark.lock.acquire()
    _sc = new SparkContext("local[4]", "test", conf)
    super.beforeAll()
  

  override def afterAll() 
    if (_sc != null) 
      _sc.stop()
    
    Spark.lock.release()

    // To avoid Akka rebinding to the same port, since it doesn't unbind immediately on shutdown
    System.clearProperty("spark.driver.port")

    _sc = null
    super.afterAll()
  

你可以像这样在你的测试中使用这个特性:

class MySpec extends FlatSpec with Spark 
  "I" should "be able to use Spark" in 
    sc.parallelize(Seq(1, 2, 3, 4, 5))
  

【讨论】:

看起来是一个完美的解决方案,但为什么我有 import org.scalatest.BeforeAndAfterAll, Suite 提出对象 scalatest 不是包 org 的成员。我的 build.sbt 中有这个: "org.scalatest" % "scalatest_2.10" % "2.2.1" % "test", 我不确定,但我看到你把它放在一个单独的问题中。让我们知道它是否适用。 它有点工作,但我不得不把这个文件放在 src/test/scala 目录中,而不是 src/main/scala。所以我必须在我所有的项目中公开它:-/谢谢【参考方案2】:

在每个测试中,在测试结束时,关闭 spark 上下文并在下一个测试开始时再次创建它:

sparkContext.stop()

还有:

val sparkContext = new SparkContext()

【讨论】:

以上是关于Spark 单元测试(在 intellij 中)的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 sbt 在本地运行 spark 作业,但可以在 IntelliJ 中运行

使用 intellij 运行时单元测试中的系统属性

如何在 intellij 中为播放框架应用程序运行单元测试

排除在 IntellIJ 中运行的测试

使用JUnit配置IntelliJ IDEA以进行单元测试

转载IntelliJ IDEA配置JUnit进行单元测试