我尝试重构ScalaTest FunSuite测试,以避免样板代码初始化并破坏Spark会话。
问题在于我需要导入隐式函数,但是使用前/后方法只能使用变量(var字段),并且导入它是必要的值(val字段)。
我们的想法是在每次测试执行时都有一个新的干净的Spark会话。
我尝试做这样的事情:
import org.apache.spark.SparkContext
import org.apache.spark.sql.{SQLContext, SparkSession}
import org.scalatest.{BeforeAndAfter, FunSuite}
object SimpleWithBeforeTest extends FunSuite with BeforeAndAfter {
var spark: SparkSession = _
var sc: SparkContext = _
implicit var sqlContext: SQLContext = _
before {
spark = SparkSession.builder
.master("local")
.appName("Spark session for testing")
.getOrCreate()
sc = spark.sparkContext
sqlContext = spark.sqlContext
}
after {
spark.sparkContext.stop()
}
test("Import implicits inside the test 1") {
import sqlContext.implicits._
// Here other stuff
}
test("Import implicits inside the test 2") {
import sqlContext.implicits._
// Here other stuff
}
但是在import sqlContext.implicits._
行中我有一个错误
无法解析符号sqlContext
如何解决此问题或如何实现测试类?
答案 0 :(得分:1)
为spark上下文定义一个新的不可变变量,并在导入implicits之前将var赋值给它。
{{1}}
答案 1 :(得分:1)
您还可以使用spark-testing-base,它几乎可以处理所有样板代码。
创建者在这里a blog post,解释了如何使用它。
这是他们的wiki中的一个简单示例:
class test extends FunSuite with DatasetSuiteBase { test("simple test") { val sqlCtx = sqlContext import sqlCtx.implicits._ val input1 = sc.parallelize(List(1, 2, 3)).toDS assertDatasetEquals(input1, input1) // equal val input2 = sc.parallelize(List(4, 5, 6)).toDS intercept[org.scalatest.exceptions.TestFailedException] { assertDatasetEquals(input1, input2) // not equal } } }