Cómo configurar Unit Test para Fragmentar en Android

15 minutos de lectura

Avatar de usuario de Trev Sorbie
Trev Sorbie

Quiero realizar una prueba unitaria de una clase de Fragmentos de Android.

¿Puedo configurar una prueba usando AndroidTestCase o necesito usar ApplicationTestCase?

¿Hay algún ejemplo útil de cómo se pueden usar estos dos TestCases? Los ejemplos de prueba en el sitio del desarrollador son mínimos y solo parecen centrarse en las actividades de prueba.

Todo lo que he encontrado en otros lugares son ejemplos en los que la clase AndroidTestCase se extiende, pero luego todo lo que se prueba es sumar dos números o si se usa el Contexto, ¡simplemente hace una simple obtención y prueba que algo no es nulo!

Tal como lo entiendo, un Fragmento tiene que vivir dentro de una Actividad. Entonces, ¿podría crear una Actividad simulada u obtener la Aplicación o el Contexto para proporcionar una Actividad dentro de la cual pueda probar mi Fragmento?

¿Necesito crear mi propia actividad y luego usar ActivityUnitTestCase?

Avatar de usuario de Konstantin Loginov
Konstantin Loginov

Estaba luchando con la misma pregunta. Especialmente, dado que la mayoría de los ejemplos de código ya están desactualizados + Android Studio/SDK está mejorando, por lo que las respuestas antiguas a veces ya no son relevantes.

Entonces, lo primero es lo primero: debe determinar si desea usar Instrumental o sencillo JUnit pruebas

La diferencia entre ellos bellamente descrita por SD aquí; En resumen: las pruebas JUnit son más livianas y no requieren un emulador para ejecutarse, Instrumental: le brinda la experiencia más cercana posible al dispositivo real (sensores, gps, interacción con otras aplicaciones, etc.). También lea más sobre probando en android.

1. Pruebas JUnit de fragmentos

Digamos que no necesita pruebas instrumentales pesadas y las pruebas junit simples son suficientes. Yo uso buen marco roboelectrico para este propósito.

En gradle agregar:

dependencies {
    .....
    testImplementation('junit:junit:4.12')
    testImplementation('org.robolectric:robolectric:3.0')
    testImplementation("org.mockito:mockito-core:1.10.8")
    testImplementation('com.squareup.assertj:assertj-android:1.0.0') {
    exclude module: 'support-annotations'
    }
    .....
}

Mockito, AsserJ son opcionales, pero los encontré muy útiles, así que recomiendo incluirlos también.

luego en Variantes de construcción especificar Pruebas unitarias como un Artefacto de prueba:
ingrese la descripción de la imagen aquí

Ahora es el momento de escribir algunas pruebas reales 🙂 Como ejemplo, tomemos el proyecto de muestra estándar “Actividad en blanco con fragmento”.

Agregué algunas líneas de código, para tener realmente algo para probar:

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.List;

public class MainActivityFragment extends Fragment {

    private List<Cow> cows;
    public MainActivityFragment() {}

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {   
        cows = new ArrayList<>();
        cows.add(new Cow("Burka", 10));
        cows.add(new Cow("Zorka", 9));
        cows.add(new Cow("Kruzenshtern", 15));

        return inflater.inflate(R.layout.fragment_main, container, false);
    }

    int calculateYoungCows(int maxAge) {
        if (cows == null) {
            throw new IllegalStateException("onCreateView hasn't been called");
        }

        if (getActivity() == null) {
            throw new IllegalStateException("Activity is null");
        }

        if (getView() == null) {
            throw new IllegalStateException("View is null");
        }

        int result = 0;
        for (Cow cow : cows) {
            if (cow.age <= maxAge) {
                result++;
            }
        }

        return result;
    }
}

Y clase Vaca:

public class Cow {
    public String name;
    public int age;

    public Cow(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

El conjunto de prueba de Robolectic se vería así:

import android.app.Application;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.test.ApplicationTestCase;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk=21)
public class MainActivityFragmentTest extends ApplicationTestCase<Application> {

    public MainActivityFragmentTest() {
        super(Application.class);
    }

    MainActivity mainActivity;
    MainActivityFragment mainActivityFragment;

    @Before
    public void setUp() {
        mainActivity = Robolectric.setupActivity(MainActivity.class);
        mainActivityFragment = new MainActivityFragment();
        startFragment(mainActivityFragment);
    }

    @Test
    public void testMainActivity() {
        Assert.assertNotNull(mainActivity);
    }

    @Test
    public void testCowsCounter() {
        assertThat(mainActivityFragment.calculateYoungCows(10)).isEqualTo(2);
        assertThat(mainActivityFragment.calculateYoungCows(99)).isEqualTo(3);
    }

    private void startFragment( Fragment fragment ) {
        FragmentManager fragmentManager = mainActivity.getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(fragment, null );
        fragmentTransaction.commit();
    }
}

Es decir, creamos actividad a través de Robolectric.setupActivity, nuevo fragmento en el setUp() de las clases de prueba. Opcionalmente, puede iniciar inmediatamente el fragmento desde setUp() o puede hacerlo directamente desde la prueba.

¡NÓTESE BIEN! no he gastado también mucho tiempo en eso, pero parece que es casi imposible vincularlo con Dagger (no sé si es más fácil con Dagger2), ya que no puede configurar una aplicación de prueba personalizada con inyecciones simuladas.

2. Pruebas instrumentales de fragmentos

La complejidad de este enfoque depende en gran medida de si está utilizando la inyección Dagger/Dependency en la aplicación que desea probar.

En Variantes de construcción especificar Pruebas instrumentales de Android como un Artefacto de prueba:
ingrese la descripción de la imagen aquí

En Gradle agrego estas dependencias:

dependencies {
    .....
    androidTestCompile "com.google.dexmaker:dexmaker:1.1"
    androidTestCompile "com.google.dexmaker:dexmaker-mockito:1.1"
    androidTestCompile 'com.squareup.assertj:assertj-android:1.0.0'
    androidTestCompile "org.mockito:mockito-core:1.10.8"
    }
    .....
}

(Nuevamente, casi todos son opcionales, pero pueden hacer tu vida mucho más fácil)

– Si no tienes Daga

Este es un camino feliz. La diferencia con Robolectric de lo anterior estaría solo en pequeños detalles.

Pre-paso 1: Si va a usar Mockito, debe habilitarlo para que se ejecute en los dispositivos y emuladores con este truco:

public class TestUtils {
    private static final String CACHE_DIRECTORY = "/data/data/" + BuildConfig.APPLICATION_ID + "/cache";
    public static final String DEXMAKER_CACHE_PROPERTY = "dexmaker.dexcache";

    public static void enableMockitoOnDevicesAndEmulators() {
        if (System.getProperty(DEXMAKER_CACHE_PROPERTY) == null || System.getProperty(DEXMAKER_CACHE_PROPERTY).isEmpty()) {
            File file = new File(CACHE_DIRECTORY);
            if (!file.exists()) {
                final boolean success = file.mkdirs();
                if (!success) {
                    fail("Unable to create cache directory required for Mockito");
                }
            }

            System.setProperty(DEXMAKER_CACHE_PROPERTY, file.getPath());
        }
    }
}

El MainActivityFragment permanece igual, como arriba. Entonces el conjunto de prueba se vería así:

package com.klogi.myapplication;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.test.ActivityInstrumentationTestCase2;

import junit.framework.Assert;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MainActivityFragmentTest extends ActivityInstrumentationTestCase2<MainActivity> {

    public MainActivityFragmentTest() {
        super(MainActivity.class);
    }

    MainActivity mainActivity;
    MainActivityFragment mainActivityFragment;

    @Override
    protected void setUp() throws Exception {
        TestUtils.enableMockitoOnDevicesAndEmulators();
        mainActivity = getActivity();
        mainActivityFragment = new MainActivityFragment();
    }

    public void testMainActivity() {
        Assert.assertNotNull(mainActivity);
    }

    public void testCowsCounter() {
        startFragment(mainActivityFragment);
        assertThat(mainActivityFragment.calculateYoungCows(10)).isEqualTo(2);
        assertThat(mainActivityFragment.calculateYoungCows(99)).isEqualTo(3);
    }

    private void startFragment( Fragment fragment ) {
        FragmentManager fragmentManager = mainActivity.getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(fragment, null);
        fragmentTransaction.commit();

        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                getActivity().getSupportFragmentManager().executePendingTransactions();
            }
        });

        getInstrumentation().waitForIdleSync();
    }

}

Como puede ver, la clase Test es una extensión de ActividadInstrumentaciónTestCase2 clase. Además, es muy importante prestar atención a Fragmento de inicio método, que ha cambiado en comparación con el ejemplo de JUnit: de forma predeterminada, las pruebas no se ejecutan en el subproceso de la interfaz de usuario y debemos solicitar explícitamente la ejecución de las transacciones pendientes de FragmentManager.

– Si tienes daga

Las cosas se están poniendo serias aquí 🙂

Primero, nos deshacemos de ActividadInstrumentaciónTestCase2 a favor de ActivityUnitTestCase class, como clase base para todas las clases de prueba del fragmento.

Como de costumbre, no es tan simple y hay varias trampas (este es uno de los ejemplos). Así que tenemos que proxenetarnos AcitivityUnitTestCase a ActivityUnitTestCaseOverride

Es demasiado largo para publicarlo completo aquí, así que subo la versión completa a github;

public abstract class ActivityUnitTestCaseOverride<T extends Activity>
        extends ActivityUnitTestCase<T> {

    ........
    private Class<T> mActivityClass;

    private Context mActivityContext;
    private Application mApplication;
    private MockParent mMockParent;

    private boolean mAttached = false;
    private boolean mCreated = false;

    public ActivityUnitTestCaseOverride(Class<T> activityClass) {
        super(activityClass);
        mActivityClass = activityClass;
    }

    @Override
    public T getActivity() {
        return (T) super.getActivity();
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        // default value for target context, as a default
        mActivityContext = getInstrumentation().getTargetContext();
    }

    /**
     * Start the activity under test, in the same way as if it was started by
     * {@link android.content.Context#startActivity Context.startActivity()}, providing the
     * arguments it supplied.  When you use this method to start the activity, it will automatically
     * be stopped by {@link #tearDown}.
     * <p/>
     * <p>This method will call onCreate(), but if you wish to further exercise Activity life
     * cycle methods, you must call them yourself from your test case.
     * <p/>
     * <p><i>Do not call from your setUp() method.  You must call this method from each of your
     * test methods.</i>
     *
     * @param intent                       The Intent as if supplied to {@link android.content.Context#startActivity}.
     * @param savedInstanceState           The instance state, if you are simulating this part of the life
     *                                     cycle.  Typically null.
     * @param lastNonConfigurationInstance This Object will be available to the
     *                                     Activity if it calls {@link android.app.Activity#getLastNonConfigurationInstance()}.
     *                                     Typically null.
     * @return Returns the Activity that was created
     */
    protected T startActivity(Intent intent, Bundle savedInstanceState,
                              Object lastNonConfigurationInstance) {
        assertFalse("Activity already created", mCreated);

        if (!mAttached) {
            assertNotNull(mActivityClass);
            setActivity(null);
            T newActivity = null;
            try {
                IBinder token = null;
                if (mApplication == null) {
                    setApplication(new MockApplication());
                }
                ComponentName cn = new ComponentName(getInstrumentation().getTargetContext(), mActivityClass.getName());
                intent.setComponent(cn);
                ActivityInfo info = new ActivityInfo();
                CharSequence title = mActivityClass.getName();
                mMockParent = new MockParent();
                String id = null;

                newActivity = (T) getInstrumentation().newActivity(mActivityClass, mActivityContext,
                        token, mApplication, intent, info, title, mMockParent, id,
                        lastNonConfigurationInstance);
            } catch (Exception e) {
                assertNotNull(newActivity);
            }

            assertNotNull(newActivity);
            setActivity(newActivity);

            mAttached = true;
        }

        T result = getActivity();
        if (result != null) {
            getInstrumentation().callActivityOnCreate(getActivity(), savedInstanceState);
            mCreated = true;
        }
        return result;
    }

    protected Class<T> getActivityClass() {
        return mActivityClass;
    }

    @Override
    protected void tearDown() throws Exception {

        setActivity(null);

        // Scrub out members - protects against memory leaks in the case where someone
        // creates a non-static inner class (thus referencing the test case) and gives it to
        // someone else to hold onto
        scrubClass(ActivityInstrumentationTestCase.class);

        super.tearDown();
    }

    /**
     * Set the application for use during the test.  You must call this function before calling
     * {@link #startActivity}.  If your test does not call this method,
     *
     * @param application The Application object that will be injected into the Activity under test.
     */
    public void setApplication(Application application) {
        mApplication = application;
    }
    .......
}

Cree un AbstractFragmentTest abstracto para todas sus pruebas de fragmentos:

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;

/**
 * Common base class for {@link Fragment} tests.
 */
public abstract class AbstractFragmentTest<TFragment extends Fragment, TActivity extends FragmentActivity> extends ActivityUnitTestCaseOverride<TActivity> {

    private TFragment fragment;
    protected MockInjectionRegistration mocks;

    protected AbstractFragmentTest(TFragment fragment, Class<TActivity> activityType) {
        super(activityType);
        this.fragment = parameterIsNotNull(fragment);
    }

    @Override
    protected void setActivity(Activity testActivity) {
        if (testActivity != null) {
            testActivity.setTheme(R.style.AppCompatTheme);
        }

        super.setActivity(testActivity);
    }

    /**
     * Get the {@link Fragment} under test.
     */
    protected TFragment getFragment() {
        return fragment;
    }

    protected void setUpActivityAndFragment() {
        createMockApplication();

        final Intent intent = new Intent(getInstrumentation().getTargetContext(),
                getActivityClass());
        startActivity(intent, null, null);
        startFragment(getFragment());

        getInstrumentation().callActivityOnStart(getActivity());
        getInstrumentation().callActivityOnResume(getActivity());
    }

    private void createMockApplication() {
        TestUtils.enableMockitoOnDevicesAndEmulators();

        mocks = new MockInjectionRegistration();
        TestApplication testApplication = new TestApplication(getInstrumentation().getTargetContext());
        testApplication.setModules(mocks);
        testApplication.onCreate();
        setApplication(testApplication);
    }

    private void startFragment(Fragment fragment) {
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.add(fragment, null);
        fragmentTransaction.commit();
    }
}

Hay varias cosas importantes aquí.

1) anulamos establecerActividad() para establecer el tema AppCompact en la actividad. Sin eso, el traje de prueba fallará.

2) método setUpActivityAndFragment():

YO. crea actividad ( => getActivity() comienza a devolver un valor no nulo, en las pruebas y en la aplicación que está bajo prueba)

  1. onCreate() de la actividad llamada;

  2. onStart() de la actividad llamada;

  3. onResume() de la actividad llamada;

II. adjunte y comience el fragmento a la actividad

  1. onAttach() del fragmento llamado;

  2. onCreateView() del fragmento llamado;

  3. onStart() del fragmento llamado;

  4. onResume() del fragmento llamado;

3) Método createMockApplication(): Al igual que en la versión sin daga, en el paso previo 1, habilitamos la simulación en los dispositivos y en los emuladores.

Luego, reemplazamos la aplicación normal con sus inyecciones con nuestra TestApplication personalizada.

MockInjectionRegistration parece:

....
import javax.inject.Singleton;

import dagger.Module;
import dagger.Provides;
import de.greenrobot.event.EventBus;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@Module(
        injects = {

                ....
                MainActivity.class,
                MyWorkFragment.class,
                HomeFragment.class,
                ProfileFragment.class,
                ....
        },
        addsTo = DelveMobileInjectionRegistration.class,
        overrides = true
)
public final class MockInjectionRegistration {

    .....
    public DataSource dataSource;
    public EventBus eventBus;
    public MixpanelAPI mixpanel;
    .....

    public MockInjectionRegistration() {
        .....
        dataSource = mock(DataSource.class);
        eventBus = mock(EventBus.class);
        mixpanel = mock(MixpanelAPI.class);
        MixpanelAPI.People mixpanelPeople = mock(MixpanelAPI.People.class);
        when(mixpanel.getPeople()).thenReturn(mixpanelPeople);
        .....
    }
...........
    @Provides
    @Singleton
    @SuppressWarnings("unused")
        // invoked by Dagger
    DataSource provideDataSource() {
        Guard.valueIsNotNull(dataSource);
        return dataSource;
    }

    @Provides
    @Singleton
    @SuppressWarnings("unused")
        // invoked by Dagger
    EventBus provideEventBus() {
        Guard.valueIsNotNull(eventBus);
        return eventBus;
    }

    @Provides
    @Singleton
    @SuppressWarnings("unused")
        // invoked by Dagger
    MixpanelAPI provideMixpanelAPI() {
        Guard.valueIsNotNull(mixpanel);
        return mixpanel;
    }
.........
}

Es decir, en lugar de clases reales, estamos proporcionando a los fragmentos sus versiones simuladas. (Que sean fácilmente rastreables, permitan configurar resultados de llamadas a métodos, etc.).

Y TestApplication es solo su extensión personalizada de la aplicación, que debería admitir la configuración de módulos e inicializar ObjectGraph.

Estos fueron los pasos previos para comenzar a escribir las pruebas 🙂
Ahora la parte simple, las pruebas reales:

public class SearchFragmentTest extends AbstractFragmentTest<SearchFragment, MainActivity> {
    
    public SearchFragmentTest() {
        super(new SearchFragment(), MainActivity.class);
    }

    @UiThreadTest
    public void testOnCreateView() throws Exception {
        setUpActivityAndFragment();

        SearchFragment searchFragment = getFragment();
        assertNotNull(searchFragment.adapter);
        assertNotNull(SearchFragment.getSearchAdapter());
        assertNotNull(SearchFragment.getSearchSignalLogger());
    }

    @UiThreadTest
    public void testOnPause() throws Exception {
        setUpActivityAndFragment();

        SearchFragment searchFragment = getFragment();
        assertTrue(Strings.isNullOrEmpty(SharedPreferencesTools.getString(getActivity(), SearchFragment.SEARCH_STATE_BUNDLE_ARGUMENT)));

        searchFragment.searchBoxRef.setCurrentConstraint("abs");
        searchFragment.onPause();

        assertEquals(searchFragment.searchBoxRef.getCurrentConstraint(), SharedPreferencesTools.getString(getActivity(), SearchFragment.SEARCH_STATE_BUNDLE_ARGUMENT));
    }

    @UiThreadTest
    public void testOnQueryTextChange() throws Exception {
        setUpActivityAndFragment();
        reset(mocks.eventBus);

        getFragment().onQueryTextChange("Donald");
        Thread.sleep(300);

        // Should be one cached, one uncached event
        verify(mocks.eventBus, times(2)).post(isA(SearchRequest.class));
        verify(mocks.eventBus).post(isA(SearchLoadingIndicatorEvent.class));
    }

    @UiThreadTest
    public void testOnQueryUpdateEventWithDifferentConstraint() throws Exception {
        setUpActivityAndFragment();

        reset(mocks.eventBus);

        getFragment().onEventMainThread(new SearchResponse(new ArrayList<>(), "Donald", false));

        verifyNoMoreInteractions(mocks.eventBus);
    }
    ....
}

¡Eso es todo!
Ahora tiene habilitadas las pruebas instrumentales/JUnit para sus fragmentos.

Espero sinceramente que esta publicación ayude a alguien.

  • Esto es algo realmente bueno. ¡Gracias por compartir con nosotros!

    – Vulovic Vukasin

    6 de julio de 2016 a las 8:21

  • Más sencillo sería extraer calculateYoungCows() método en una clase separada y simplemente prueba de unidad eso.

    –Andy Res

    19 de agosto de 2016 a las 18:42

avatar de usuario de abhijit.mitkar
abhijit.mitkar

Supongamos que tiene una clase FragmentActivity denominada ‘MyFragmentActivity’ en la que se agrega una clase Fragment pública denominada ‘MyFragment’ mediante FragmentTransaction. Simplemente cree una clase ‘Caso de prueba JUnit’ que amplíe ActivityInstrumentationTestCase2 en su proyecto de prueba. Luego simplemente llame a getActivity() y acceda al objeto MyFragment y sus miembros públicos para escribir casos de prueba.

Consulte el fragmento de código a continuación:

// TARGET CLASS
public class MyFragmentActivity extends FragmentActivity {
    public MyFragment myFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        myFragment = new MyFragment();
        fragmentTransaction.add(R.id.mainFragmentContainer, myFragment);
        fragmentTransaction.commit();
    }
}

// TEST CLASS
public class MyFragmentActivityTest extends android.test.ActivityInstrumentationTestCase2<MyFragmentActivity> {
    MyFragmentActivity myFragmentActivity;
    MyFragment myFragment;

    public MyFragmentActivityTest() {
        super(MyFragmentActivity.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        myFragmentActivity = (MyFragmentActivity) getActivity();
        myFragment = myFragmentActivity.myFragment;
    }

    public void testPreConditions() {
        assertNotNull(myFragmentActivity);
        assertNotNull(myFragment);
    }

    public void testAnythingFromMyFragment() {
        // access any public members of myFragment to test
    }
}

Espero que esto ayude. Acepta mi respuesta si encuentras esto útil. Gracias.

  • ¿Cómo solucionas el TestRunner (16162): java.lang.RuntimeException: No se puede resolver la actividad para: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.example/.test.MyFragmentActivityTest $MyFragmentActivity }

    – mach

    19 de julio de 2013 a las 11:12

  • @mach ¿Puede proporcionar el stacktrace completo?

    – abhijit.mitkar

    23 de julio de 2013 a las 10:03

  • El ejemplo anterior no es una prueba unitaria, es una prueba de instrumentación.

    – Muhammad Babar

    5 de junio de 2015 a las 11:04

Estoy bastante seguro de que puede hacer lo que dice, crear una actividad simulada y probar el fragmento desde allí. Solo tiene que exportar la biblioteca de compatibilidad en el proyecto principal y podrá acceder a los fragmentos del proyecto de prueba. Voy a crear un proyecto de muestra y probar el código aquí y actualizaré mi respuesta según lo que descubra.

Para obtener más detalles sobre cómo exportar la biblioteca de compatibilidad, consulte aquí.

  • ¿Puede compartir algún código aquí sobre cómo probar Fragmentos por unidad? ¡Tengo problemas con los fragmentos de pruebas unitarias!

    – Muhammad Babar

    5 de junio de 2015 a las 11:16


avatar de usuario de cristopher cutas
cristopher cutas

Agregando a la respuesta de @ abhijit.mitkar.

Dado un escenario en el que su fragmento no es un miembro público en la actividad bajo prueba.

protected void setUp() {
   mActivity = getActivity();
   mFragment = new TheTargetFragment();

   FragmentTransaction transaction = mActivity.getSupportFragmentManager().beginTransaction();
   transaction.add(R.id.fragment_container, mFragment, "FRAGMENT_TAG");
   transaction.commit();
}

El propósito del código anterior es reemplazar el fragmento con un nuevo objeto de fragmento al que tenemos acceso.

El siguiente código le permitirá obtener acceso a los miembros de la interfaz de usuario de fragmentos.

TextView randomTextView= (TextView) mFragment.getView().findViewById(R.id.textViewRandom);

Obtener la interfaz de usuario de la actividad no lo haré darte el resultado esperado.

TextView randomTextView= (TextView) mActivity.findViewById(R.id.textViewRandom);

Finalmente, si desea hacer algunos cambios en la interfaz de usuario. Como un buen desarrollador de Android, hazlo en el hilo principal.

mActivity.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // set text view's value
    }
});

Nota:
Es posible que desee darle un Thread.sleep() cada vez que finaliza una prueba. Para evitar el bloqueo, getInstrumentation().waitForIdleSync(); no parece funcionar siempre.

solía ActividadInstrumentaciónTestCase2 ya que estaba haciendo pruebas funcionales.

¿Ha sido útil esta solución?