2015-05-05 2 views
5

Я нахожусь на Android Studio 1.2, Robolectric 3.0-rc2.некоторые тесты Robolectric терпят неудачу при запуске все вместе, но проходят индивидуально

У меня есть два тестовых класса, один из которых называется MotdTest с одним методом испытаний, который тестирует сериализацию POJO json & десериализация. Другой называется UserInfoTest, который содержит 4 метода тестирования, которые проверяют информацию пользователя, которую я установил в SharedPreferences. Если я запускаю UserInfoTest отдельно, все 4 метода тестирования всегда проходят. Однако, если я запускаю все тесты, тест в MotdTest преуспевает, но два метода UserInfoTest всегда терпят неудачу. Я бегу от командной строки прямо сейчас, позвонив ./gradlew test

Кто-нибудь знает, почему некоторые мои тесты терпят неудачу, когда я запускаю все тесты? В моем UserInfoTest у меня действительно есть аннотированный метод @After, где я делаю очистку, вызывая clear(). Commit() на SharedPreferences.Editor.

UserInfoTest:

testOnSignIn() проваливает assertThat(6, equalTo(prefs.getAll().size()));, так как размер prefs 0.

И testIsSignedIn() проваливает 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 является Application подкласс d App.getInstance() - одноэлементный.

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: Модифицированная версия this потому, что я нахожусь на Mac, а также потому, что я нацеливание API 22 в моем проекте, но robolectric не поддерживает до этого, поэтому я запускаю тесты против 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

Какой вид сбоя вы видите? Не могли бы вы поделиться кодом для тестов? –

+0

@EugenMartynov Я включил некоторые из кода, который я использую для тестов. – waynesford

ответ

0

Использование robolectric gradle plugin и установка этого свойства имеет все мои тесты прохождения:

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

Но я до сих пор не знаю, почему это может повлиять на мою т при запуске индивидуально против всех вместе. Кроме того, похоже, что плагин robolectric gradle больше не нужен, так как я на Android Studio 1.2, но я не мог понять, как заставить его работать без него и вручную установить свойство maxParallelForks.

+1

Это обходное решение, но не правильное решение –

1

Вы сохраняете статические ссылки на SharedPreferences в PREFS. Я думаю, что ваши тесты будут исправлены, как только вы сбросите его в свой метод tearDown или вообще удалите статические ссылки. Если вы удалите статическую ссылку, то файл SharedPreferences будет очищен Robolectric сам по себе - не нужно очищать его снова в tearDown.

Еще один момент - я также использую Mac, и у меня нет проблем с RobolectricGradleTestRunnner. Иногда мне нужно запустить clean перед запуском тестов, но ничего больше.

И еще одно, что вы упомянули robobolectric-gradle-plugin. Вам это не нужно с Android Studio v1.1 + и плагин android gradle v1.1 +

Смежные вопросы

 Смежные вопросы