[英]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测试,以打BeforeAndAfterAll
和BeforeAndAfterEach
。
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.