Skip to content

Amazon Shopping Cart

Kristian Karl edited this page Mar 4, 2021 · 12 revisions

This is a Model-Based test, testing the shopping cart at the Amazon website. The source code of the test is Amazon Shopping Cart test.

Pre-requisites

  • Java JDK version 8 installed
  • Maven installed (version equal or greater than 3.2.3)
  • git installed
  • Latest Firefox installed

Get the source code of the example

git clone https://github.com/GraphWalker/graphwalker-example.git
cd graphwalker-example/java-amazon

Run the test

mvn graphwalker:test

Docker

Another way of running the same test is using docker. The advantage is that Firefox with the specific version 47.0.1 is pre-installed, eliminating conflicts with newer versions of Firefox and versions of Selenium. You need to have docker installed on you machine. Currently this is only confirmed to work on Linux.

docker pull graphwalker/amazon
docker run -ti --rm -e DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:/home/developer/.Xauthority \
    --net=host --pid=host --ipc=host graphwalker/amazon

The graph

Shopping cart model

The test is designed using yEd. If you click on the graph to the right and save the file as ShoppingCart.graphml, you can open it in yEd and have a closer look at it.

The test design

PDFl

The design of the test is based on an imaginary Use Case document. In the model, there are some special tags in the vertices. They look like:
REQTAG=UC01 2.2.1
The meaning of that keyword is to help you track what requirement is verified at that specific vertex. So if you open the Use Case document, you can verify for yourself that the test covers the requirements Use Case.

Other than the Use Case, the design is made in a way so that there is no Cul-de-Sac in the model. This means that given the start point at the Start node, GraphWalker will never end up in a state from which it cannot go any further.

The implementation

The test uses Firefox as a browser and Selenium to interact with that browser.

Have a look at the source code file ShoppingCartTest.java. The first thing to notice, is the annotation code at line 34.

@GraphWalker(value = "random(edge_coverage(100))", start = "e_StartBrowser")
public class ShoppingCartTest extends ExecutionContext implements ShoppingCart {

The annotation does the following 3 things:

  1. It tells GraphWalker to pick up this class as part of a test.

  2. The attribute value sets the path generator and stop condition for this model.

    The path generator is set to random, using a stop condition which requires 100% coverage of all edges in the model. Read more about generators and stop conditions at Generators and stop conditions

  3. Sets the starting point of the path generation using the attribute start set to e_StartBrowser.

    The model has a node called Start, but you do not need it. The attribute start overrides that node. In our case with the Shopping Cart test we want the test to start with an edge, which is hard to do with yEd since it requires a source node for any edge.

Always dry run your models

You should always verify your graphs before running your tests. You need to check that they do not misbehave.

java -jar graphwalker-cli-4.3.1.jar offline --start-element e_StartBrowser --model ShoppingCart.graphml "random(edge_coverage(100))"
{"currentElementName":"e_StartBrowser"}
{"currentElementName":"v_BrowserStarted"}
{"currentElementName":"e_EnterBaseURL"}
{"currentElementName":"v_BaseURL"}
{"currentElementName":"e_SearchBook"}
{"currentElementName":"v_SearchResult"}
{"currentElementName":"e_ShoppingCart"}
{"currentElementName":"v_ShoppingCart"}
{"currentElementName":"e_SearchBook"}
{"currentElementName":"v_SearchResult"}
{"currentElementName":"e_ClickBook"}
{"currentElementName":"v_BookInformation"}
{"currentElementName":"e_ShoppingCart"}
:

You can ask GraphWalker to be more verbose, and expose more data:

java -jar graphwalker-cli-4.3.1.jar offline --verbose --start-element e_StartBrowser --model ShoppingCart.graphml "random(edge_coverage(100))"
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"e0","currentElementName":"e_StartBrowser","properties":[{"description":"\n        \n          \n          \n          \n          e_StartBrowser\n          \n          \n        \n      "}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"n1","currentElementName":"v_BrowserStarted","properties":[{"x":118.94031187996033},{"description":"Verify that the web browser is upp running. "},{"y":77.962890625}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"e1","currentElementName":"e_EnterBaseURL","properties":[{"description":"\n        \n          \n          \n          \n          e_EnterBaseURL\n          \n          \n        \n      "}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"n2","currentElementName":"v_BaseURL","properties":[{"x":129.40442320808532},{"description":"Verify that Amazon's home page is properly displayed."},{"y":155.92578125}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"e2","currentElementName":"e_SearchBook","properties":[{"description":"\n        \n          \n          \n          \n          e_SearchBook\n          \n          \n        \n      "}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"n3","currentElementName":"v_SearchResult","properties":[{"x":147.87029622395832},{"description":"Verify that in the search result list, the book 'Practical Model-Based Testing: A Tools Approach by Mark Utting and Bruno Legeard' exists."},{"y":278.1416015625}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"e3","currentElementName":"e_ClickBook","properties":[{"description":"\n        \n          \n          \n          \n          e_ClickBook\n          \n          \n        \n      "}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"n4","currentElementName":"v_BookInformation","properties":[{"x":184.80164543030753},{"description":"Verify that the page displaing detailed information regarding '\nPractical Model-Based Testing: A Tools Approach' is correct."},{"y":385.357421875}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"0"}],"currentElementID":"e4","currentElementName":"e_AddBookToCart","properties":[{"description":"\n        \n          \n            \n            \n          \n          \n          \n          e_AddBookToCart [num_of_books<=3] / num_of_books++;\n          \n          \n        \n      "}]}
{"modelName":"ShoppingCart","data":[{"num_of_books":"1"}],"currentElementID":"n5","currentElementName":"v_OtherBoughtBooks","properties":[{"x":328.72195483010915},{"description":"Verify that the page 'Shopping Cart' now displays information 'Customers Who Bought Practical Model-Based Testing: A Tools Approach Also Bought'"},{"y":528.2200675843254}]}
:

If you only want to see the element name and the value of the num_of_books, using the jq command:

java -jar graphwalker-cli-4.3.1.jar offline --verbose --start-element e_StartBrowser --model ShoppingCart.graphml "random(edge_coverage(100)) | jq -r '.currentElementName + ", " + (.data[] | .num_of_books) | tostring'"
e_StartBrowser, 0
v_BrowserStarted, 0
e_EnterBaseURL, 0
v_BaseURL, 0
e_SearchBook, 0
v_SearchResult, 0
e_ClickBook, 0
v_BookInformation, 0
e_SearchBook, 0
v_SearchResult, 0
e_ClickBook, 0
v_BookInformation, 0
e_AddBookToCart, 0
v_OtherBoughtBooks, 1
e_SearchBook, 1
v_SearchResult, 1
e_ClickBook, 1
v_BookInformation, 1
e_AddBookToCart, 1
v_OtherBoughtBooks, 2
:

If you try this on your models and the command never stops, you have some logical problem with your test design, and might need to re-think the design.

Clone this wiki locally