In een eerdere blog (Unittest frameworks bij functioneel testen: waarom?) heb ik uitgelegd waarom ik graag een unittest framework gebruik, zelfs bij functioneel testen. Aan het einde verwees ik kort naar enkele tutorials om hiermee aan de slag te gaan. Nu wil ik jullie laten zien hoe ik een testframework inzet en hoe ik daarmee mijn eerste test schrijf. Aan het einde van deze tutorial hebben we een framework opgezet met daarin een test, weet je hoe je TestNG kunt gebruiken en wat voor extra functionaliteit deze biedt.

(Lees de blog Unittest frameworks bij functioneel testen: waarom?)

Voor deze tutorial heb je niet veel voorkennis van programmeren nodig, ook al zijn we bezig met code. Wel verwacht ik dat er al enkele zaken op je computer zijn geïnstalleerd, of dat je de handleidingen van de tools zelf kunt volgen voor de installatie. Denk hierbij aan Windows 10, Eclipse Oxygen.2, Java SE Development Kit 8, Maven 3.5, Selenium 3.11, TestNG 6.14 en WebDriverManager 2.1. Deze tutorial is ook geschikt voor op een Mac of Linux; zolang de hoofdversies van de tools hetzelfde zijn, moet de informatie kloppen. De code is geschreven in Java.

Vereiste onderdelen

Voor we van start gaan met ons eerste testproject moeten we wat voorbereidingen treffen. De beschreven installaties zijn generiek. Als je deze onderdelen al hebt geïnstalleerd, kun je deze paragrafen overslaan. Let bij het installeren goed op of jouw systeem de 32- of 64-bit-versies van de software nodig heeft. Het is soms even zoeken naar de 32–bit-versies, maar ze zijn er wel.

Java

Het testframework dat we gaan gebruiken, en daarmee ook de versie van Selenium, zijn voor Java gemaakt. Daarom moeten we als eerste Java installeren en instellen op onze computer. Als er nog geen JDK (Java Development Kit) op je machine staat, installeer dan JDK 8. De exacte versie maakt in dit geval niet uit. Op de Oracle-pagina kun je JDK downloaden. Run de installer, daarna kun je je environmentvariabelen updaten. Zet hierbij de bin van de JDK in je PATH-variabele en maak een JAVA_HOME-variabele aan met de map boven de bin. Voor uitgebreide instructies en uitleg zie de installatiepagina’s van Oracle zelf en deze pagina over het zetten van JAVA_HOME-variabele.

Maven

Maven is een tool waarmee een softwareproject gemanaged kan worden. Het kan gebruikt worden voor onder andere het managen van dependencies (andere libraries/tools die je in je project gebruikt). Download en installeer Maven. Vergeet niet de bin directory van Maven toe te voegen aan de PATH-variabele (zoals je hierboven met de bin van JDK gedaan hebt).

Eclipse

Als je code gaat schrijven, is het handig om een IDE te gebruiken. Dit programma waarin je de code schrijft, biedt veel extra opties en hulpmiddelen. De twee meest gebruikte IDE’s zijn Eclipse en IntelliJ. Aan welke van de twee jij de voorkeur geeft, is persoonlijk. Kijk ook naar wat je collega’s gebruiken. Als je dezelfde hulpmiddelen gebruikt, kun je van hun kennis gebruikmaken. Je hebt overigens maar een van de twee IDE’s nodig. Deze tutorial gebruikt Eclipse (InteliJ kan hetzelfde, maar het zal er net iets anders uitzien).

Download en installeer Eclipse. Kijk voor de exacte instructies op de website. De standaardeditie is voldoende.

Omdat we TestNG gaan gebruiken als framework, moeten we ook de TestNG Eclipse Plugin installeren.

  1. Open de Eclipse Marketplace waar je plugins kunt vinden en installeren.

    Image

  2. Zoek in de Eclipse Marketplace naar de TestNG plugin en klik op [Install].

    Image

  3. Laat beide opties geselecteerd staan en klik op [Confirm].

    Image

  4. Accepteer de licentieovereenkomst en rond de installatie af. Het kan zijn dat er een waarschuwing getoond wordt, deze kun je accepteren en wegklikken.

    Image

  5. Restart Eclipse als hierom gevraagd wordt.

Opzetten project

Het project dat we gaan opzetten, is een Maven-project. Dat betekent dat we een POM (Project Object Model) kunnen gebruiken om ons project te beschrijven. Deze POM gebruikt Maven later om het project te bouwen. Voor meer informatie over wat een POM is, wat je er mee kunt en wat Maven ermee doet, kijk je op de introductiepagina van Maven. We beginnen met het aanmaken van een Maven-project.

  1. Kies ervoor om een ander project aan te maken door te klikken op File > New > Other…

    Image

  2. Open de Maven-map en kies voor een Maven Project en klik daarna op [Next].

    Image

  3. Vink het vakje aan voor Create a simple project en klik daarna op [Next].

    Image

  4. Op dit scherm vul je informatie in over je project. Als je meer wilt weten over wat de velden precies betekenen, kijk dan bij de informatie over de Maven Coördinaties op de Maven-site. Dit is slechts een demo, dus wat je invult maakt niet zoveel uit, maar wat er ongeveer hoort te staan is:

    • Group Id: naam van je bedrijf (met punten tussen de woorden, geen hoofdletters)
    • Artifact Id: naam van je project (aan elkaar, beginnend met een kleine letter)
    • Name: een leesbare naam van je project
    • Description: een beschrijving van je project

    Klik nu op [Finish]

    Image

  5. Het project is nu aangemaakt. In de package-explorer links op het scherm kun je het project bekijken (misschien moet je even het welkomstscherm wegklikken). Er is een mappenstructuur opgezet met daarin een src (source) map, met daarin de mappen main en test. In de map main komt de code van je project, in de map test de tests die dat project testen. We maken hier een testproject, maar omdat de tests de code van het project zijn, en iets testen buiten dit project, plaatsen we deze tests in de main-map. Je kunt ook zien dat er een pom.xml is aangemaakt, die gaan we nu aanpassen en invullen.

    Image

Eerste test

We hebben nu een project, maar dit is nog helemaal leeg. Er zitten nog geen tests in. Daar gaan we nu voor zorgen.

Dependencies toevoegen

Dependencies zijn stukjes code die iemand anders heeft geschreven, die wij gebruiken in onze code. Maven managed deze voor ons. Als wij in de pom.xml aangeven welke code wij nodig hebben, zorgt Maven ervoor dat deze beschikbaar is. Dit betekent dat we ons project makkelijk kunnen uitvoeren op andere omgevingen door alleen het project te delen.

De dependencies die we gaan toevoegen zijn:

  • Selenium: de bekende testtool voor het testen van websites/webapps
  • WebDriverManager: een tool die ervoor zorgt dat we altijd de juiste webdriver voor Selenium hebben, zonder deze lokaal te hoeven opslaan en updaten
  • TestNG: door dit testframework te gebruiken, kunnen we de testen beter organiseren en testresultaten opslaan in een rapport
  • Simple Logging Facade for Java: een tool die nodig is om de logging te faciliteren
  1. Open de pom.xml via het overzicht aan de linkerkant. Als je deze opent, zie je niet meteen de XML, maar krijg je verschillende tabbladen te zien die je helpen om de pom juist op te zetten. Klik op het tabblad Dependencies.

    Image

  2. Klik op [Add…] om onze eerste dependency toe te voegen.

    Image

  3. Vul de velden boven in het scherm in. Druk daarna op [OK] om de dependency toe te voegen. Met de ingevoerde informatie weet Maven welke code wij uit de Maven-repository willen ophalen. Zoals je ziet, is deze informatie vergelijkbaar met de informatie die wij hebben ingevoerd toen we ons project aanmaakten. De precieze informatie over dependencies, zoals de group id en versie, kun je altijd vinden in de Maven Repository.

    • Group Id: seleniumhq.selenium
    • Artifact Id: selenium-java
    • Version: 3.11.0

    Image

  4. Voeg daarna op dezelfde manier de volgende dependencies toe:

    1. WebDriverManager
      • Group Id: github.bonigarcia
      • Artifact Id: webdrivermanager
      • Version: 2.1.0
    2. TestNG
      • Group Id: testng
      • Artifact Id: testing
      • Version: 6.14.2
    3. SL4J Api
      • Group Id: slf4j
      • Artifact Id: slf4j-api
      • Version: 1.6.6
    4. SL4J Simple
      • Group Id: slf4j
      • Artifact Id: slf4j-simple
      • Version: 1.6.6

    Image

  5. Als je nu op het laatste tabblad, pom.xml, klikt, zie je dat de dependencies in de xml zijn ingevoegd. Sla de pom.xml nu op.

    Image

De eerste tests

Na al dat voorbereidend werk zijn we nu eindelijk toe aan het maken van onze eerste test. Wat we gaan doen, is het openen van een webpagina en het controleren of een bepaalde tekst op de juiste locatie zichtbaar is.

  1. Klik met je rechtermuisknop op de map src/main/java. Selecteer New en dan Class. Hiermee maak je een nieuwe Java-class aan. We maken onze test overigens aan in de Java-map in plaats van de testmap, omdat de testen in ons geval de enige code in het project zijn. Mocht je de code schrijven in hetzelfde project als de code, vraag dan aan de ontwikkelaars van je project wat de beste plaats is voor de testcode.

    Image

  2. Voer een naam in voor je bestand en druk op [Finish].

    Image

  3. Eclipse heeft nu een Java class file aangemaakt met basiscode.

    Image

  4. Nu gaan we beginnen met de code. We zorgen er eerst voor dat we een driver hebben, waarmee de browser kan worden aangestuurd (en de test dus in de browser kan worden uitgevoerd). De code is als volgt:

    private WebDriver driver;
    
    @BeforeMethod
    public static void setupClass() {
        WebDriverManager.chromedriver().setup();
        driver = new ChromeDriver();
    } 
    

    Kopieer en plak deze code onder regel 3 (public class EersteTest {).

    Image

    De code doet het volgende:

    • We maken een WebDriver aan met de naam driver, die we binnen de hele class kunnen aanspreken.
    • We maken een setupClass-methode. Omdat de annotatie @BeforeMethod ervoor staat, zal deze voor alle andere code worden uitgevoerd. In de methode doen we de setup van de Chrome driver. Hiervoor maken we gebruik van de WebDriverManager (een van onze eerder geïmporteerde dependencies). Daarna maken we van de driver (die we als eerste hebben aangemaakt) een ChromeDriver. Deze driver wordt in de rest van de tests gebruikt om de browser aan te spreken.

    De rode lijnen die je ziet onder de code betekenen dat er iets nog niet helemaal goed is. In ons geval hebben we de benodigde code nog niet geïmporteerd in onze class. Gelukkig kan Eclipse ons hierbij helpen. Door met je muis op een rood onderlijnd woord te staan, geeft Eclipse suggesties voor een oplossing.

    • Ga op het woord WebDriver staan in regel 4. Kies voor Import ‘WebDriver’ (org.openqa.selenium).

      Image

    • Je ziet nu dat de regel import org.openqa.selenium.WebDriver; is toegevoegd. Hierdoor kunnen we de WebDriver uit het Selenium-pakket gebruiken.

      Image

    • Doe dit nu voor alle rood onderlijnde woorden in je code. Je code ziet er nu als volgt uit.

      Image

    Alleen het woord driver in regel 11 is nog geel onderlijnd, omdat we deze variabele nergens gebruiken.

  5. We kunnen de browser aanspreken, laten we dat dan ook maar eens doen met onze eerste echte test. We maken een nieuwe methode aan voor onze test, genaamd controleerTitle. We annoteren deze met @Test, zodat het TestNG-framework weet dat we het hier over een test hebben. In de test zeggen we eerst tegen de driver dat hij de url http://www.nu.nl moet openen (get). Daarna gaan we de title van de pagina ophalen (driver.getTitle()) en deze vergelijken met de titel die wij verwachten. Dat het een vergelijking is, geven we aan door Assert.assertequals te gebruiken. Deze functie kan van alles met elkaar vergelijken, in dit geval twee stukken tekst (strings). Voeg de volgende code toe onder regel 16. Los de rode lijntjes op zoals aangegeven en sla het bestand op.

    @Test
    public static void controleerTitle() {
        driver.get("http://www.nu.nl");
        Assert.assertEquals(driver.getTitle(), "NU - Het laatste nieuws het eerst op NU.nl");
    }  
    

    Image

    Als je zelf de code hebt getypt (in plaats van knippen/plakken) heb je misschien gemerkt dat Eclipse je probeert te helpen door suggesties te geven voor hoe je verder kunt gaan (bijvoorbeeld bij driver.get, wat kan worden aangevuld tot driver.getTitle). Deze functie kan je helpen om te zien welke mogelijkheden er zijn en welke parameters eventueel verwacht worden.

  6. Als laatste gaan we een stukje code toevoegen dat wordt uitgevoerd na de test. Deze code zal kijken of er een browser openstaat door de test (is er een driver?). Zo ja, dan wordt deze gesloten. Dit is vooral handig als je heel veel tests hebt die ieder een browserscherm zullen openen.

    Voeg de volgende code toe onder regel 24. Los de rode lijntjes op zoals aangegeven en sla het bestand op.

    @AfterTest
    public void teardown() {
        if (driver != null) {
        driver.quit();
        }
    }
    

    Image

Tests uitvoeren

  1. We hebben nu onze eerste test! Druk boven in op de Run-knop om onze test uit te voeren.

    Image

  2. Als het goed is, zie je nu de browser en nu.nl openen. In Eclipse kun je de testuitvoer volgen in de console (onderaan het scherm). Schrik niet van de rode tekst, dit zijn enkele waarschuwingen die de uitvoer van de test niet beïnvloeden. In de console zie je ook het resultaat van de testuitvoer (Tests run: 1, Failures: 0, Skips: 0).

    Image

  3. Klik nu op het tabje naast de Console, Results of running class Eerste Test. Dit is de tab van TestNG, waar je meer details kunt zien over de testresultaten. Nu is er slechts een test, maar zodra er veel meer tests zijn in verschillende classes kun je je voorstellen dat je veel hebt aan deze informatie.

    Image

  4. Verander de verwachte titel in de test, zodat de test zal falen. Sla de test op en voer de test nogmaals uit. In de Console zal je nu zien staan (Tests run: 1, Failures: 1, Skips: 0), en de TestNG-tab zal er als volg uitzien:

    Image

    Niet alleen kun je zien dat de test gefaald is, maar je kunt ook zien waarom. De exceptie die gegeven wordt, laat zien dat hij Craft verwachtte te vinden, maar hij vond in werkelijkheid NU – Het laatste nieuws het eerst op NU.nl.

  5. De TestNG-tab heeft nog meer handige functies. Zo maakt TestNG ook een rapport voor je. Zie hiervoor de knoppen aan de rechterkant van het tabblad. Zoals je kunt zien, is dit rapport een HTML-bestand dat lokaal wordt opgeslagen. Hierdoor kan het makkelijk gebruikt worden richting het team, de productowner of de stakeholders.

    Image

  6. De overige knoppen zijn ook handig:

    1. Clear results: om alle resultaten te wissen
    2. Next/Previous Failure: om makkelijk door alle falende testen te lopen
    3. Rerun Last Test: de laatste test nog eens uitvoeren
    4. Run Failed Test: alleen de gefaalde test nog eens uitvoeren
    5. Test Run History…: een x aantal eerder uitgevoerde tests (en hun resultaten)

    Image

Hoe nu verder?

We hebben nu een test opgezet in ons framework. Voor een deel is het zware werk gedaan en hebben we nu een solide basis om meer tests toe te voegen. Daarnaast kunnen we ook extra functionaliteit toevoegen aan ons framework. Enkele voorbeelden zijn:

  • Als we de Maven Surefire Plugin toevoegen kunnen we de tests ook via Maven uitvoeren. Hierdoor wordt een integratie met een continuous integration systeem, zoals Jenkins, mogelijk. Dit betekent dat het uitvoeren van de tests een stap in het bouwproces kan zijn, dat de rapportages in Jenkins beschikbaar zijn en dat tests ook periodiek kunnen worden uitgevoerd (bijvoorbeeld iedere nacht).
  • Als we de Allure-plugin toevoegen, kunnen we mooie rapportages maken die voor de niet-technische leden van het team beter te lezen is.
  • Het opzetten van de driver kunnen we verplaatsen naar een aparte class, zodat we dit maar een keer hoeven te doen en we er steeds gebruik van kunnen maken.
  • We kunnen gebruikmaken van variabelen (bijvoorbeeld voor de te testen URL) in een apart bestand, zodat we deze maar op één plek hoeven aan te passen als deze verandert.