4 Konstruktion
4.1 Testverkyg
Innan de verkliga testerna implementerades valdes verktygen Espresso och Appium ut för utvärdering. Denna utvärdering gjordes för att bedöma vilket verktyg som var bäst lämpat för implementation i detta projekt.
4.1.1 Appium
Innan installationen av Appium kan påbörjas installerades NodeJs eftersom Appium server körs i NodeJs. Appium installerades sedan enligt [21]
När samtliga beroenden installerats skapades ett nytt projekt med byggsystemet Maven. Följande beroenden lades till i projektets pom.xml.
• Selenium-Java, version 2.46.0 • TestNG, version 6.1.1
• Appium Java-client library, version 3.0.0
Ett minimalt test implementerades för utvärdering. Kodexempel följer nedan. Appiumtester utförs i tre steg.
@BeforeMethod
protected void prepareAndroidForAppium() throws
MalformedURLException { File appDir = new
File("C:\\Users\\Berglund\\Dropbox\\Exjobb\\Testkod\\Telia_Touch point\\SMESOL_Android\\SMESOL_Android\\build\\outputs\\apk\\"); File app = new File(appDir, "SMESOL_Android-debug.apk"); DesiredCapabilities capabilities = new
DesiredCapabilities();
capabilities.setCapability("device","Android"); //mandatory capabilities
capabilities.setCapability("deviceName","Android"); capabilities.setCapability("platformName","Android"); capabilities.setCapability("unicodeKeyboard", true); //other caps
capabilities.setCapability("app", app.getAbsolutePath()); driver = new AndroidDriver(new
22
Figur 6: Metoden prepareAndroidForAppium.
Först ansluter testet till Appium-servern via dess IP-adress och port. Det valda applikationspaketet installeras och applikationen startas. Se Figur 6 ovan.
@Test
private void appiumDemoTest() throws InterruptedException{ driver.manage()
.timeouts().implicitlyWait(30, TimeUnit.SECONDS); driver.scrollToExact("Testa appen");
driver.findElement(By.id("se.teliasonera.smesol.dev:id/demo_mode _button")).click();
driver.scrollToExact("Driftinfo och nyheter");
driver.findElement(By.id("se.teliasonera.smesol.dev:id/settings_ menu_item")).click();
driver.scrollToExact("VISA KONTAKTER");
driver.findElement(By.id("se.teliasonera.smesol.dev:id/user_sett ings_calltransfer_quick_info")).click();
}
Figur 7: Kodavsnitt från ett test som implementerades under utvärderingen
Andra steget är utförandet av det faktiska testet. Här görs all navigering och verifiering i applikationen. I Figur 7 ovan redovisas ett kodavsnitt från ett av de mindre tester som skrev under utvärderingen av Appium. @AfterMethod
public void tearDown() throws Exception { driver.resetApp();
driver.quit();
}
Figur 8: Metoden tearDown() som görs efter varje test.
Sista steget som visas i Figur 8 stänger ner testet och applikationen och avslutar sessionen mot Appium-servern. Detta steg rensar även användardata för appen för att garantera att alla tester utgår från samma förhållanden.
23
4.1.2 Espresso
För att använda Espresso och Android Testing Support Library installerades Android Support Repository med Android SDK manager. När ett Android projekt skapas i Android Studio skapas per automatik ett paket till för Espressotester. Innan de faktiska testerna kunde skrivas installerades nödvändiga beroenden enligt [22]. Espressotester använder JUnit annotation för att sätta upp testmiljön och är utformade i tre delar.
• Först körs en metod som annoteras med @Before där en instans av den del av applikationen som ska testas skapas.
• Andra delen innehålla själva testskripet med instruktioner om navigering, inmatning och kontroller. Dessa metoder annoteras med @Test.
• Tredje och sista delen monterar ner testet och sparar resultaten. Metoden annoteras med @After.
En abstract klass TestBase skapades innehållande metoden setup() annoterad med @Before och metoden teardown() annoterad med @After. Nedan i Figur 9 visas ett kodavsnitt med dessa metoder från klassen TestBase.
24 @RunWith(AndroidJUnit4.class)
public abstract class TestBase { @Rule
public ActivityTestRule<MainActivity> mActivityRule = new
ActivityTestRule<>(MainActivity.class, true, true);
@Before
public void setup() {
instrumentation = InstrumentationRegistry .getInstrumentation(); // Disable animations
systemAnimations = new SystemAnimations(instrumentation
.getTargetContext()); systemAnimations.disableAll(); // Register idling resource
servicesIdlingResource = new IntentServiceIdlingResource(
instrumentation.getTargetContext());
} @After
public void tearDown(){
systemAnimations.enableAll();
Espresso
.unregisterIdlingResources(servicesIdlingResource);
}
Figur 9: Ett kodavsnitt från klassen TestBase.
Dessa metoder tillsammans med variabeln mActivityRule annoterad med @Rule ger testet möjlighet att påverka grafiska komponenter och simulera användarinteraktion. Varje enskilt test skapas i en egen klass som ärver basklassen TestBase och får därmed tillgång att testa applikationens funktionalitet.
4.2 Jenkins
För att utföra tester vid bygge på en CI-server installerades en instans av Jenkins som en virtuell maskin med hjälp av Docker. Detta genomfördes genom att följa instruktioner enligt [23].
4.2.1 Insticksmoduler
För att köra tester och presentera resultat installerades ett antal insticksmoduler till Jenkins. Dessa insticksmoduler installeras direkt från Jenkins webgränssnitt. Git plugin installerades för att låta Jenkins direkt
25
komma åt kodbasen. Gradle plugin installerades för att bygga själva appen och producera applikationspaket (APK). För att publicera testresultat installerades insticksmodulen JUnit Plugin som behandlar XML-filer i JUnit format och presenterar innehållet läsbart i webgränssnittet.
4.2.2 Konfiguration och installation
När Jenkins instansen var installerad behövde denna konfigureras för att bygga Android applikationer med hjälp av byggsystemet Gradle. Först installerades Java SDK och Java JRE eftersom Android applikationer skrivs i Java och använder Java APIer. Utöver detta installerades Android SDK med tillhörande komponenter för att senare ha möjlighet att installera dessa på en enhet där testen utförs. Eftersom den fysiska servern är fysiskt otillgänglig i en serverhall har testenheter som använts under examensarbetet kopplats in på en särskilt WiFi som sitter på samma virtuella nätverk som servern. På detta vis kunde APK installeras på tidigare nämnd telefon för att sedan starta igång testerna.
För att detta skulle fungera anslöts telefonen första gången manuellt. För att göra detta öppnades en SSH-tunnel till Docker servern och ett bash skal exekverades på Jenkins instansen för att komma åt systemet där Android SDK finns installerat. En ADB-server på en förvald port, i detta fall 5555. ADB-servern ansluter sedan till telefonen med dess lokala IP-adress. Följande kommandon kördes för att åstadkomma detta, se Figur 10 nedan.
Figur 10: Testenhet ansluts mot Jenkins för att köra tester.
Sedan manuellt ansluta till telefonen via dess lokala IP-adress. När telefonen är ansluten kan tester köras vid bygge.
26
4.2.3 Git-konfiguration
För detta examensarbete skapades en separat branch från applikationens utvecklingsbranch (dev). Alla tester som skapades lades till i denna branch och användes sedan för att bygga och köra tester via Jenkins. Detta gjordes genom att lägga till en kommit-hook vilket är ett Bash-skript som körs när ny kod laddas upp till Git-servern. Skriptet använder cURL för att trigga igång Jenkinsbygget med hjälp av en token som identifierare. Skriptet i sin helhet finns på Bilaga A. Insticksmodulen för Git konfigurerades genom att ange URL till Dewires Git-repo och specificera vilken branch som skulle användas.
Figur 11: Konfiguration av insticksmodul för Git
Ovan i Figur 11 visas en skärmdump från konfigurationen av insticksmodulen för Git.