我正在尝试对涉及DStream的Spark Streaming应用程序执行一些单元测试。
我发现以下西装非常有用: StreamingSuiteBase 。它包含一个名为 testOperation 的方法,您可以向其传递输入,要进行测试的操作以及预期的输出。它将验证您的预期输出是否与实际输出匹配。
我面临的问题是在相等性验证期间,我确实得到了完全相同的对象,但是包装到了不同的集合中
testOperation的定义如下:
def testOperation[U: ClassTag, V: ClassTag](
input: Seq[Seq[U]],
operation: DStream[U] => DStream[V],
expectedOutput: Seq[Seq[V]],
ordered: Boolean
) (implicit equality: Equality[V]): Unit = {
val numBatches = input.size
withOutputAndStreamingContext(setupStreams[U, V](input, operation)) {
(outputStream, ssc) =>
val output: Seq[Seq[V]] = runStreams[V](
outputStream, ssc, numBatches, expectedOutput.size)
verifyOutput[V](output, expectedOutput, ordered)
}
}
哪些不让我按预期使用List(Array(myObject))
所以我的第二个选择是修改方法verifyOutput
。我打算从代码中重写它,只需添加几行以生成List(Array(myObject))。像这样(已更新):
override def verifyOutput[V](output: Seq[Seq[V]],
expectedOutput: Seq[Seq[V]],
ordered: Boolean)
(implicit evidence$1: ClassTag[V], equality: Equality[V]): Unit = {
super.verifyOutput(output, expectedOutput, ordered)
}
//These three lines is what I am planning to add
val sq = expectedOutput(0)
val ssq = sq(0)
val newOutput = Seq(Array(ssq))
logInfo("--------------------------------")
logInfo("output.size = " + output.size)
logInfo("output")
output.foreach(x => logInfo("[" + x.mkString(",") + "]"))
logInfo("expected output.size = " + expectedOutput.size)
logInfo("expected output")
expectedOutput.foreach(x => logInfo("[" + x.mkString(",") + "]"))
logInfo("--------------------------------")
// Match the output with the expected output
assert(output.size === expectedOutput.size, "Number of outputs do not match")
if (ordered) {
for (i <- output.indices)
equalsOrdered(output(i), expectedOutput(i))
} else {
for (i <- output.indices)
equalsUnordered(output(i), expectedOutput(i))
}
logInfo("Output verified successfully")
}
可以找到整个here
但是我在Eclipse中遇到以下错误:
方法verifyOutput不会覆盖任何内容。注意:的超类 类myClass包含以下非最终成员,命名为 verifyOutput:def verifyOutput [V](输出:Seq [Seq [V]],expectedOutput: Seq [Seq [V]],排序:布尔值)(隐式证据$ 1: scala.reflect.ClassTag [V],隐式相等: org.scalactic.Equality [V]):单位
这是我的测试用例的简化版本:
import org.scalatest.FunSuite
class myClass extends StreamingSuiteBase with FunSuite {
test("ExtCustProfileHbaseAPI") {
//Here I would be generating my input and expected output
val inputData = new myInitialObject()
val expOutput = new myFinalObject()
testOperation(inputData, processTest _, expOutput, ordered = false)
}
def processTest(input: DStream[myInitialObject]): DStream[(String,myFinalObject)] = {
//Operation undertes
val result = operation(input)
result
}
//Here I added the override def verifyOutput[V: ClassTag]...
}
我在做什么错了?
答案 0 :(得分:2)
根据source,StreamingSuiteBase
特性具有自类型org.scalatest.Suite
,这意味着您还必须扩展Suite类型类(在您的情况下为FunSuite ),否则它将无法编译。
您可以参考以下内容:https://github.com/holdenk/spark-testing-base/wiki/StreamingSuiteBase
有关Scala自身类型的更多信息,您可以参考:https://docs.scala-lang.org/tour/self-types.html
您不需要V: ClassTag
我可以看到的基本IDE生成的覆盖方法是:
override def verifyOutput[V](output: Seq[Seq[V]],
expectedOutput: Seq[Seq[V]],
ordered: Boolean)
(implicit evidence$1: ClassTag[V], equality: Equality[V]): Unit = {
super.verifyOutput(output, expectedOutput, ordered)
}