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 中)的主要内容,如果未能解决你的问题,请参考以下文章