Category Archives: Retelling

Minimal Viable Authentication: usability versus security

Trigger warning: stalking.

For the following stories I am using the imaginary VIP Cinema again instead of the real app. This way I can freely write about my experiences without naming the actual app.

Usability is king

The VIP Cinema app offered his clients a discount for parking. This service appealed to me. So, I contacted the customer service and got a power of attorney number. On request I had to mention the number to get my promised discount of 50 percent on parking.

After a while I wanted to reserve my parking without calling the customer service. There was a simple solution: a parking app. I installed the app and had to register. The first thing I did, was to have my power of attorney number ready.

The next step was to enter my email address and a password. Then I had to verify it by clicking on a link in an email. A dialog asked for my membership number of the Cinema VIP App. Then I opened the app and found the number.

I received an email to verify my email address for the parking app. After clicking a link, I had to enter my VIP Cinema membership number. The next moment I could reserve a parking place for my car without entering my power of attorney number.

The registration was smoothless and it saved me an extra step of entering another number. I really liked this experience.

Security is pauper

”I want to show something to you.”, I told another computer software professional.
“Here is my mobile. The Cinema VIP app is open and shows my membership number.”
I got a nod.

“Now I am going to the website to register a new user id and password for the parking website.”
Another nod followed.

This looks familiar

Then I entered a new email address and password. After clicking the link in the mail to verify my email address I asked him for my membership number. While he was citing the number, I entered it in the requested text field in the dialog,

 “Let us see what kind of information we can get based on this single number.
You can see where I live. This information is needed for billing.“

Worth noting

“Let’s have a look at my parking history. This is the parking I used every other week. This is an interesting pattern. Last week I parked there. So next Friday I will probably park the car there at 7 pm.”

Let me guess

“There is a high chance, that I visit a cinema close to this parking. The discount is offered by the Cinema VIP app. Notice that no power of attorney number was asked. This would improve the security.”

All that being said

“Even worse: I did not get an email that another account was coupled to my parking account. I refreshed my inbox: no mail was found about the double registration.

Certain social media apps inform me directly, if my account is accessed from an unknown device. But this was not the case for this app.”

This time I did not get a nod, but an astonished face.

Signals of poverty

When I phoned the customer service of the parking service, no power of attorney number was requested.

During this phone call there was a check of my birthday, my zip code, and my house number. These can be obtained using social engineering or extracting private information without getting attention.

This I Learned

Authentication is about making sure that the right person gets access. Some shortcuts can have severe drawbacks.

Return of The Script

The last years Exploratory Testing has gained a lot of followers. In the world of Agile development fast feedback by testers is really welcome.

There are people who have doubts about the structure and knowledge transfer, because there is no script. For an experienced tester, a note about a data life cycle test is enough. Writing out tests for creating, reading, updating, and deleting data is boring for me.

Exploratory is about finding information and using it during the same activity. This can be achieved with a script. Let me tell you some Exploratory stories.

Exploring while scripting

The search

Laptops are light and small compared to desktop computers. On the other hand, for the same price I get more RAM and hard disk space in a desktop computer.

SSD or Solid State Disk is a hard disk, which is used frequently in computers. I needed an extra hard disk for my data. The challenge was to prevent my SSD from overflowing of data.

I opened a text editor and noted all kinds of information. My SSD was my default drive to store my information. I had to redirect all data to my HDD or Hard Disk Drive.

In the past I had changed this in the Windows registry, but I did not like this. It could lead to errors. I preferred to change the direction of the data using a command or a dialog.

Like a lot of programmers, I searched on the web. I found some articles and blog posts. In the meantime, I was copying links and making notes how to reproduce the steps.

The script

The first time I executed the script, I was about to copy all the steps in my notes. This is a waste of time, so I just added my observations in the script.

For personal reasons I changed the script on a few places.

network cable out
[current PC] copy all files in Kid on external hard disk
check on Appdata 08:25
[current PC] make a copy of the mail program and game subdirectory in the subdirectories of Appdata of Kid.
08:56
[current PC] remove all stuff from the mail program (after check?)
09:30
network cable in

Network cable out of new PC
[new PC] check %APPdata%
mklink does not work properly.

environment variables => no appdata found/
[New PC] old files app data
[New PC] copy all mail program and game program subdirectories to app data.
[New PC] make extra copy of files
[open Thunderbird] remove all files.

Network cable in new PC
check game
check mail program
network cable out of new PC

In case of problems:
- restore old files of mail program and game.

The details

There are some parts which need some explanation.

network cable out

So long the current PC is connected to the internet, the mails will be downloaded all the time. During the move of the files  of the mail program I might miss emails.


[current PC] copy all files in Kid on external hard disk
check on Appdata 08:25

The reason I chose an account of one of my kids is the small amount of data, which is used by this account. This is easier to restore than the huge bulk of data on my personal account. Hoarded as charged.

Appdata is a specific place for Windows. In this subdirectory there are subdirectories for programs to store information. E.g. for a mail program the address book and the mails are stored over here.

At the end of the line, I wrote down the time of the action.


network cable in

Network cable out of new PC

During my review I noticed that this was quite confusing. I added new PC in the last line. Looking at my script, the problem of downloading mail on my current PC was back. I remember that I left the network cable out.


[new PC] check %APPdata%
mklink does not work properly.

environment variables => no appdata found/

There was a step missing in this script.  The precise use of mklink was not included.  I had used this command and described the following steps in this script. However there is still enough information to reconstruct the process.

Here things go wrong, because appdata could not be found., I did not note the time, but the message is clear.


[New PC] old files app data

This is short for copy files from the old PC to on the HDD on the new PC.


check game
check mail program
network cable out of new PC

The most important thing of changing stuff is testing whether this went right.


In case of problems:
- restore old files of mail program and game.

This was my contingency plan.


While blogging I noticed that the other files to be copied were not mentioned. I forgot to include this step. Probably this was  too obvious at that time.


Debriefing or telling, what I did, is a way to discover what went wrong.


Who said: “You cannot change the script”?

Exploring while debugging

The command mklink was not the proper solution for my problem. I removed the created account and all files. This time I switched my search results to video.

After a while I got a script to make the proper redirection: when I saved the files, then they would be saved on my HDD. My first steps went right and then nothing happened. It did not work.

Time for my clean up again: remove the created account and all files. Then I could start in a clean environment.

There was a bug or error in my script which I had to remove. But what went wrong?

I opened the video to the browser and watched it again. All the time my thoughts were like “Yeah, it is in my script”. Imagine me nodding all the time.

Then something was mentioned in the voice over: I had to wait. Imagine me saying: “Oh”.

I only watched the first part of the video and stopped. I assumed that the change in my configuration would be immediate. Computers are fast. In this particular case the change took seconds.

The next time I repeated the steps in my script. I waited long enough at the crucial step. Then my files were saved on the HDD instead of the SSD.

You should always listen to the end of the message.

Exploring while planning

Years ago, I was a test coordinator for several projects. Several components would be changed and the question was: can you test whether everything went right?

I had serious doubts about the number of actions and their consequences. My goal was to explore the deployment. Less surprises means less tests.

It took me little effort to convince the project manager to have a meeting about the deployment plan. I volunteered for the chairman. Some of the questions about this meeting are answered in thhee Q&A.

You do need think about the implications of the things you create.
– Jemma Simmons

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

My wife has a good recipe for wraps.

Imagine a situation, that I want to tweak the recipe. Last evening I ate a wonderful wrap and asked about the ingredients. At home I start to change the recipe.

What am I thinking?
“Let me see. 2 spoons of sunflower oil must be replaced by 1 spoon of sunflower oil and 1 spoon of olive oil.

I use a marker to hide the 2. Now I write 1 above the square. Writing “and 1 spoon of “. It was special kind of olive oil. I need to look this up.

First, I have to add new spices. Let me remove the old ones with my marker. The new spices are chili powder and something else.

Time to look things up on the computer.” I leave the kitchen.

Then my wife enters the kitchen to make wraps for dinner:
“What happened with my wrap recipe?”

You run a tight ship.
– Glenn Talbot

Refactoring too early

In this case I used DRY or Don’t Repeat Yourself. There is no need to have several copies of the same recipe, because the new recipe was much better than the old one. Making copies is not my favourite way to spend my time.

In this situation the improvement came too early. There was no proper recipe to make wraps for my wife.

My job is to test stuff. Refactoring is a way to clean up my code. There is a risk, that I clean up my code too early.

Groundhog Day testing

The big advantage of test automation is that the computer does the boring stuff. It can repeat steps without reducing the quality of the tests. A human being is likely to lose concentration over time.

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.

For my VIP Cinema app, I had written the following method to select a drink and a snack:

public ConfirmOrderPage selectColaAndPotatoChips();
{ 
  WebElement numberOfColasTextfield = 
    driver.findElement(
      By.name(NUMBER_OF_COLAS_TEXT_FIELD);
  WebElement numberOfPotatoeChipsTextfield = 
    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);
}

This means:

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

Now I need a piece of code for ordering 2 Colas like:

public ConfirmOrderPage selectTwoColasAndPotatoChips();
{ 
  WebElement numberOfColasTextfield = 
    driver.findElement(
      By.name(NUMBER_OF_COLAS_TEXT_FIELD);
  WebElement numberOfPotatoeChipsTextfield = 
    driver.findElement(
      By.name(NUMBER_OF_POTATO_CHIPS_TEXT_FIELD);
  WebElement okButton = 
    driver.findElement(
      By.name(OK_BUTTON);
  
  numberOfColasTextfieldSnackAndDrinkPage.sendKeys("2");
  numberOfPotatoChipsfieldSnackAndDrinkPage.sendKeys("1");
  oKButtonDrinkAndSnackPage.click();
  
  return ConfirmOrderPage(driver);
}

This piece of code looks almost the same as the previous one. A lot of repeated lines of code, so it is time for …

Refactor 1

public ConfirmOrderPage selectTwoColasAndPotatoChips();
{ 
  driver.findElement(
    By.name(NUMBER_OF_COLAS_TEXT_FIELD).sendKeys("2");
  driver.findElement(
    By.name(NUMBER_OF_POTATO_CHIPS_TEXT_FIELD).sendKeys("1");
  driver.findElement(
    By.name(OK_BUTTON).click();
  
  return ConfirmOrderPage(driver);
}

My first step was to make the code more compact. But I still repeated the lines of code for the text fields and buttons in the method selectColaAndPotatoChips, so I should use methods instead. Small reminder to myself: DRY or Don’t Repeat Yourself.

Trust the system.
– Melissa May

Refactor 2

public ConfirmOrderPage selectTwoColasAndPotatoChips();
{ 
  selectColas("2");
  selectPotatoChips("1");
  pressOKButton();
  
  return ConfirmOrderPage(driver);
}

This code looked more readable than the previous code. But I still needed some way to change the number of Colas in a simple way.

Refactor 3

public ConfirmOrderPage selectDrinksAndSnacks(int numberOfColas);
{ 
  selectColas(numberOfColas);
  selectPotatoChips(1);
  pressOKButton();
  
  return ConfirmOrderPage(driver);
}

I introduced the parameter numberOfColas, so I could use this method for the situations to select 1 Cola or 2 Colas. One parameter fits all.

Some other small things I refactored are:

  • I changed the name of the method to selectDrinksAndSnacks. This is a more general name, so I could extend to other drinks and snacks. One name fits all? I mean all interactions with the Order Drink And Snack Page.

    We’ve got to get on the same page.
    – Phil Coulson

  • I did not like that numberOfColas was a string. This could lead to programming errors. An int or integer restricted the use of the possible values. I didn’t want to wait for a tester using the word “hundred” for ordering Colas. Or the polite Spanish tester: “Una, por favor.”. This means: one, please.
  • I also changed the method selectPotatoChips to use an integer number of Potato Chips. Consistency fits all.

To explore new combinations

A way to increase sales is to offer discounts to customers. If I have a discount code for a Cola, then I get the Cola for less money. If I take an orange juice, I have no discount. Bad luck.

I talked to the developers and hoarded some discount codes. And off I coded.

public ConfirmOrderPage selectDrinksAndSnacks(int numberOfColas, int numberOfOrangeJuices);
{ 
  selectColas(numberOfColas);
  selectOrangeJuices(numberOfOrangeJuices);
  selectPotatoChips("1");
  pressOKButton();
  
  return ConfirmOrderPage(driver);
}

This was pretty easy. I just added a parameter for Orange Juices. As time passed by, I added more parameters. Then I got a request to execute the scenarios for a regression test. This was the moment that test automation would shine.

The discount scenarios could be executed except the one which I worked on. But the other scenarios could not be used, because I added parameters like numberOfOrangeJuices. This was not the moment that test automation would shine.

This is a potential volatile situation.
– Melissa May

I used DRY or Don’t Repeat Yourself too early. What I needed, was to find the proper way to use it.

Wrongs have been committed. Now we make them right.
– Jemma Simmons

I could use git, a version control system, to restore my old code. In best case I could use the scenarios and get back to my current state of coding.

There was a big If. If the scenarios were broken in some way, then I had to repair them and merge them with the current scenarios. Making things a little more complicated than I had expected. A typical worst case.

We’ll figure it out. We always do.
– Phil Coulson

In order to keep things simple for myself I repaired the broken scenarios. I was not in the mood to use git to use an older version.

In hindsight

Let me summarise the situation of coding test automation. I was doing two things at the same time:

  1. adding new test automation code.
  2. using test automation code for a regression test.

It is like a kitchen where I am trying to improve the wraps and my wife is making new ones. The problem is, that we are using the same recipe at the same time.

It is important to know when to throw out the plan.
– Phil Coulson

In this case DRY or Don’t Repeat Yourself is not the peaceful option to choose. A simple solution is, that both my wife and I use different recipes for our purposes. The copy of the recipe is really needed for a workable situation.

I can still tweak the wrap using herbs and spices. There might be a better wrap. In the meantime my wife is baking the wraps. After all I want to have dinner with wraps.

We are solving problems we created.
– Phil Coulson

Closing note

During the weeks of programming test automation I noticed, that I had made a lot of beginner errors. These things happen. My way is to learn from my mistakes.

What you do next, matters.
– Phil Coulson

DRY or Don’t Repeat Yourself is a principle. I realised, that I should not use it without thinking. As a tester I always looked to exceptions. As a coder I had experienced the same situation.

Should I remove duplicated lines of code? Or even more important, is it smart to copy the code?

Copy that.
– Mack