top of page
  • Foto van schrijverBas Dam

Regular Expressions en Testautomatisering, twee problemen of juist een oplossing?

Bijgewerkt op: 9 nov. 2023


Bij geautomatiseerde checks wil je regelmatig een verwachte waarde controleren tegen een actuele waarde. Vroeg of laat kom je dan in aanraking met wildcards: Je wilt bijvoorbeeld weten of de tekst “Er zijn 42 resultaten gevonden” voorkomt, maar het aantal, hier 42, kan variabel zijn. Van 42 wil je dan een wildcard maken.

De meest gebruikte wildcard language is de regular expression. Binnen het testautomatiseren gebruik ik graag regular expressions:

Maar eigenlijk is de belangrijkste reden:

Wat betekent dit? Je hoeft de check niet programmatisch af te handelen. Laten we kijken hoe we dit programmatisch zouden kunnen afhandelen:

public void CheckCorrectResultAmountMessage(string actualText) 
{
    // Check the start of the text
    Assert.IsTrue(actualText.StartsWith("Er zijn "));

    // Check the end of the text
    Assert.IsTrue(actualText.EndsWith(" resultaten gevonden"));

    // Grab the amount
    var amountText = actualText.Replace("Er zijn ", "").Replace(" resultaten gevonden", "");

    // Check if the amount is a valid integer
    int amount;
    Assert.IsTrue(int.TryParse(amountText, out amount), "The amount '{0}' is not a valid integer", amountText);
} 

Dat is best wel veel gedoe voor de check van 1 regel tekst en dan zijn er nog genoeg cases die niet afgedekt worden: negatieve waarden worden niet als foutief gezien, wat gebeurt er als je ‘4 2’, ‘4.2’, ‘4e2’ of ‘4,2’ terugkrijgt? (dit vereist interne kennis over de int.TryParse method). En hoe ga je dit uitbreiden naar “Er zijn geen resultaten gevonden” en “Er is 1 resultaat gevonden”?


Het onderliggende probleem is: We proberen twee problemen tegelijkertijd op te lossen: Wat we willen checken en hoe we dat doen. Een betere strategie is om dat uit elkaar te trekken.

We kunnen dit oplossen door een regular expression te gebruiken:

public void CheckCorrectResultAmountMessage(string actualText)
{
    var pattern = "^Er zijn <0-9>+ resultaten gevonden$";
    Assert.IsTrue(Regex.IsMatch(actualText, pattern));
} 

Nu kunnen de definitie (wat) en de implementatie (hoe) scheiden waarbij je het pattern op een andere plek bepaalt (in een config file, een database, Excel bestand of je testscenario) dan waar je het test. Als we dit bijvoorbeeld in een Feature file gebruiken dan bepalen we in de feature file de definitie (Wat we testen):

Scenario: There must be an amount displayed if there are results
Given I search for "ipod"
Then I can see the message "Er (zijn \d+ resultaten|is 1 resultaat) gevonden"

Scenario: A message should be shown when no results are found
Given I search for "sony walkman"
Then I can see the message "Er zijn geen resultaten gevonden" 

en in de step definitie de implementatie (Hoe we dat doen):

[Then(@"I can see the message ""(.*)""")]
public void ThenICanSeeTheMessage(string expectedMessagePattern)
{
      var msg = MyFancyWebApp.GetMessage();
      Assert.IsTrue(Regex.IsMatch(msg, expectedMessagePattern));
} 

Regular expressions is maar één gebied dat je helpt om definitie en implementatie te scheiden. Binnen applicatie development en dus ook test automatisering is Separation of Concerns een leidend principe dat je binnen een goede code basis veel terug zal zien komen. Samen met DRY (Don't Repeat Yourself) en KISS (Keep It Simple Stupid) vormt dit de basis code principes waarmee je niet alleen jezelf, maar ook je team enorm helpt.



Recente blogposts

Alles weergeven
bottom of page