Software testing

Software testing

Introductie

Software testing

Software testing is the process of evaluating and
verifying that a software product or application
does what it’s supposed to do.

 

  • Vergelijken van:
    • Verwacht gedrag
    • Actueel gedrag

Software testing

Vaak een aparte rol in software-teams:

  • Software Tester
  • Test Engineer
  • QA Engineer
  • Test Automation Engineer
  • ...

 

Los daarvan is testen een groot onderdeel van het werk van elke developer.

Warm-up exercise 1

  • Maak een nieuw bestand sum.js
  • Schrijf een functie sum die 2 argumenten accepteert en de som van deze 2 getallen teruggeeft
  • Roep de functie op met 2 zelfgekozen getallen en log het resultaat in de console
  • Voer de code uit en verifieer of alles werkt zoals verwacht

Warm-up exercise 2

  • Maak een nieuw bestand sum-of-array.js
  • Schrijf een functie sumOfArray die een array van getallen accepteert als argument en de som van alle getallen in die array teruggeeft
  • Roep de functie op met een zelfgekozen array en log het resultaat in de console
  • Voer de code uit en verifieer of alles werkt zoals verwacht

Software testing

Validatie vs verificatie

Validatie vs verificatie

  • Validatie
    • Vergelijken t.o.v. business requirements
      • Think: clients, profit, turnover, regulations ...
      • What should we achieve?
    • Are we building the right thing?
       
  • Verification
    • Vergelijken t.o.v. functional requirements
      • Think: features, designs, specifications ...
      • How do we achieve it?
    • Are we building it right?
  • Business requirements (validatie)
    • Omdat ik nu volwassen ben, moet ik verantwoordelijkheid nemen voor mijn eigen gedrag, zonder dat anderen mij moeten vertellen wat ik moet doen en hoe/waar/wanneer ik het moet doen.

 

  • Functional requirements (verification)
    • Oefening: schrijf zelf potentiële functionele requirements op

Validatie vs verificatie

  • Business requirements (validatie)
    • Omdat ik nu volwassen ben, moet ik verantwoordelijkheid nemen voor mijn eigen gedrag, zonder dat anderen mij moeten vertellen wat ik moet doen en hoe/waar/wanneer ik het moet doen.
       
  • Functional requirements (verificatie)
    • Create a web application to keep track of all my tasks
    • I should be able to:
      • Log in using my e-mail address and password
      • When logged in:
        • Create, update, remove and view tasks
        • Create, update, remove and view categories
        • Add a date to a task
      • ...

Validatie vs verificatie

  • Business requirements (validatie)
    • Door nieuwe Europese regelgeving, zijn we wettelijk verplicht om het klanten mogelijk te maken elk kwartaal een overzicht te bekijken van hun investeringsportefeuille inclusief alle transacties, de huidige staat van hun investering en alle kosten, onderverdeeld per kosttype.
       
  • Functional requirements (verificatie)
    • Oefening: schrijf zelf potentiële functionele requirements op

Validatie vs verificatie

  • Business requirements (validatie)
    • Door nieuwe Europese regelgeving, zijn we wettelijk verplicht om het klanten mogelijk te maken elk kwartaal een overzicht te bekijken van hun investeringsportefeuille inclusief alle transacties, de huidige staat van hun investering en alle kosten, onderverdeeld per kosttype.
  • Functional requirements (verificatie)
    • Automatically create a letter in PDF format for every client in the system
    • PDF should be sent by mail on the 1st day of every quarter, relating to the quarter before
      • Clients without e-mail address should get a physical copy of the letter at their registered physical address
    • PDF should be available on our platform under 'Document center'
    • PDF should adhere to the design in Figma, including header with logo, footer, page numbering
    • ...

Validatie vs verificatie

  • Validatie
    • Acceptance testing
    • Vaak in een aparte omgeving (acceptance)
    • Verantwoordelijkheid van eindgebruikers of hun vertegenwoordigers
      • Tester, product owner, business analist ...
         
  • Verificatie
    • Functional testing
    • Vaak in een aparte omgeving (development) en op je lokale machine
    • Verantwoordelijkheid van developers of mensen waarmee ze nauw samenwerken
      • Tester, developer uit hetzelfde team, functioneel analist ...
         

Validatie vs verificatie

  • Vaak is de scheiding tussen business requirements en
    functionele requirements niet strikt aanwezig
     
  • Daarom: implementeer niet zomaar wat je wordt opgedragen
    • Luister goed
    • Stel vragen
    • Bezint eer ge begint
    • Denk na over de impact op de gehele organisatie
    • Wees kritisch, zonder negatief te zijn
    • Bied alternatieven aan

Validatie vs verificatie

Andere vormen van testing

  • Security testing
  • Performance testing
  • Recovery testing
  • ...

 

Dit zijn ook voorbeelden van non-functional testing 
omdat ze geen betrekking hebben op de functionele requirements.

Software testing

Unit testing

Unit testing

A unit test is a block of code that verifies the accuracy of a smaller, isolated block of application code.

 

  • Unit testing is een vorm van verificatie
    • Function
    • Method
    • Component
    • API endpoint
    • ...

Unit testing

  • Verantwoordelijkheid van de developer
    • Uitvoering is doorgaans geautomatiseerd
    • Wanneer schrijven?
      • Vóór implementatie (test-driven development, TDD)
      • Na implementatie
    • Wanneer uitvoeren?
      • Voor pushen naar feature branch
      • Vóór merge naar main
      • Vóór merge naar develop
      • ...

Unit testing

  • Waarom doen?
    • Bugs in productie = negatieve business impact
    • Vorm van documentatie
    • Bug sneller ontdekken = lagere kost om te fixen
       
  • Hoe schrijven?
    • Test framework bv. Jest
    • Arrange - Act - Assert
      • Alternatief: Given - When - Then

Arrange - Act - Assert

describe('multiply', () => {
  it('should return the two numbers multiplied by each other', () => {
    // Arrange
    const number1 = 5;
    const number2 = 10;
    
    // Act
    const multiplication = multiply(number1, number2);
    
    // Assert
    expect(multiplication).toBe(50);
  });
});

Arrange - Act - Assert

describe('multiply', () => {
  it('should return the two numbers multiplied by each other', () => {
    // Arrange & Act gebeuren hier impliciet
    expect(multiply(5, 10)).toBe(50);
  });
});
  • In eenvoudige scenario's kan je stappen combineren

Describe - it

describe('mathematics', () => {
  describe('subtraction', () => {
    it('should return the second number subtracted by the first', () => {
      expect(subtract(10, 3)).toBe(7);
  	});
  });
  
  describe('multiply', () => {
    test('returns the two numbers multiplied by each other', () => {
      expect(multiply(5, 10)).toBe(50);
  	});
  });
});
  • describe gebruik je om tests te groeperen
    • kan oneindig vaak genest worden
  • de effectieve tests roep je steeds aan met it
    • bij voorkeur begint het eerste argument (beschrijving) met should
  • Een alternatieve syntax is test in plaats van it

Software testing

Unit testing met Jest

 

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.

Designed to ensure correctness of any JavaScript codebase. It allows you to write tests with an approachable, familiar and feature-rich API that gives you results quickly.

Installatie

npm install jest --save-dev

⚠️ ES modules & Jest

  • Jest ondersteunt ES modules niet volledig
  • In package.json
    • Verander het test script
    • Voeg "type": "module"  toe
{
  // ...
  "scripts": {
      // Windows
      "test": "set NODE_OPTIONS=--experimental-vm-modules && npx jest",
      // Mac or Linux -> Change 'set' to 'export'
  },
  "type": "module",
  // ...
}

Tests schrijven: oefening 1

  • Schrijf een unit test voor de functie uit warm-up exercise 1
    (zie slide 2-2 uit deze les)
    • Maak een nieuwe file: sum.test.js
    • Importeer de functie uit sum.js
    • Gebruik describe en it / test om test(s) op te stellen
       

Tests schrijven: oefening 2

  • Schrijf een unit test voor de functie uit warm-up exercise 2
    (zie slide 2-3 uit deze les)
    • Maak een nieuwe file: sumOfArray.test.js
    • Importeer de functie uit sum.js
    • Gebruik describe en it / test om test(s) op te stellen
       

VS Code extension: Jest

VS Code extension: Jest

  • Uitbreiding op VS Code interface om tests te runnen
    • Meerdere tests (describe)
    • Enkele test (it / test)

 

 

Tests schrijven: oefening 3

  • Schrijf in een aparte file een functie passed die een getal als argument heeft
    • Als het getal < 10: geef de string "Gebuisd" terug
    • Als het getal >= 10: geef de string "Geslaagd" terug
    • Als het getal < 0 of > 20 of het is geen (geheel) getal :
      gooi een error met een gepaste boodschap
  • Schrijf unit tests voor deze functie

Tests schrijven: oefening 4

  • Schrijf in een aparte file een functie olderThan die 2 argumenten heeft:
    • Een array van objecten met property name (string)
      en age (number)
    • minimumAge (number)
  • Deze functie moet een array van namen terug geven, voor wie de leeftijd
    groter is dan of gelijk aan minimumAge
  • Schrijf unit tests voor deze functie
// Given following input
const persons = [
  {name: 'John', age: 27},
  {name: 'Jane', age: 31},
  {name: 'Joe', age: 41},
  {name: 'Janet', age: 19}
];

const result = olderThan(persons, 30);
// ['Jane', 'Joe']

Software testing

(Chrome) DevTools

Chrome DevTools

Chrome DevTools

  • Simulating a mobile device
  • Editing CSS
  • Inspecting network requests
  • Throttling network speed
  • Run Javascript against the current page
  • Testing page performance
  • ...

(Chrome) DevTools

  • Firefox, Safari, Edge have their own similar version
  • For uniformity, we'll use Chrome
    • Step 1: Download and install Google Chrome

Elements

  • Inspect all HTML and CSS
    • Show computed properties
  • Manipulate HTML and CSS
    • Force element state
  • Oefening: 
    • wijzig de beschrijving van je eerste taak
    • wijzig de achtergrondkleur van body naar grijs
    • verwijder een taak op de homepagina

Console

  • View client-side logs, warnings and errors
  • Run any valid Javascript
    • Against the open page
  • $: shorthand for document.querySelector
    • Oefening: wijzig de beschrijving van je eerste taak door in de console Javascript uit te voeren (tip: innerText)

Network

  • List of network requests
    • Tip: add "Method" column
    • Click on a request to see the details
      • Headers: request + response headers
      • Payload: request body
      • Preview: response body
    • Filter
    • Clear

Network

  • List of network requests

Network

  • List of network requests
    • Oefening:
      • In Make IT Happen, voeg een nieuwe taak toe
      • Bekijk de payload die je naar de API stuurde. Bekijk ook wat de respons is.
      • Doe hetzelfde voor het verwijderen van een taak.

Network

  • Override content
    • Onderschatte feature bij werken met APIs
    • Test API contract
      • "Als ik endpoint X aanroep, welke respons verwacht ik?"
    • Mock responses worden lokaal opgeslaan 
      • 1e keer: Chrome vraagt waar ze op te slaan
      • Vergeet ze niet te verwijderen!
    • Refresh pagina (CTRL + R) na bewerken

Network

Network

  • Override content
    • Oefening: in Make IT Happen, pas de response op de GET /categories aan zodat er meer dan 20 categorieën zijn. Ziet je pagina er nog steeds uit zoals verwacht?

Network

  • Snelheid van network requests throttlen

Network

  • Snelheid van network requests throttlen
    • Oefening:
      • Test Make IT Happen alsof je zou werken met een smartphone met 3G-connectie

Software testing

Performance testing - Web Vitals

(Core) Web Vitals

  • Initiative led by Google
  • Goal: define metrics which have a significant impact on the customer experience of a website
    • The most important metrics are named Core Web Vitals
  • https://web.dev/articles/vitals

Largest Contentful Paint

  • Largest Contentful Paint (LCP)
    • represents how quickly the main content is loaded
    • time from initial load until largest image or text block
      is loaded

First Input Delay

  • First Input Delay (FID)
    • represents how smooth the interaction is
      • inputs, dropdowns, links ...
    • time from first interactions to start of processing
      • is the main thread blocked?

Cumulative Layout Shift

  • Cumulative Layout Shift (CLS)

(Core) Web Vitals

  • Hoe testen?
    • Chrome DevTools - tab Performance
  • Oefening:
    • Meet de Core Web Vitals voor jouw applicatie
    • Bedenk wat redenen zijn voor eventuele slechte scores ("Needs improvement" of "Poor")

Software testing

Werkcollege - unit testing

Tests schrijven: oefening 5

  • In Make IT Happen, identificeer een functie die je zou kunnen testen. Dit is bij voorkeur een functie die een bepaalde waarde terug geeft.
    • Als je niets kan identificeren, denk dan na over hoe je een deel van een functie zou kunnen onderbrengen in een aparte functie die iets terug geeft als input voor die grotere functie.
  • Schrijf in pseudo code hoe je dit gaat testen
    • Arrange: testdata aanmaken
    • Act: functie aanroepen met de testdata
    • Assert: verifiëren dat de functie teruggeeft wat je verwacht
  • Zet de pseudo code om in echte code

Tests schrijven: oefening 5

function displayCategoryOption(categories, $categorySelect) {
  $categorySelect.insertAdjacentHTML(
    "beforeend",
    mapCategoriesToOptionsHtml(categories)
    // Replaced below with mapCategoriesToOptionsHtml to make it testable:
    // 
    // categories
    //  .map((category) => {
    //    return `
    //    <option value=${category.id}>${category.name}</option>
    //    `;
    //  })
    //  .join("")
  );
}

function mapCategoriesToOptionsHtml(categories) {
  return categories
    .map((category) => {
      return `
      <option value=${category.id}>${category.name}</option>
      `;
    })
    .join("");
}

Tests schrijven: oefening 5

describe("mapCategoriesToOptionsHtml", () => {
  it('should map an array of categories to corresponding <option> elements', () => {
    const categories = [
      { id: 1, name: "Huishouden" },
      { id: 2, name: "Hobbies" },
      { id: 3, name: "School" }
    ];
    
    const optionsAsHtml = mapCategoriesToOptionsHtml(categories);
    
    expect(optionsAsHtml).toBe(`
		<option value="1">Huishouden</option>
		<option value="2">Hobbies</option>
		<option value="3">School</option>
	`);
  });
});

PGM3/7 - Software Testing

By kareldesmet

PGM3/7 - Software Testing

  • 47