如何实现ScalaTest FunSuite以避免样板Spark代码和导入含义

时间:2017-01-11 15:29:26

标签: scala apache-spark scalatest

我尝试重构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

如何解决此问题或如何实现测试类?

2 个答案:

答案 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
    }
  }
}