我想编写火花单元测试用例,我正在使用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。 但那么我们怎样才能实现我的目的,即在所有测试用例都运行时,火花上下文只会被触发一次
答案 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的生命周期。
您不必通过覆盖beforeAll
,afterAll
方法和管理sparkSession
/ sparkContext
的生命周期来污染测试。
通过覆盖以下方法,您可以为所有测试共享一个sparkSession
/ sparkContext
:
def reuseContextIfPossible: Boolean = true
了解更多详细信息:https://github.com/holdenk/spark-testing-base/wiki/SharedSparkContext
希望对您有帮助!