簡體   English   中英

對於基本數據框創建示例,我應該如何在Spark中編寫單元測試?

[英]How should I write unit tests in Spark, for a basic data frame creation example?

我正在努力編寫一個基本單元測試來創建數據框,使用Spark提供的示例文本文件,如下所示。

class dataLoadTest extends FunSuite with Matchers with BeforeAndAfterEach {

private val master = "local[*]"
private val appName = "data_load_testing"

private var spark: SparkSession = _

override def beforeEach() {
  spark = new SparkSession.Builder().appName(appName).getOrCreate()
}

import spark.implicits._

 case class Person(name: String, age: Int)

  val df = spark.sparkContext
      .textFile("/Applications/spark-2.2.0-bin-hadoop2.7/examples/src/main/resources/people.txt")
      .map(_.split(","))
      .map(attributes => Person(attributes(0),attributes(1).trim.toInt))
      .toDF()

  test("Creating dataframe should produce data from of correct size") {
  assert(df.count() == 3)
  assert(df.take(1).equals(Array("Michael",29)))
}

override def afterEach(): Unit = {
  spark.stop()
}

}

我知道代碼本身是有效的(來自spark.implicits._ .... toDF()),因為我已經在Spark-Scala shell中驗證了這一點,但在測試類中我遇到了很多錯誤; IDE無法識別'import spark.implicits._或toDF(),因此測試不會運行。

我正在使用SparkSession,它自動創建SparkConf,SparkContext和SQLContext。

我的代碼只使用Spark repo中的示例代碼。

任何想法為什么這不起作用? 謝謝!

NB。 我已經看過StackOverflow上的Spark單元測試問題,如下所示: 如何在Spark 2.0+中編寫單元測試? 我用它來編寫測試,但我仍然得到錯誤。

我正在使用Scala 2.11.8和Spark 2.2.0與SBT和IntelliJ。 這些依賴項正確包含在SBT構建文件中。 運行測試時的錯誤是:

錯誤:(29,10)值toDF不是org.apache.spark.rdd.RDD [dataLoadTest.this.Person]的成員可能的原因:可能在`to toFF'之前缺少分號? .toDF()

錯誤:(20,20)需要穩定的標識符,但找到了dataLoadTest.this.spark.implicits。 import spark.implicits._

IntelliJ將無法識別導入spark.implicits._或.toDF()方法。

我導入了:import org.apache.spark.sql.SparkSession import org.scalatest。{BeforeAndAfterEach,FlatSpec,FunSuite,Matchers}

你需要將sqlContext分配給val以使implicits工作。 由於你的sparkSession是一個var ,因此implicits不適用

所以你需要這樣做

val sQLContext = spark.sqlContext
import sQLContext.implicits._

此外,您可以為測試編寫函數,以便您的測試類看起來如下所示

    class dataLoadTest extends FunSuite with Matchers with BeforeAndAfterEach {

  private val master = "local[*]"
  private val appName = "data_load_testing"

  var spark: SparkSession = _

  override def beforeEach() {
    spark = new SparkSession.Builder().appName(appName).master(master).getOrCreate()
  }


  test("Creating dataframe should produce data from of correct size") {
    val sQLContext = spark.sqlContext
    import sQLContext.implicits._

    val df = spark.sparkContext
    .textFile("/Applications/spark-2.2.0-bin-hadoop2.7/examples/src/main/resources/people.txt")
    .map(_.split(","))
    .map(attributes => Person(attributes(0), attributes(1).trim.toInt))
    .toDF()

    assert(df.count() == 3)
    assert(df.take(1)(0)(0).equals("Michael"))
  }

  override def afterEach() {
    spark.stop()
  }

}
case class Person(name: String, age: Int)

有許多庫用於火花的單元測試,其中一個最常用的是

spark-testing-base作者Holden Karau

這個庫都帶有sc因為下面的SparkContext是一個簡單的例子

class TestSharedSparkContext extends FunSuite with SharedSparkContext {

  val expectedResult = List(("a", 3),("b", 2),("c", 4))

  test("Word counts should be equal to expected") {
    verifyWordCount(Seq("c a a b a c b c c"))
  }

  def verifyWordCount(seq: Seq[String]): Unit = {
    assertResult(expectedResult)(new WordCount().transform(sc.makeRDD(seq)).collect().toList)
  }
}

在這里,每個東西都用sc作為SparkContext

另一種方法是創建一個TestWrapper並用於多個testcases ,如下所示

import org.apache.spark.sql.SparkSession

trait TestSparkWrapper {

  lazy val sparkSession: SparkSession = 
    SparkSession.builder().master("local").appName("spark test example ").getOrCreate()

}

並使用此TestWrapper所有tests使用Scala測試,以打BeforeAndAfterAllBeforeAndAfterEach

希望這可以幫助!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM