FitNesse Training: 3. How to write your first test script

Computest
Testautomation Computest
9 min readNov 17, 2020
Photo by Marvin Meyer on Unsplash

Notes: This training is part of a series of 7, the complete series can be found here.
We have used FitNesse with HSAC fixtures for this training-series.

In the previous tutorial, you have learned how to set up your first project and get it up and running. In short: you have learned about the structure of FitNesse, you have created a basic project-structure and you are now ready to write your first test!

Writing your first test script step by step

In this tutorial, we want FitNesse to visit a web shop, search for a product, narrow down the results and add a product to the basket. Besides testing the flow, we also want to test if the correct product ends up in your cart and if the right price is charged.

We will show you in nine steps how this works and how you can write your first test script:

Step 1- Add your own Test Page
In the previous tutorial you have created your first Test Suite ‘Smoke Tests’. Go to this Test Suite.

Now add your own Test Page by clicking ‘Add’ and then ‘Test Page’. Let’s name this ‘WebshopTest’. Save this test. You should now be on your test page ‘Webshop Test’. Do you see the space between Webshop and Test? FitNesse automatically places a space between words starting with a capital.

Step 2- Start writing your Test
On your test page click ‘Edit’. On line 1 you should see <test page>. You can remove this. Now let’s start writing the test.

FitNesse uses pipes ( | ) to structure its code. Each part of the code starts and ends with pipes. Each block of coding has to start with a link to the kind of code you are using. There are several options. We will discuss these and their differences in a later article, but for now, start your code with:

|script|browser test|

Step 3- Tell FitNesse to go to a webshop
On the next line, we will start to tell FitNesse what to do. You can find a list of basic HSAC-commands here. We have already set up our project so that the browser itself will start in SetUp. So, in this test, the first thing we need to do is tell FitNesse to go to the webshop, which in our case will be Amazon.com. Implementing that in our code will look like this:

|open|https://www.amazon.com/|

We see a FitNesse command followed by a pipe and then the value (the URL). This is how FitNesse works. By using pipes, FitNesse can break down the code into predefined commands and values.

Step 4 Tell FitNesse what item to search for
Now we want FitNesse to search for an item. To do so, we need to tell FitNesse what to look for on the page. We can do this by using selectors. FitNesse allows for several technical selectors, including id, CSS and Xpath.

Selectors
If you are not familiar with this concept, go look it up (for example here). Upon inspection we notice that the Amazon-search bar is an input-field with id ‘twotabsearchtextbox’. Here we selected this ID, because it is easier to read, but you could try other selectors yourself. Now we are ready for the next line of code:

|enter|sunglasses|for|id=twotabsearchtextbox|

A quick look at this line learns that there are two commands and two values. We ask FitNesse to enter (command) ‘sunglasses’ (value) for (command) ‘id=twotabsearchtextbox’ (value). Basically: enter ‘sunglasses’ in the search bar. If you would want to use different selectors, you could replace ‘id=’ with ‘xpath=’ or ‘css=’.

Step 5 Tell FitNesse to press the ‘search’ button
The next step is to tell FitNesse to press the search button. We could tell Fitness to hit ‘Enter’. Alternatively, we could use an Xpath or CSS-selector. We are just going to use the press Enter-option as it is much easier to read.

|press|Enter|

Step 6 — Narrow down the selection with heuristic selectors

On the illustration on the left, you will see that with only these few lines of code we already get a lot of hits for our sunglasses search. It will take forever to go through all of the 10.000+ results so we want to narrow down this selection.

So far, we used technical selectors to tell FitNesse where to click or enter values, but FitNesse also allows for heuristic selectors. Where technical selectors provide a direct path to an element on the page (go to coordinates X,Y), heuristic selectors only provide a general direction to the element (look for the tall building). The main advantages of using heuristic selectors are speed and readability of the code. Going back to our test, on the search results-page we can narrow down the results by selecting specific departments. One of those departments is the ‘Surf, Skate & Street’-category. Instead of finding a CSS-selector or Xpath, we can tell FitNesse to click ‘Surf, Skate & Street’.

|click|Surf, Skate & Street|

Besides the readability and speed of coding, using heuristic selectors is also more flexible. FitNesse looks on the page for the word to click on, without having to know the specific location. This could be helpful when someone changes the layout of the page or decides to change the ID’s. And, we testers are lazy, it is much simpler to program than searching for the right Xpath.

From sunglasses to backpacks

But let’s continue. Our script now takes us to the department ‘Surf, Skate & Street’. To our surprise, there is no mention of sunglasses in this department, even though we searched for sunglasses. Ah well, we wanted a new backpack anyway. So, we now know that we can use heuristic selectors, so we can use:

|click|Backpacks|

Now we want to select a backpack. At the time of writing, only three backpacks are displayed. Because we want to make our script as fail-proof as possible, using heuristics (just |click|<name of backpack>|) will not work if the backpack is sold out.

So instead, we want to write a selector that will always click on the first result. Give it a try If you get stuck, we have written down an example below this screenshot.

|click|xpath=//div[1]//span[@class=”a-offscreen”]//ancestor::a|

Step 7 — Verify the price
Now we want to verify whether the price displayed on the product page is the same as the price in your basket. At the time of writing this article, the price of the first backpack is $75.00. But due to dynamic pricing or different backpacks being displayed, this amount can change instantly. FitNesse allows you to store the value of the field in a variable. We will come back to this in more detail in a later, but for now, we can do that by implementing this code:

|$price=|value of|xpath=//div[@id=’buybox’]//descendant::span[contains(text(),’$’) and not(text()=’$’)]|

In this line of code, we will store the value of the element with id ‘price_inside_buybox’ in a variable called price. Now write the code to put the item in the basket:

|click|Add to Cart|

Once we add the item to the cart, Amazon shows a subtotal-screen:

On this page we want to make sure Amazon added the right value. There are several ways to do this, but we want to check whether the value is the same as the price we stored earlier. We can do so with this piece of code:

|check|value of|xpath=//*[@id=’hlb-subcart’]//span/span[2]|$price|
|check|value of|xpath=//*[@id=’hlb-bottom-subcart’]//span/span[2]|$price|

We also want to make sure the cart itself contains the item with the right price. Add another line of code to your script to go to the cart:

|click|xpath=//a[contains(text(),’Cart’)]|

Why not to use the heuristic approach here
Now, why did we not use the heuristic approach? Could we not just |click|Cart|? Notice that the word ‘Cart’ appears on the screen multiple times, not all are clickable. FitNesse will click the first instance of ‘Cart’ it finds. We wanted our test to be failproof, so we decided to go with the Xpath this time.

On the Cart-page we want to confirm the price again:

|check|value of|xpath=//*[@id=’sc-subtotal-amount-activecart’]/descendant-or-self::span[contains(text(),’$’) and not(text()=’$’)]|$price|
|check|value of|xpath=//*[
@id=’sc-subtotal-amount-buybox’]/descendant-or-self::span[contains(text(),’$’) and not(text()=’$’)]|$price|

Checking if the right product was added to the cart
We have now written the code we wanted. But we also wanted to check whether the right product was added to the cart. If you are up to it, can you write the code before scrolling down to see an answer.

Your code should now look something like this:

|script|browser test|
|open |
https://www.amazon.com/|
|enter |sunglasses|for|id=twotabsearchtextbox|
|press |Enter|
|click |Surf, Skate & Street|
|click |Backpacks|
|click |xpath=//div[1]//span[
@class=”a-offscreen”]//ancestor::a|
|$price=|value of|xpath=//div[
@id=’buybox’]//descendant::span[contains(text(),’$’) and not(text()=’$’)]|
|$product=|value of|xpath=//*[@id=’productTitle’]|
|click |Add to Cart|
|check |value of|xpath=//*[@id=’hlb-subcart’]//span/span[2]|$price|
|check |value of|xpath=//*[@id=’hlb-bottom subcart’]//span/span[2]|$price|
|click |xpath=//a[contains(text(),’Cart’)]|
|check |value of|xpath=//*[
@id=’sc-subtotal-amount-activecart’]/descendant-or-self::span[contains(text(),’$’) and not(text()=’$’)]|$price|
|check |value of|xpath=//*[
@id=’sc-subtotal-amount-buybox’]/descendant-or-self::span[contains(text(),’$’) and not(text()=’$’)]|$price|
|check |value of|xpath=//*[
@id=’sc-active-cart’]//*[@class=’a-list-item’]//span|$product|

Before you save your test, click the ‘Format’-button. You see what happened? FitNesse should have straightened all pipes to look like this:

The test should look like this

This again makes for an easier read. FitNesse is all about readability and making it accessible for lots of different users.

Step 8 — Run the test
Now let’s run the test! First, save your test by using the ‘Save’-button. Once saved, you can now click ‘Test’ on the top of the screen.

Step 9 — Check the results page
FitNesse should run your test by opening the browser and start to go through all the lines of the code step by step. Eventually, it will close the browser and present a results page.

Green, red or orange
On this page, FitNesse will show whether the test succeeded (green beam), failed (red beam) or something went wrong (orange beam). By scrolling down you could zoom in on the different lines of code. Here FitNesse will also colour-code each line. This way, if a test is failing or not working, you should be able to narrow down the problem.

The test has succeeded without errors

All steps have been executed and are in the green. A watchful eye will spot that the price of the item in the basket is different from what we saw earlier in this article. Dynamic pricing and product placement at it’s finest.

Inserting a pause in your script
If you noticed Amazon loading times might have caused the issues, you could insert a pause in your script. It is not recommended but it could do the trick. Between each transition of pages, you could insert:

|wait|1|seconds|

(1 being the number of seconds you want FitNesse to wait)

Your first script is now up and running
Congratulations! Your first script is now up and running and somewhat fail-proof. It might still be a bit hard to read for non-programmers and we could improve the efficiency in some ways. If your test fails at certain lines, try to figure out what the problem is. During our own testing, we found that the last line, where the product title is being verified, sometimes causes problems. We will expand on this in the next tutorial in which you will also learn some other tricks and best practices to improve your script. Happy coding!

Continue to the next story.

--

--

Computest
Testautomation Computest

What started out as a group of friends in 2005, has expanded into a company with over 100 experienced technical specialists. Driven by passion for quality & fun