Java 无法在单元测试方法之前和之后启动/停止spark in
我正在为spark应用程序编写单元测试,但遇到了一个问题。理想情况下,我希望有一个Java 无法在单元测试方法之前和之后启动/停止spark in,java,unit-testing,apache-spark,junit,Java,Unit Testing,Apache Spark,Junit,我正在为spark应用程序编写单元测试,但遇到了一个问题。理想情况下,我希望有一个Before和After方法,在这里我启动和停止spark(而不是在单元测试方法本身中这样做) 下面的实现工作正常,我能够在测试开始时声明SparkConf和JavaSparkContext,然后在测试结束时执行sc.close() @Test public void testMethod(){ SparkConf conf = new SparkConf().setMaster("loca
Before
和After
方法,在这里我启动和停止spark(而不是在单元测试方法本身中这样做)
下面的实现工作正常,我能够在测试开始时声明SparkConf
和JavaSparkContext
,然后在测试结束时执行sc.close()
@Test
public void testMethod(){
SparkConf conf = new SparkConf().setMaster("local").setAppName("testGeoHashAggregation");
JavaSparkContext sc = new JavaSparkContext(conf);
// yadda yadda yadda
//tests here
sc.close()
}
但是我想设置它,这样开始和停止都有自己的方法
@Before
public void init(){
SparkConf conf = new SparkConf().setMaster("local").setAppName("testGeoHashAggregation");
JavaSparkContext sc = new JavaSparkContext(conf);
}
@After
public void close(){
sc.close();
}
你知道为什么后者不起作用吗?我将遇到一个异常,即某些对象不可序列化
首先,sc
应该是一个类字段,而不是init()
方法的局部变量
其次,在课前使用@BeforeClass
和课后使用@AfterClass
不是更好吗?Spark start相当长(web ui、集群等每次都会启动),如果完全隔离不是问题,那么@BeforeClass
会更好。然而,这只是一个建议,不是你问题的解决方案
因此,本例中的代码如下所示:
public class SomeSparkTest implements Serializable {
private static transient JavaSparkContext jsc;
@BeforeClass
public static void init () {
SparkConf conf = new SparkConf().setMaster("local").setAppName("testGeoHashAggregation");
jsc = new JavaSparkContext(conf);
}
@AfterClass
public static void close(){
jsc.close();
}
@Test
public void shouldSomethingHappend () {
// given
// preparation of RDDs
JavaRDD<String> rdd = jsc.textFile(...)
// when
// actions
long count = rdd.count()
// then
// verify output; assertThat is from FestAssertions, not necessary
assertThat(count).isEqualTo(5)
}
}
public类SomeSparkTest实现可序列化{
私有静态瞬态JavaSparkContext jsc;
@课前
公共静态void init(){
SparkConf conf=new SparkConf().setMaster(“本地”).setAppName(“testGeoHashAggregation”);
jsc=新的JavaSparkContext(conf);
}
@下课
公共静态无效关闭(){
jsc.close();
}
@试验
公共空间应该发生一些事情(){
//给定
//RDD的制备
JavaRDD=jsc.textFile(…)
//什么时候
//行动
长计数=rdd.count()
//然后
//验证输出;来自断言的资产,不需要
资产(计数)。isEqualTo(5)
}
}
您已经从Spark存储库获得了一些测试套件
说明:在测试中使用的任何lambda或内部类都引用外部类,在本例中,它就是测试类。Spark始终序列化lambdas/内部类,即使在本地集群模式下也是如此。如果您的测试类不可序列化,或者它有任何不可序列化的字段,那么会出现这样的错误第二个代码看起来很奇怪-我想JavaSparkContext
不仅在init()
中,而且在类中。如果序列化的问题在于某个对象,只需实现可序列化的接口即可。如果您对JavaSparkContext
的序列化有问题,请将transient添加到此字段。类似于->公共类YourClass{private transient JavaSparkContext sc;…这里的所有代码都是以前的…之后的
谢谢,我把JavaSparkContext作为一个类字段,但不确定为什么我把它作为init的一个局部变量写进去。总之,将其设置为transient解决了我的问题。我没有考虑在
之前的和之前的nks寻求帮助!@rvisio好的,所以只需将Serializable添加到测试类中,并将JavaSparkContext标记为transient。应该可以工作:)