我正在尝试在Spark中运行多个单元测试,并从源代码中复制(并略微调整)该位:
import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}
import org.scalatest.{BeforeAndAfterAll, Suite}
trait SharedSparkContext extends BeforeAndAfterAll {
self: Suite =>
@transient private var _sc: SparkContext = _
@transient private var _sqlContext: SQLContext = _
def sc: SparkContext = _sc
def sqlContext: SQLContext = _sqlContext
private var conf = new SparkConf(false)
override def beforeAll() {
super.beforeAll()
_sc = new SparkContext("local[*]", "Test Suites", conf)
_sqlContext = new SQLContext(_sc)
}
override def afterAll() {
try {
LocalSparkContext.stop(_sc)
_sc = null
} finally {
super.afterAll()
}
}
}
只需从源中复制带有伴随对象的LocalSparkContext类。
我考虑过如下使用它,它告诉我stable identifier required
,因为def
sqlContext
没有成员implicits
:
class MySuite extends FlatSpec with SharedSparkContext {
import sqlContext.implicits._
// ...
}
我尝试用以下内容替换它,但这给了我空指针异常:
class MySuite extends FlatSpec with SharedSparkContext {
val sqlCtxt = sqlContext
import sqlCtxt.implicits._
// ...
}
我使用的是Spark 1.4.1,我设置了parallelExecution in test := false
。
如何才能使其工作(不使用其他软件包)?
答案 0 :(得分:2)
您可以使用包含所有变量的简单对象,而不是使用特征,这是我为测试所做的事情:
object TestConfiguration extends Serializable {
private val sparkConf = new SparkConf()
.setAppName("Tests")
.setMaster("local")
private lazy val sparkContext = new SparkContext(sparkConf)
private lazy val sqlContext = new SQLContext(sparkContext)
def getSqlContext() = {
sqlContext
}
}
然后,您将能够在测试套件中使用sqlContext。
class MySuite extends FlatSpec with SharedSparkContext {
val sqlCtxt = TestConfiguration.getSqlContext
import sqlCtxt.implicits._
// ...
}