Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels...

42
Principes, Librairies, Impact

Transcript of Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels...

Page 1: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Principes, Librairies, Impact

Page 2: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 02 / 42

• Un framework de test intégré dans le sdk– JUNIT 4

• Deux sortes de tests – Local Tests

• Junit « normal » pour le java « normal »• Tout ce qui n’est pas graphique ou qui n’a pas besoin de l’environnement « android » se teste

comme au S5

– Instrumented Tests• Suites de tests dans des environnements semblables aux applications

• Intégration dans l’IDE• Doc : https://developer.android.com/tools/testing/index.html

http://developer.android.com/training/testing/unit-testing/index.html

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 3: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 03 / 42

• En fait même package que l’application, dans des dossiers séparés

• Mais dans des dossiers à côté de « Main » dans <projet>/app/src– app/src/test/java… pour les

« tests locaux »

– app/src/androidTest/java… pour les « tests instrumentés »

– Possibilité d’avoir des ressources (res) spécifique

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 4: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 04 / 42

android {

// pour pouvoir lire les fichiers depuis R (R.raw par exemple)

// il ne faut pas qu'ils soient compressés

aaptOptions {

noCompress 'txt'

}

// [...]

defaultConfig {

// [...]

// pour que les tests se lancent en JUnit4

testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'

}

// [...]

// pour séparer les ressources pour les tests et celles de l’application

sourceSets {

androidTest {

main.res.srcDirs = ['src/main/res', 'src/androidTest/res']

}

}

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 5: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 05 / 42

Obtenu avec un getResource sur le

ClassLoader

Obtenu avec R.rawavec une configuration

du graddle

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 6: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 06 / 42

Tests sans Android

Configurations (app/src/build.graddle)

Intégration de ressources

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 7: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 07 / 42

• Des tests pour des classes qui ne dépendent pas de l’environnement Android

– Pouvoir les créer sans Context, Instrumentation, etc.

– Pouvoir les utiliser sans Context, Instrumentation, etc.

• Dans un dossier app/src/test

– app/src/test/java/… (package) pour les tests

– app/src/test/resources pour les fichiers utiles aux tests

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 8: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 08 / 42

• Dans un dossier src/test– src/test/java pour les classes– src/test/resources pour les fichiers

•Configuration de build.graddle

// Required -- JUnit 4 frameworktestCompile 'junit:junit:4.12'// Optional -- Mockito frameworktestCompile 'org.mockito:mockito-core:2.+'

– édition à la main du fichier de configuration

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 9: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 09 / 42

• Pour les imports : org.junit…

– Ne pas prendre les autres propositions

• Pour créer les fichiers :

– Soit manuellement

– Soit avec l’ide :

• Clic droit sur une méthode « Go To test »

• Choisir « Create New Test »

• Fenêtre de création

• Au besoin déplacer / renommer le dossier

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 10: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 10 / 42

• à préciser en début de classe de test :

import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 11: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 11 / 42

@Test

public void monTest() throws Exception {

ClassLoader classLoader = this.getClass().getClassLoader();

URL resoclassLoader.getResource("storage_input_test.txt");

File data = new File(resource.getPath());

FileInputStream fis = new FileInputStream(data);

// etc.

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 12: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 12 / 42

Classes ayant besoin de l’environnement Android pour être créées ou pour être utilisées

Android Instrumentation Tests

Configuration du build.graddle

Besoin d’une Activity => création automatique

Mock et Activity => création plus contrôlée

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 13: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 13 / 42

• Pour lancer les tests en Junit4

• Pour séparer les ressources pour les tests de celles de l’application

• Intégration de Junit et mockito

• Les règles pour lancer junit 4– Annotation en fonction du sdk cible

• Pour espresso et ui automator

• Pour Mockito (génération de dex et non pas de class)

android {

// [...]

defaultConfig {

// [...]

// pour que les tests se lancent en JUnit4

testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'

}

sourceSets {

androidTest {

main.res.srcDirs = ['src/main/res', 'src/androidTest/res']

}

}

}

dependencies {

// [...]

androidTestCompile 'junit:junit:4.12'

androidTestCompile 'org.mockito:mockito-core:2.+‘

androidTestCompile 'com.android.support.test:runner:0.5

androidTestCompile 'com.android.support.test:rules:0.5'

androidTestCompile 'com.android.support:support-annotations:25+'

androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'

androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

androidTestCompile ‘com.linkedin.dexmaker:dexmaker-mockito:2.+'

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 14: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 14 / 42

// annotation permettant de lancer le test (Junit 4)

@RunWith(AndroidJUnit4.class)

public class ConversionTest {

// lancement de l’activité : initialisation dès le début du test

// mActivityRule permet d’accéder à l’activité = le contexte

// sinon InstrumentationRegistry.getInstrumentation() permet

// d’accéder à l’intrumentation (environnement android)

@Rule

public ActivityTestRule<TodoList> mActivityRule =

new ActivityTestRule<>(TodoList.class);

@Before

public void startTest() { }

@After

public void endTest() { }

@Test

public void monTest() { }

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 15: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 15 / 42

• Besoin d’initialisation– @RunWith(MockitoJUnitRunner.class) lance JUnit3...– Initialisation dans le @Before

• Ensemble d’instruction à lancer :// lance l’activity TodoList pour les tests

@RuleActivityTestRule<TodoList> mActivityRule = new ActivityTestRule<>(TodoList.class);

Context initialContext;

@Beforepublic void startTest() throws Exception {

// [...]initialContext = mActivityRule.getActivity();System.setProperty("dexmaker.dexcache", initialContext.getCacheDir().getPath());

MockitoAnnotations.initMocks(this);}

• Pb : initialContext suppose que l’application soit « lancée »... s’il faut faire un mock pour l’initialisation…

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 16: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 16 / 42

• Une application se lance avec les données sauvegardées d’une session à une autre

• Mais pour les tests, cela pose problème : il n’y a pas de contrôle des sessions passées

• Besoin de « mock » pour l’initialisation– Ne pas charger pour les tests

• Solution – paramétrer le chargement dans l’Activity à un Intent

– Faire un chargement « paresseux » (lazzy) dans le test

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 17: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 17 / 42

@Rule

public ActivityTestRule<TodoList> mActivityRule = new ActivityTestRule<>(TodoList.class, true, false);

@Mock

Sauvegarde mockSauvegarde;

// pour des raisons d’initialisation, à déclarer en Context et non pas en TodoList

// (TodoList est la classe réelle)

Context todo;

@Before

public void startTest() throws Exception {

// Lazily start the Activity from the ActivityTestRule this time to inject the start Intent

Intent startIntent = new Intent();

startIntent.putExtra(TodoList.MUSTLOAD, false);

mActivityRule.launchActivity(startIntent);

todo = mActivityRule.getActivity();

System.setProperty("dexmaker.dexcache", todo.getCacheDir().getPath());

MockitoAnnotations.initMocks(this);

// [...] création du mock

// [...] et affectation...

when(mockSauvegarde.charger(any(Context.class))).thenReturn(loaded);

TodoList.sauvegarde = mockSauvegarde;

// après on utilise le mock

((TodoList) todo).chargerNoteEnregistees();

// et on attend que l’activity ne soit plus active

InstrumentationRegistry.getInstrumentation().waitForIdleSync();

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 18: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 18 / 42

// en cas de modification « static », il faut remettre en

// « place » pour les tests suivants

@After

public void endTest() {

// on remet la valeur par défaut

TodoList.sauvegarde = Sauvegarde.getInstance();

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 19: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 19 / 42

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.list_ui);

boolean loadingToDo = true;

loadingToDo = getIntent().getBooleanExtra(MUSTLOAD, true); // si Intent absent, true par défaut

// [...]

/** loading **/

/** but not in a rotation... or a restore... **/

if ((savedInstanceState == null) && loadingToDo) {

/*** code initial, non testable separement... ***/

/*

si le code de chargerNoteEnregistees() est ici alors ce n'est pas testable sans lancer

toute l'application...

*/

chargerNoteEnregistees();

}

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 20: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 20 / 42

• On peut accéder à l’activité par : mActivityRule.getActivity();

• On peut accéder à l’environnement Android par : InstrumentationRegistry.getInstrumentation

()

– Cela permet notamment : InstrumentationRegistry.getInstrumentation().wa

itForIdleSync();

– attente actions “graphique” terminées

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 21: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 21 / 42

@Test

public void testCreationItem() {

// le chargement des données, par un mock, est fait préalablement

// un cast est nécessaire

List<Item> items = ((TodoList) mActivityRule.getActivity()).getListItem();

// notes est un tableau, il fait partie de l’oracle

// Item est une classe de l’application

// il est ici vérifier que les éléments ont été créés correctement

assertEquals("nb item attendu : "+notes.length, notes.length, items.size());

for(int i = 0; i < notes.length; i++) {

Item item = items.get(i);

assertEquals("texte de "+i, notes[i], item.getNote());

assertEquals("creation de "+i, (long) buttoirs[i], item.getButtoir());

assertEquals("buttoir de "+i, (long) creations[i], item.getCreation());

}

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 22: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 22 / 42

Impact sur l’architecture : isoler ce qui doit être testé unitairement

Conséquences : modularité, contraintes sur l’architecture

Illustration avec la sauvegarde locale

version instrumentée

version locale

Permet l’utilisation à la librairie Mockito

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 23: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 23 / 42

• Ouverture de flux :

– Méthode de la classe Context

– FileInputStream avec openFileInput(Nom)

– FileOutputStream avec openFileOutput(Nom, Mode)

• Mode = Context.MODE_PRIVATE (écrasement)

• Mode = Context.MODE_APPEND (concaténation)

– /data/data/<app>/files

• Flux usuels de java

Tip: If you want to save a static file in your

application at compile time, save the file in yourproject res/raw/directory. You can open it

with openRawResource(), passing

the R.raw.<filename> resource ID. This method

returns an InputStream that you can use to read

the file (but you cannot write to the original file).

[http://developer.android.com/]

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 24: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 24 / 42

• Chargement / Sauvegare de notes dans la TodoList

• Chargement… dans le onCreate(pour être dès le début)– Code non accessible sans le onCreate…– Complexification du test…– … qui n’est plus unitaire

• Isolation– Testable séparément– Mock possible– Choix :

• paramètrage• retour

Activity

onCreate

Load

Activity

onCreate

load()

invokes

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 25: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 25 / 42

• Création d’Activity « lourde » de sens

• Mock « static » impossible ?– Cas d’utilitaires…– Powermock a priori non compatible…

• Solution : utilisation d’un champ static– Un mock peut être fait– Ce mock peut être affecté avant la

création de l’objet

• Méthode load() pour tester utilisation sans l’ensemble de l’activité

Activity

onCreate

load()uses mySave

invokes

static Save mySave = usualValue ;

Save

Mock of Save

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 26: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 26 / 42

• Chargement

– paramètre : le Context• Nécessaire pour ouvrir le flux

– retour : un tableau de valeurs • séparation lecture des données /

création d’objet (fragment) en partie graphique

• MockContext

– Les méthodes par défaut lève des exceptions

– Permet de remplacer les méthodes de communication avec l’extérieur

– le test devient indépendant au Context

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 27: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 27 / 42

• Appel à setContext

MyMockContext context = new MyMockContext(R.raw.storage_input_test);

• Chargé un fichier pour le test, placé dans res/raw

protected class MyMockContext extends MockContext {

/** the file must not be compressed... **/

int idRaw;

MyMockContext() { this(R.raw.storage_input_test); }

MyMockContext(int idRaw) {

super();

this.idRaw = idRaw;

}

public FileInputStream openFileInput(String name) {

AssetFileDescriptor afd = initialContext.getResources().openRawResourceFd(idRaw);

FileInputStream res = null;

res = new FileInputStream(afd.getFileDescriptor());

return res;

}

} Voir aussi RenamingDelegatingContext

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 28: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 28 / 42

• Comment vérifier qu’on écrit (sauvegarde) ce qu’il faut ?

– vérifier que c’est au bon format…

– Avec les bonnes valeurs…

• Il faudrait pouvoir recevoir le résultat du flux de sortie (FileOutputStream)

• => Mock avec Mockito

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 29: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 29 / 42

public FileOutputStream openFileOutput(String name, int mode) {

FileOutputStream res = mock(FileOutputStream.class);

try {

// objectif : simuler l’écriture

// récupérer les « write » et stocker ce qui

// est écrit dans une String « written », champ de

// classe de MyMockContext

// mock write(int)

// mock write(byte[])

// mock write(byte[], int, int)

} catch (IOException e) {

e.printStackTrace();

}

return res;

}

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 30: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 30 / 42

doAnswer(new Answer() {public Object answer(InvocationOnMock invocation) {

Object[] args = invocation.getArguments();

byte[] bytes = (byte[]) args[0];int start = ((Integer) args[1]).intValue();int len = ((Integer) args[2]).intValue();bytes = Arrays.copyOfRange(bytes, start, start + len);

try {written = written + new String(bytes, "UTF-8");

} catch (UnsupportedEncodingException e) {e.printStackTrace();

}return null;

}}).when(res).write(any(byte[].class), anyInt(), anyInt());

• Récupérer la valeur (args[0]) à écrire

• Récupérer le début (args[1])

• Récupérer la longueur (args[2])

• Cast en String et concaténation

• void write(byte[] b, intoffset, int length)

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 31: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 31 / 42

• Test d’écriture :

– Mock du Context (MyMockContext) -> context

– Préparation des objets à sauvegarder

• Mock…

• Oracle : on connait la String à écrire -> expected

– On fait la sauvegarde

• Écriture via le mock du FileOutputStream

– On compare assertEquals("msg...", expected, context.written);

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 32: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 32 / 42

• Séparer

– L’obtention des I/O Stream

– De leur utilisation

TodoList(Activity)

SauvegardeDonnees[] charger(Context c)

void sauvegarder(List<Item> mesItems, Context c)

TodoList(Activity)

SauvegardeEncapsuleeDonnees[] charger(Context c)

void sauvegarder(List<Item> mesItems, Context c)

EntreeSortieFichierArrayList<Donnees> chargerDepuisStream(FileInputStream fis, String

SEPARATOR)

void enregistrerVersStream(List<Item> mesItems, FileOutputStream

fos, String SEPARATOR)

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 33: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 33 / 42

• EntreeSortieFichier– Indépendance d’Android

• Réutilisable

• Tests locaux

– Paramétrage à choisir

• Transparent pour TodoList

• SauvegardeEncapsulee– Modèle pour l’utilisation de capteur : séparation de l’acquisition du

traitement

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 34: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 34 / 42

Cas particulier de tests instrumentés

Utilisation de l’extérieur (à la place d’un « utilisateur »)

http://developer.android.com/tools/testing-support-

library/index.html#Espresso

http://developer.android.com/tools/testing-support-

library/index.html#UIAutomator

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 35: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 35 / 42

• Lancement avec ActivityTestRule– « Comme » un test instrumenté

• Permet de faire des actions– Sans s’occuper du thread graphique

• Permet de faire des vérifications• Fonctionne avec des Matchers / Actions / Assertions• https://developer.android.com/training/testing/ui-

testing/espresso-testing.html• https://google.github.io/android-testing-support-

library/docs/espresso/cheatsheet/

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 36: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 36 / 42

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 37: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 37 / 42

onView(withId(R.id.ajouter)).perform(click());

android.support.test.espresso.Espresso.onView

android.support.test.espresso.matcher.ViewMatchers.withIdUn matcher pour désigner un éléments avec son id… doit être sur l’écran

android.support.test.espresso.action.ViewActions.click

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 38: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 38 / 42

public static Matcher<View> numberOfChildren (final int size) {

return new TypeSafeMatcher<View>() {

int mysize = 0;

@Override public boolean matchesSafely (final View view) {

boolean result = false;

if (view instanceof ViewGroup) {

mysize = ((ViewGroup) view).getChildCount ();

result = (mysize == size);

}

return result ;

}

@Override public void describeTo (final Description description) {

description.appendText ("ViewGroup should have " + size + " items and has "+mysize);

}

};

}

Pour une utilisation :

onView(withId(R.id.liste)).check(ViewAssertions.matches(numberOfChildren(i + 1)));

Test effectué : si renvoie « true », cela correspond

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 39: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 39 / 42

• Si l’écran est trop petit…

– Les sélections des objets graphiques ne sont possibles que si les objets sont visibles…

– … erreur dans les

• Si le layout dépend de la résolution…

• …

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 40: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 40 / 42

• Permet de « sortir » de l’application

– Accès au dispositif, exemple : mDevice.setOrientationLeft();

– Sélection des objets graphique avec UI Automator ou Espresso

• Lancement de l’application particulier (c.f. transparent suivant)

• https://developer.android.com/training/testing/ui-testing/uiautomator-testing.html

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 41: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 41 / 42

// dans le @Before

// UiDevice mDevice;

mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

mDevice.waitForIdle();

// Wait for launcher

final String launcherPackage = mDevice.getLauncherPackageName();

assertThat(launcherPackage, notNullValue());

mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), 5000);

// Launch the app

Context context = InstrumentationRegistry.getContext();

final Intent intent = context.getPackageManager().

getLaunchIntentForPackage("gonin.renevier.philippe.exempletest");

intent.putExtra(TodoList.MUSTLOAD, false);

// Clear out any previous instances

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);

context.startActivity(intent);

// attente fin creation

mDevice.waitForWindowUpdate("gonin.renevier.philippe.exempletest",1000);

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques

Page 42: Principes, Librairies, Impactdeptinfo.unice.fr/~renevier/ancien/POO-2017/cours... · •Flux usuels de java Tip: If you want to save a static file in your application at compile time,

Philippe Renevier Gonin - L3 Informatique parcours Miage, semestre 6 - POO - Tests & Android 42 / 42

• Rotation (re-création des objets)

• Gestion des threads (graphique vs le reste)

• Incorporation de ressources dans les classes

– Si intégration trop couplée, cela ne sera pas « mockable »

– Cas des listeners (accéléromètres, gps, etc.)

– Cas d’accès à des fichiers de stockage, de bd, etc.

– Cas d’accès à des « intents » (reconnaissance vocale de google par exemple)

Tests & Android Tests Locaux Tests Instrumentés Tests et Architecture Tests Graphiques