Spark单元测试:如何使用FunSuite为所有套件初始化sc一次

时间:2016-03-02 15:49:47

标签: scala apache-spark spark-streaming scalatest

我想编写火花单元测试用例,我正在使用FunSuite。 但我希望我的sparkContext只初始化一次,由所有套件使用,然后在所有套件完成后被杀死。

abstract class baseClass extends FunSuite with BeforeAndAfter{
  before {
    println("initialize spark context")
  }
  after {
    println("kill spark context")
  }

}



@RunWith(classOf[JUnitRunner])
class A extends baseClass{
test("for class A"){
//assert
}

@RunWith(classOf[JUnitRunner])
class B extends baseClass{
test(for class b){
//assert
}
}

但是当我运行sbt test时 我可以看到从两个测试中调用了println语句baseClass。无意中为A和B类,Abstract创建了对象 调用baseclass。 但那么我们怎样才能实现我的目的,即在所有测试用例都运行时,火花上下文只会被触发一次

3 个答案:

答案 0 :(得分:1)

选项1 :使用优秀的https://github.com/holdenk/spark-testing-base库(并提供许多其他好处)。在阅读完自述文件之后,它就像混合SharedSparkContext而不是baseClass一样,并且您的测试中有sc: SparkContext值可供使用

选项2 :要自己动手,您想要混合BeforeAndAfterAll而不是BeforeAndAfter,并实施beforeAll和{ {1}},这正是上面提到的afterAll所做的。

答案 1 :(得分:0)

如果您真的想要在套件之间共享上下文,那么您必须将其设置为静态。然后,您可以使用lazy值使其在首次使用时启动。关闭它 - 你可以将它留给每次创建上下文时创建的自动关闭钩子。

看起来像是:

abstract class SparkSuiteBase extends FunSuite {
    lazy val sparkContext = SparkSuiteBase.sparkContext
}

// putting the Spark Context inside an object allows reusing it between tests
object SparkSuiteBase {
    private lazy val sparkContext = ??? // create the context here
}

答案 2 :(得分:0)

我强烈建议使用spark-testing-base库,以便在测试期间管理sparkContext或sparkSession的生命周期。 您不必通过覆盖beforeAllafterAll方法和管理sparkSession / sparkContext的生命周期来污染测试。

通过覆盖以下方法,您可以为所有测试共享一个sparkSession / sparkContextdef reuseContextIfPossible: Boolean = true

了解更多详细信息:https://github.com/holdenk/spark-testing-base/wiki/SharedSparkContext

希望对您有帮助!