2016-10-05 36 views
3

我正在爲我的火花應用程序編寫單元測試,但遇到了問題。理想的情況下,我想有一個BeforeAfter方法,我開始和停止火花(而不是在單元測試方法本身)。無法在單元測試的前後方法中啓動/停止火花

下面的實現工作,我可以在測試開始時聲明SparkConfJavaSparkContext,然後在最後執行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(); 
} 

任何想法,爲什麼後者不工作?我將遇到一個異常,一些對象不可序列化。

+2

第二個代碼看起來很奇怪 - 我想'JavaSparkContext'不僅在init()中,而且在類中。如果序列化的問題與某個對象有關 - 只需實現Serializable接口。如果您在JavaSparkContext序列化過程中遇到問題,請在此字段中添加瞬變。 類似於 - > 'public class YourClass { private transient JavaSparkContext sc; ....所有的代碼都在這之前......之後...... – VladoDemcak

回答

1
  1. 起初,sc應該是一個類字段,init()方法
  2. 其次的不是局部變量,是不是更好地使用@BeforeClass@AfterClass? Spark的啓動時間很長(每次啓動web ui,cluster等),如果完全隔離不成問題,則@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) 
} 
} 

Here你已經得到了來自星火庫的一些測試套件

說明:任何拉姆達或內部類,你是在測試中使用,引用外部類,在這種情況下,它是測試類。即使在本地集羣模式下,Spark也總是對lambda表達式/內部類進行序列化。如果你的測試類不是可序列化的,或者它有任何不可序列化的字段,那麼這樣的錯誤會出現

+0

謝謝,我把JavaSparkContext作爲一個類字段,但不知道爲什麼我把它寫成init的局部變量。無論如何,將其設置爲瞬態解決了我的問題。 我沒想過'BeforeClass' vs'Before'。將調查,感謝您的幫助! – rvisio

+1

@rvisio OK,所以只需將Serializable添加到您的測試類並將JavaSparkContext標記爲瞬態即可。應該管用 :) –