Scala 使用FunSuite测试Spark抛出NullPointerException
我想通过使用名为Scala 使用FunSuite测试Spark抛出NullPointerException,scala,apache-spark,scalatest,Scala,Apache Spark,Scalatest,我想通过使用名为localTest的新函数扩展FunSuite来测试我的作业,该函数使用默认的SparkContext运行测试: class SparkFunSuite extends FunSuite { def localTest(name : String)(f : SparkContext => Unit) : Unit = { val conf = new SparkConf().setAppName(name).setMaster("local") val
localTest
的新函数扩展FunSuite来测试我的作业,该函数使用默认的SparkContext运行测试:
class SparkFunSuite extends FunSuite {
def localTest(name : String)(f : SparkContext => Unit) : Unit = {
val conf = new SparkConf().setAppName(name).setMaster("local")
val sc = new SparkContext(conf)
try {
this.test(name)(f(sc))
} finally {
sc.stop
}
}
}
然后,我可以轻松地将测试添加到我的测试套件中:
class MyTestSuite extends SparkFunSuite {
localTest("My Spark test") { sc =>
assertResult(2)(sc.parallelize(Seq(1,2,3)).filter(_ <= 2).map(_ + 1).count)
}
}
是什么导致了NullPointerException
?在这种情况下,我使用Spark的方式是否不正确
我将Scala 2.10.4与spark core一起使用。
1.0.2和scalatest
2.2.2。这不起作用的原因是我误用了FunSuite.test
。此方法在调用时注册一个新的测试,即在构造FunSuite
时。然后在运行测试时调用该测试。但是我的localTest
在调用FunSuite.test前后都会执行一些操作。特别是,在使用this.test(name)(f(sc))
注册测试后,它会停止SparkContext
。调用测试时,sc
停止,并导致sparkcontext
的taskScheduler
字段上出现NullPointerException
。使用FunSuite的正确方法是:
import org.scalatest.FunSuite
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
class SparkFunSuite extends FunSuite {
def localTest(name : String)(f : SparkContext => Unit) : Unit = {
this.test(name) {
val conf = new SparkConf()
.setAppName(name)
.setMaster("local")
.set("spark.default.parallelism", "1")
val sc = new SparkContext(conf)
try {
f(sc)
} finally {
sc.stop()
}
}
}
}
class MyTestSuite extends SparkFunSuite {
localTest("My Spark test") { sc =>
assertResult(2)(sc.parallelize(Seq(1,2,3)).filter(_ <= 2).map(_ + 1).count)
}
}
import org.scalatest.FunSuite
导入org.apache.spark.SparkConf
导入org.apache.spark.SparkContext
类SparkFunsite扩展了FunSuite{
def localTest(名称:字符串)(f:SparkContext=>Unit):Unit={
此.test(名称){
val conf=new SparkConf()
.setAppName(名称)
.setMaster(“本地”)
.set(“spark.default.parallelism”,“1”)
val sc=新的SparkContext(配置)
试一试{
f(资深大律师)
}最后{
sc.停止()
}
}
}
}
类MyTestSuite扩展了SparkFunSite{
localTest(“我的火花测试”){sc=>
assertResult(2)(sc.parallelize(Seq(1,2,3))过滤器(如果在多个类中运行SparkContext,请确保在build.sbt中放入parallelExecution:=false
。我在运行命令时遇到了问题:sbt Test
。我会得到一个NPE
或一个解析\u错误,该错误是由在JVM。如果你调用.set(“spark.default.parallelism”,“n”)
,其中n
是你的内核数,就在setMaster
之后,NPE会消失吗?@huitseker同样的错误。我不知道什么是空的……spark自己的单元测试使用类似的模式(我们使用ScalaTest的BeforeAndAfterAll和BeforeAndAfterEach特性来执行此设置),因此我很惊讶这不起作用。您是否并行运行多个测试(例如,您是否在同一JVM中同时运行SparkContext)不,我同意你的看法:Spark做了类似的事情。我改变的是如何创建sc以避免代码中出现空值。这太神秘了…太棒了-我一直在寻找这个。这需要在Spark测试文献中的某个突出位置
import org.scalatest.FunSuite
import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
class SparkFunSuite extends FunSuite {
def localTest(name : String)(f : SparkContext => Unit) : Unit = {
this.test(name) {
val conf = new SparkConf()
.setAppName(name)
.setMaster("local")
.set("spark.default.parallelism", "1")
val sc = new SparkContext(conf)
try {
f(sc)
} finally {
sc.stop()
}
}
}
}
class MyTestSuite extends SparkFunSuite {
localTest("My Spark test") { sc =>
assertResult(2)(sc.parallelize(Seq(1,2,3)).filter(_ <= 2).map(_ + 1).count)
}
}