Category Archives: Retelling

DRY or Don’t Repeat Yourself – part 2

One evening I had a wrap on my plate. Then I took a modest amount of vegetarian filling. My wife noticed this:
“No wonder you can eat three wraps.”

Refactoring

My wife improved my meal with this single remark. The more filling, the better. Lucky for me, she did it, before I would eat my wrap. These small things add up.

In software development improving the code is called refactoring. The first step is to notice something wrong, which is followed by using the right solution.

Let’s go back to the wraps. My wife saw, that I did not put enough filling on my wrap. Then her solution was more filling.

Refactoring in practice

After hours of programming, I had a test scenario for the Cinema VIP app, where the number of Colas was increased because of the Desert scene in Monsters Unlimited.

Some steps from the scenario were:

  • order 1 Cola in the Drink and Snack page,
  • go to the next page,
  • regret my choice, (I did not code this, but it adds to the flavor.)
  • go back to the Drink and Snack page,
  • change the number of Colas to 2 in the Drink and Snack page, and
  • go to the next page.

Changing lines

A note for the screen reader users: characters like parentheses, dot, and braces are used in the code. It is advised to change the interpunction and symbol level before reading the code.

Then it was time for me to have a close look to the code. The line of code to find the text field with the number of Colas was used twice. First I set it to 2 and later to 1. Every time the Snack and Drink page was opened, the text field must be found again.

In my code I found the following line twice.

WebElement numberOfColasTextfieldSnackAndDrinkPage = 
  driver.findElement(
    By.name(“4958495”);

This means: find the text field with the name 4958495.

I had to change this, so I added the following line:

public static final String NUMBER_OF_COLAS_TEXT_FIELD =
  “4958495”;

This means: NUMBER_OF_COLAS_TEXT_FIELD is 4958495.

Then I changed both lines to find the text field.

WebElement numberOfColasTextfieldSnackAndDrinkPage = 
  driver.findElement(
    By.name(NUMBER_OF_COLAS_TEXT_FIELD);

This means: find the text field with the name NUMBER_OF_COLAS_TEXT_FIELD.

I had severe doubts about NUMBER_OF_COLAS_TEXT_FIELD. In my test scenario several windows were used. There was only 1 Number of Colas Text Field in the whole application. On the other hand every page had an OK button. Using OK_BUTTON is an accident to happen.

So I changed OK_BUTTON in the Drink and Snack Page to OK_BUTTON_DRINK_AND_SNACK_PAGE. So I used
NUMBER_OF_COLAS_TEXT_FIELD_DRINK_AND_SNACK_PAGE.

In this case I used refactoring to make sure, that my test automation would still work. I like code which is easy to read and change.

Time for some reflection

I noticed the recurring lines of code. This would lead to code which would be difficult to maintain. I remembered DRY or Don’t Repeat Yourself.

My solution was to use a single line of code to determine the name of the Number of Colas Text Field. If the name would change, then I had only to change this line of code.

Page Object Model

A few weeks later I had 3 scenarios with the Drink and Snack Page containing the same lines:

numberOfColasTextfieldSnackAndDrinkPage.sendKeys("1");
numberOfPotatoChipsfieldSnackAndDrinkPage.sendKeys("1");
oKButtonDrinkAndSnackPage.click();

This means:

  • order 1 Cola
  • order 1 potato chips
  • press the OK button.

These same lines of code in 3 different test scenarios did not feel quite right to me. Repeat after me: Don’t Repeat Yourself. There was still too much repetition.

I already used objects for the web elements. Then a tester introduced me to the Page Object Model. I looked at her code and saw less lines of code to do similar things.
“Why did you tell me this before?”
“First you have to get comfortable with the normal way of coding.”
She got a point.

The Page Object Model or POM makes objects for complete pages. So the Drink and Snack page was an object.

My test scenario contained the following actions:

  • select the movie in the Movie Page.
  • select the drink and snack in the Drink and Snack Page.
  • confirm the made options in the Confirm Order Page.

The first 2 steps I programmed as follows:

MoviePage moviePage = homepage.selectMovie();
DrinkAndSnackPage drinkAndSnackPage =
  moviePage.confirmMovie("Monsters Unlimited");
ConfirmOrderPage confirmOrderPage = 
  drinkAndSnackPage.selectColaAndPotatoChips();

This code was more readable than all those detailed lines of code. This also saved me a lot of space.

I put all the code for the web elements of the Drink and Snack Page in the following method:

public ConfirmOrderPage selectColaAndPotatoChips();
{ 
  WebElement numberOfColasTextfield = 
    driver.findElement(
      By.name(NUMBER_OF_COLA_TEXT_FIELD);
  WebElement numberOfPotatoChipsTextfield = 
    driver.findElement(
      By.name(NUMBER_OF_POTATO_CHIPS_TEXT_FIELD);
  WebElement okButton = 
    driver.findElement(
      By.name(OK_BUTTON);
  
  numberOfColasTextfieldSnackAndDrinkPage.sendKeys("1");
  numberOfPotatoChipsfieldSnackAndDrinkPage.sendKeys("1");
  oKButtonDrinkAndSnackPage.click();
  
  return ConfirmOrderPage(driver);
}

In the meantime I could not resist another refactoring. I put all the code for the Snack and Drink Page in one Java file. So all mentioned web elements in this file are on this page. So I renamed NUMBER_OF_COLAS_TEXT_FIELD_DRINK_AND_SNACK_PAGE to
NUMBER_OF_COLA_TEXT_FIELD.

Cliffhanger coming up

At the end I used DRY or Don’t Repeat Yourself. Less copied lines meant less problems. It was time to hit the wall again.

To be continued.

DRY or Don’t Repeat Yourself in test automation – part 1

This month my wife thought that it would be a great idea to make wraps. She looked on the internet and found a good recipe.

The case of 3 recipes

Do you have a copy for me?

Suppose one of my kids would like to make wraps at a friend’s place. The kid copies the recipe for the wrap and the vegetarian wrap filling. Some weeks later I have to make wraps with minced meat filling. So I copy the recipe for the wrap and the wrap filling.

At that moment there are 3 recipes in use. There is no problem, because the wraps are still tasty.

Any updates?

Now imagine the following situation.
One evening I get a call from one of my kids.
“What is the bottle in the third row and second column?”
I open the drawer and pick the bottle.
“It is the sunflower oil.”
“Thanks, dad. Now I can continue with the wraps.”
“Wait, did I not use the right one?”
“Mom told my friend and she wrote down the change.”
“Then you already know, that mom adds an extra spoon of oil.”
“Wait. What did you say, dad?”

Don’t Repeat Yourself

The more copies you make, the more things you have to watch. Especially, if things change. Now I could assign a task to myself to update all the 3 recipes all the time. That sounds to me as a part time job. I would rather spend that time on cooking.

In software development DRY or Don’t Repeat Yourself is used to avoid these kinds of mistakes. The more code I copy, the more I need to update in case of a change. This is part of my job. It would be great, if I could reduce these changes to a minimum.

Change the right field

In the following story the companies and products have been obfuscated.

After a few weeks of coding, I had test automation in place for the VIP Cinema App. In most scenarios the order page for the drink and snack was used.

In one test scenario I would order a drink and snack and go to the next page. Then I would go one page back and change my order. The desert scene in Monsters Unlimited is so good, that people get thirsty. I definitely needed 2 drinks.

A note for the screen reader users: parentheses, at symbol, dot, and double quote are used in the code. It is advised to change the interpunction and symbol level before reading the code.

Don’t Repeat Yourself or DRY in practice

Now I had several lines in my code to change the number of Colas on the drink and snack page. The first line of Java code looked like

WebElement NumberOfColasTextfieldSnackAndDrinkPage = 
  driver.findElement(
    By.name(“4958495”);

This means: find the text field with the name 4958495.

The second line of Java code was:

NumberOfColasTextfieldSnackAndDrinkPage.sendKeys("1");

This means: enter “1” in the Number of Colas in the text field on the Snack and Drink Page.

The third line of Java code was:

NumberOfColasTextfieldSnackAndDrinkPage.sendKeys("2");

This means: enter “2” in the Number of Colas in the text field on the Snack and Drink Page.

DRY in more details

For my code I used Java. This is an object-oriented programming language. The Number of Colas text field in the Snack and Drink Page is an object, which I used for test automation.

A test scenario would only contain the following code once:

WebElement NumberOfColasTextfieldSnackAndDrinkPage = 
  driver.findElement(By.name(“4958495”);

The code to make this text field was written once instead of twice. I did not repeat myself. In this particular DRY or Don’t Repeat Yourself was not applicable.

Ready for the change

For me and other people 4958495 is not related to a Number of Colas text field. It makes the code hard to read.

I assumed, that the development environment had assigned a random number to each web element. Luckily it was a unique number, so my text automation code would work at that moment.

If a developer would change something in the Snack and Drink Page, then the random number or change might also change. this would result in broken test automation code. That is the bad part of my job.

The best way to identify the text field was to use id. id is short for identity. id is an attribute of the web element, which is used to identify it.

I talked to another tester, who agreed with me. The programmer should change the code for the text field. In turn I would have to change my test automation code:

WebElement NumberOfColasTextfieldSnackAndDrinkPage =
 driver.findElement(By.xpath(contains(@id, “NumberOfColasTextField”));

If the name would change to some other random number, the id would be the same.

A cliffhanger at your request

The code with the name attribute looked good enough for me, but there was still too much repetition.

To be continued.

Advanced blogging – The Usual Rushed Texts

The first time I noticed the speed of the screen reader of a blind person I was overwhelmed. I barely could catch each word. The speed was at least twice the speaking speed of a person.

Imagine a friend who excitedly talks about a great job offer.
It sounds like a rushed text.

“Are you a member of the Guild?”
“Last time I checked.”

Show me the code

The default editor in WordPress is the visual editor. For beginners this is a great way to begin. The text is shown in the same way the visitors will read it. There is a catch. Sometimes the editor will change the look and feel.

For me the visual editor in WordPress hided too much information, so I used the code editor. I was editing HTML files and checked the changes in the visual editor.

For fast writing, HTML provides a nice structure: headings. I just put some keywords or short sentences in the file. Jerry Weinberg called them fieldstones. I kept the rest of the words in my mind and added them later on.

Let me show and tell

I always thought that it was a good idea to show what I did. Pictures can clarify a lot. A lot of pictures can clarify a lot more.

in the visual editor the picture had a bad contrast. I thought that I shrunk the picture too much. The picture looked good in the preview mode.

No alternative text

If I did not use an alternative text, then the screen reader would read the following aloud:
“Just to be sure I turned off the highlighting.
https://mindfultester.com/wp-content/uploads/2021/01/mindful-tester-p3-1.20-no-highlightingboxes.jpg”

In this case NVDA, a screen reader, used the path and file name instead of the empty alternative text.

“This is not according to the code of the Guild.”

Non descriptive alternative text

If I did use a short alternative text, then the screen reader would read the following aloud:
“Just to be sure I turned off the highlighting.
Dialog without highlighting”

This sounds like a rushed text. In the picture there are more details worth mentioning.

“This is not part of the deal.”

A complete alternative text

In my blog post I used a descriptive alternative text, then the screen reader would read the following aloud:
“Just to be sure I turned off the highlighting.
In the left image or baseline “Cap” in the username is shown, in the right image or checkpoint the username is empty. In the right upper corner, there is a thumb down button.”

“This is the way.”

Summary

Let me break down the structure. First, I wrote a text with a short introduction to the picture. Then the alternative text was a detailed description of the picture. A screen reader user would hear a normal story. This way I told a story with normal texts and alternative texts in a natural flow.

For the third blog post about Visual TDD in Test Automation I had a separate file for alternative texts. This was handy for the consistency of the text. But I disliked the continuously switching of files: open WordPress, go to the location of the picture, open the editor with the alternative texts, copy the desired text, and paste the text at the right spot in WordPress.

So I put all my alternative texts into the HTML file. This saved me some application switching. It might have some impact on the consistency of the alternative texts.

Even worse, I needed to do some spell checking.

I have a spell on you

The problem with blogging is that the mind is faster than the hands. This often leads to spelling and punctuation errors.

For the creative mind, speed is essential. I could lose my train of thoughts. This is why I gladly accept any typos.
It sounds like a rushed text.

WordPress uses the browser spell check. This is focused on the right spelling of the words. The syntax of the sentences is ignored.

If I spell check my blog post, then I go to the visual editor. I copy the text into my favourite word processor and start the spell checking. Because I was worried about the layout, I change the text in both WordPress and the text editor.

Fine, but what about the alternative text?
A simple solution is:

  • go to the picture
  • copy the alternative text
  • paste in your favourite word pressor
  • do a spell check

There is one place where all the alternative texts are shown and that is the HTML file. The code editor shows all the lines including the alternative texts, which are not shown in the visual editor.

Simple solution

My advice would be: search for alt in the html file and copy the stuff.

Difficult solution

For the selection of my alternative texts, I chose a complicated solution.
This paragraph is meant for people with an IT background. You are free to skip this.

If you are using a screen reader, please set the interpunction level to all.

I opened baregrep, a shareware tool which can filter lines of codes with the text “alt”. This basically means: give me all the lines with alternative texts. I was lucky that I did not use words like alternative or salt.

Baregrep shows all the lines of the files with the file name ending with "v1t.txt" in the subdirectory D:\Users\Han Toan\Mijn documenten\Blog\2020 Blog containing the text alt!

I copied the output.

The Export Test Results Dialog has a To Clipboard button!

The next step is to use VIM, a free software program with a typical interface. I pasted the text in my word processor.

VIM shows the pasted lines of the test results!

The file contained one picture with an alternative text on a different line.

:%s/^.*alt="//
  • : means, that I wanted to execute an ed command. ed is an editor command.
  • % is for all lines in the file
  • s is short for substitute.
  • /^.*alt="/ is the pattern, which I looked for between / and /.
    • ^ is from the beginning of the line.
    • .* is zero or more arbitrary characters.
    • alt=" is the literal text “alt=””
  • // is the text between / and /, which must be used for the replacement. In this case this is an empty string.

The whole command removed all the text from the beginning of the line until and including “alt=”in every line.


:%s/".*//

  • : means, that I wanted to execute an ed command. ed is an editor command. What I basically write, is “ed, I am talking to you. The following command is for you.”
    It is like a home assistant: “VIP Home app, I am talking to you. The following command is for you.”
  • % is for all lines in the file
  • s is short for substitute.
  • /".*/ is the pattern, which I looked for between / and /.
    • " is the literal text “.
    • .* is zero or more arbitrary characters.
  • // is the text between / and /, which must be used for the replacement. In this case this is an empty string.

The whole command removed all the text from ” until the end of the line in every line.

The last step is to copy the lines into the word processor for the final spell checking.

For the people who like to quit VIM without saving:
:q!

  • : means, that I wanted to execute an ed command. ed is an editor command. What I basically write, is “ed, I am talking to you. The following command is for you.”
    It is like a home assistant: “VIP Home app, I am talking to you. The following command is for you.”
  • q is quit.
  • ! means without saving, because I am sure.

Back to Media for the change

Then I updated the alternative texts in Media, where all my pictures are stored.
If you are using a screen reader, you can set the interpunction level to your favourite setting.

Here is the change

A few days later I noticed that the wrong alternative texts were included in the blog post. I tried to figure out what happened.
Who was the usual suspect?

The moment I inserted a picture from the Media in my blog post, a copy of the HTML code was used. Any later changes in Media remained there. So I had to change the text again in the code editor.

One of my kids summarised my story as follows:
if you send your homework to school, then you send a copy of the file.

I could have chosen to replace the old pictures in the blog post with the latest pictures in Media. I was afraid to add the wrong picture. Then I should not forget the resizing.

So I edited the alternative texts in the visual editor.

Listen carefully. I only tell this once.

Pro tip: use the screenreader to read your text aloud. Some typos are difficult to see, but are easy to hear.
Just hover with your mouse over the text and hear it.

“I have spoken.”