2015-05-05 11 views
5

Jestem na Androidzie Studio 1.2, Robolectric 3.0-rc2.niektóre testy Robolectric zawodzą, gdy są uruchamiane razem, ale przechodzą osobno

Mam dwie klasy testowe, jedną o nazwie MotdTest z jedną metodą testowania, która testuje przekształcanie do postaci szeregowej POJO json &. Drugi nazywa się UserInfoTest, który zawiera 4 metody testowania, które testują informacje o użytkowniku, które ustawię w SharedPreferences. Jeśli uruchomię osobno UserInfoTest, wszystkie 4 metody testowe zawsze będą przekazywane. Jednakże, jeśli uruchomię wszystkie testy, test w MotdTest się powiedzie, ale dwie metody UserInfoTest zawsze zawodzą. Zaczynam teraz od linii poleceń, dzwoniąc pod numer ./gradlew test

Czy ktoś wie, dlaczego niektóre z moich testów zawodzą, gdy przeprowadzam wszystkie testy? W moim UserInfoTest prawidłowo wykonuję metodę z adnotacją @After, w której dokonuję czyszczenia, wywołując metodę clear(). Commit() na SharedPreferences.Editor.

UserInfoTest:

testOnSignIn() nie na assertThat(6, equalTo(prefs.getAll().size())); ponieważ wielkość prefs 0.

I testIsSignedIn() nie na assertThat(UserInfo.isSignedIn(), is(false));

@RunWith(MyRoboRunner.class) 
@Config(constants = BuildConfig.class) 
public class UserInfoTest { 

    private String mExpectedId; 

    private String mExpectedName; 

    private String mExpectedEmail; 

    private String mExpectedToken; 

    private String mExpectedKey; 

    @Before 
    public void setUp() throws Exception { 
     ShadowLog.stream = System.out; 

     mExpectedId = "someiD"; 
     mExpectedName = "johnny boy"; 
     mExpectedEmail = "[email protected]"; 
     mExpectedToken = "Session Token"; 
     mExpectedKey = "Session Key"; 
    } 

    @After 
    public void tearDown() { 
     SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
       UserInfo.PREFERENCES, Context.MODE_PRIVATE); 
     prefs.edit().clear().commit(); 
     mExpectedId = null; 
     mExpectedName = null; 
     mExpectedEmail = null; 
     mExpectedToken = null; 
     mExpectedKey = null; 
    } 

    @Test 
    public void testOnSignIn() {   
     SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
       UserInfo.PREFERENCES, Context.MODE_PRIVATE); 

     UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken); 
     assertThat(mExpectedKey, equalTo(UserInfo.getSessionKey())); 

     assertThat(mExpectedToken, equalTo(UserInfo.getSessionToken())); 
     assertThat(mExpectedId, equalTo(UserInfo.getUserId())); 
     assertThat(mExpectedEmail, equalTo(UserInfo.getUserEmail())); 
     assertThat(mExpectedName, equalTo(UserInfo.getUserName())); 

     assertThat(6, equalTo(prefs.getAll().size())); 
    } 

    @Test 
    public void testOnSignOut() { 
     UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken); 
     // Set Over21 to make sure we unset this value on Signout 
     UserInfo.setIsOver21(true); 

     UserInfo.onSignOut(); 
     SharedPreferences prefs = RuntimeEnvironment.application.getSharedPreferences(
       UserInfo.PREFERENCES, Context.MODE_PRIVATE); 
     assertThat(UserInfo.getSessionKey(), nullValue()); 
     assertThat(UserInfo.getSessionToken(), nullValue()); 
     assertThat(UserInfo.isOver21Set(), is(false)); 
     assertThat(prefs.getAll().size(), equalTo(0)); 
    } 

    @Test 
    public void testIsSignedIn() { 
     assertThat(UserInfo.isSignedIn(), is(false)); 

     UserInfo.onSignIn(mExpectedId, mExpectedName, mExpectedEmail, mExpectedKey, mExpectedToken); 
     assertThat(UserInfo.isSignedIn(), is(true)); 

     UserInfo.onSignOut(); 
     assertThat(UserInfo.isSignedIn(), is(false)); 
    } 

    @Test 
    public void testIsOver21Set() { 
     assertThat(UserInfo.isOver21Set(), is(false)); 
     UserInfo.setIsOver21(false); 
     assertThat(UserInfo.isOver21Set(), is(true)); 
    } 
} 

userinfo:

App jest an an Application podklasa d App.getInstance() to singleton.

private static final SharedPreferences PREFS = App.getInstance() 
     .getSharedPreferences(PREFERENCES, Context.MODE_PRIVATE); 

public static void onSignIn(String userId, String fullName, String email, String sessionKey, 
     String sessionToken) { 
    SharedPreferences.Editor editor = PREFS.edit(); 
    editor.putString(PROPERTY_USER_ID, userId); 
    editor.putString(PROPERTY_USER_NAME, fullName); 
    editor.putString(PROPERTY_USER_EMAIL, email); 
    editor.putString(PROPERTY_SESSION_KEY, sessionKey); 
    editor.putString(PROPERTY_SESSION_TOKEN, sessionToken); 
    editor.putStringSet(PROPERTY_PENDING_SCANS, new HashSet<String>()); 

    editor.commit(); 
} 
public static boolean isSignedIn() { 
    return getSessionToken() != null; 
} 

MyRoboRunner: Zmodyfikowana wersja this bo jestem na Mac, a także dlatego, że jestem kierowania API 22 w moim projekcie, ale robolectric nie obsługuje aż do tego jeszcze, więc biegnę moich testów przeciwko API 21.

public class MyRoboRunner extends RobolectricGradleTestRunner { 

    public MyRoboRunner(Class<?> klass) throws InitializationError { 
     super(klass); 
    } 

    protected AndroidManifest getAppManifest(Config config) { 
     AndroidManifest appManifest = super.getAppManifest(config); 
     String moduleRoot = getModuleRootPath(config); 

     //can use this line instead dynamic path resolution when AS bug is fix, or use @Config 
     //FsFile androidManifestFile = appManifest.getAndroidManifestFile(); 
     FsFile androidManifestFile = FileFsFile.from(moduleRoot, 
       appManifest.getAndroidManifestFile().getPath() 
         .replace("bundles", "manifests/full")); 
     FsFile resDirectory = FileFsFile.from(moduleRoot, appManifest.getResDirectory().getPath()); 
     FsFile assetsDirectory = FileFsFile 
       .from(moduleRoot, appManifest.getAssetsDirectory().getPath()); 
     return new AndroidManifest(androidManifestFile, resDirectory, assetsDirectory) { 
      @Override 
      public int getTargetSdkVersion() { 
       //lollipop bc it's highest that robolectric 3.0 supports 
       return Build.VERSION_CODES.LOLLIPOP; 
      } 

      @Override 
      public int getMinSdkVersion() { 
       return Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1; 
      } 
     }; 
    } 

    private String getModuleRootPath(Config config) { 
     String moduleRoot = config.constants().getResource("").toString().replace("file:", ""); 
     return moduleRoot.substring(0, moduleRoot.indexOf("/build")); 
    } 
} 
+0

Jakiego rodzaju błąd widzisz? Czy mógłbyś udostępnić kod do testów? –

+0

@EugenMartynov Dołączyłem kod, którego używam do testów. – waynesford

Odpowiedz

0

Używanie robolectric gradle plugin i ustawienie tej właściwości ma wszystkie moje testy uchwala:

robolectric { 
    // Specify max number of processes (default is 1) 
    maxParallelForks = 2 
} 

Ale ja nadal nie wiem, dlaczego miałoby to wpływ na moją t ests po uruchomieniu indywidualnie vs wszystkie razem. Wydaje się również, że wtyczka gradacyjna robolectric nie jest już potrzebna, ponieważ jestem w Androidzie 1.2, ale nie mogłem wymyślić, jak uruchomić go bez niego i ręcznie ustawić właściwość maxParallelForks.

+1

Jest to rozwiązanie zastępcze, ale nieodpowiednie –

1

Masz stałe odwołania do SharedPreferences w PREFS. Myślę, że twoje testy zostaną naprawione, gdy tylko zresetujesz je w swojej metodzie tearDown lub w ogóle usuniesz odwołania statyczne. Jeśli usuniesz odniesienie statyczne, wówczas plik SharedPreferences zostanie wyczyszczony sam przez Robolectric - nie trzeba usuwać go ponownie w tearDown.

Kolejny punkt, o którym warto wspomnieć - używam również Mac i nie mam żadnego problemu z RobolectricGradleTestRunnner. Czasami muszę uruchomić clean przed uruchomieniem testów, ale nic więcej.

I jeszcze jedna rzecz, o której wspomniałeś robobolectric-gradle-plugin. Nie potrzebujesz tego z Androidem Studio v1.1 + i Androidem gradle plugin v1.1 +

Powiązane problemy