Decision table for testing algorithms

The previous articles Decision Table for Filtering Testing with Dependent Filters and Decision Table for Testing Complex Forms described how the Decision Table test design technique can be used to test filtering and complex web forms.

In this article, I want to show how this technique can be used to test algorithms, including data selection priority algorithms.

Algorithms may not be very complex, and for such algorithms, test design in the form of a “decision table” can be done quickly enough.

Example 1: Algorithm for calculating the total cost of a product, taking into account the discount, depending on the total cost of the selected product

Flowchart for the algorithm for calculating the total cost of goods, taking into account the discount
Flowchart for the algorithm for calculating the total cost of goods, taking into account the discount

Below is a “decision table” for this algorithm.

Example 2: Algorithm for determining the possibility of returning / exchanging or repairing goods

Flowchart of the algorithm for determining the possibility of returning / exchanging or repairing goods
Flowchart of the algorithm for determining the possibility of returning / exchanging or repairing goods

Below is a “decision table” for this algorithm.

But on any large project, algorithms have very complex business logic and test design for them looks much larger.

One of the most difficult “decision table” test designs I’ve had to do for algorithms was a test design for the “priority price range” selection algorithm.

Example 3: Selection Algorithm priority price range».

First, I will briefly describe the essence of this algorithm.

There is an entity “Outlet” (abbreviated as TT), in which (optional) fields can be filled in the card:

  • A country

  • Region

  • retailer

  • Segment

But if the country is not filled, then the region is also not filled.

There is an entity “Price range”, in which (optional) fields can also be filled in the card:

  • A country

  • Region

  • retailer

  • Segment

Also, for the “Price range” indicate the type of price tag (“regular” (without a promotion), “for a promotion”).

There are the following priority levels for selecting a priority “Price Range”:

  • Level 1: For TT and “Price Range” the data is the same for “Country + Region + Segment + Retailer”

  • Level 2: For TT and “Price Range” the data is the same for “Country + Segment + Retailer”

  • Level 3: For TT and “Price Range” the data is the same for “Segment + Retailer”

  • Level 4: For TT and “Price Range”, the data is the same for “Country + Region + Retailer”

  • Level 5: For TT and “Price Range” the data is the same for “Country + Retailer”

  • Level 11: For TT and “Price Range” the data is the same for “Country”

  • Level 12: For TT and “Price range” the fields Country, Region, Retailer, Segment are not filled

Those. in the code, the selection of the “Price range” goes from a higher level to a lower one, until there is a match in the filled fields for the TT and the “Price range”.

The algorithm works on the fly when making a GET request for an individual TT, as a result of which the request response should contain only two “Price Ranges” of the “regular” and “promotion” types for each product from the product list.

For the test design of this algorithm, I used the Decision Table technique, but in a slightly unusual way, since here you need to test that the choice will go exactly from level 1 to level 12 in the order indicated above.

First, it was necessary to understand what data options are.

For each of the 4 TT fields, a value will either be selected or not. So there can be 2 options for each of their 4 fields, which means there are 2 * 2 * 2 * 2 = 16 options in total. But since there is a condition that if the country is not filled, then the region is also not filled, then 4 options for TT are excluded ( marked with red squares). Therefore, in the end, there are only 12 options for filling in the required fields of the TT card.

Since there are a lot of data options for tests when comparing filling in the TT and “Price Range” fields, I immediately decided to divide the data into just 12 separate tables (one table for one option to fill in the fields of the TT card).

Those. for the first table in all tests, the data set for TT will go when all fields “Country”, “Region”, “Retailer”, “Segment” are filled. For the next table, the next data set for the CT.

I first added these 4 fields for TT to the table at the very top of the conditions block.

Next, it was already necessary to decide on the data options for the “Price Range”. Price Range has the same 4 data fields. But since in the code they are also compared with the fields of the TT card, then for the “Price Range” there will already be three options for values ​​for each field:

  • empty

  • filled in and has the same meaning as in the TT card (in the table “Yes (completed)”)

  • is filled in and has a different meaning than in the TT card (in the table “No (filled)”)

I added these 4 fields for the “Price Range” next to the table in the conditions block. But so far I haven’t put down the values ​​right away, since it was also necessary to somehow take into account the condition for the priority of choosing the “Price range” depending on the level at which the data in the fields of the TT card and the “Price range” coincided. To do this, under the already added fields, I immediately added the line “Item from the priority list”, where I put down the values ​​​​for each level, starting from level 1 and up to level 12.

Then I already multiplied the columns of the table for each level 1-12 and looked at what combinations of data in 4 fields for the “Price Range” could be from the possible values.

When compiling the tests, all possible combinations for filling in the TT and “Price range” fields were covered, as well as their equality or difference when compared. At the same time, duplicate tests were removed from these 12 tables to reduce tests. I didn’t cut the tests even further, since this algorithm needed good coverage in order to have confidence in the accuracy of choosing exactly the required “Price Range” in each of the possible data sets.

As a result, 12 tables were obtained, each of which contained 44 tests, i.e. 528 tests to test this algorithm.

Table example No. 1: For TT, all fields “Country”, “Region”, “Retailer”, “Segment” are filled in:

Table example No. 6: For TT, only the fields “Country” and “Segment” are filled:

I tested these tables in the following way:

  1. Prepared 12 TTs with different data filling in the card according to the test design

  2. For each test, I created a “Price Range” of each type “regular” and “by stock” and registered their id in the tables.

  3. Then I made a GET request for each TT and checked that its response displays the two necessary “Price Ranges” and does not display others (for each of the 12 tables – its own)

  4. Then I deleted the first two “Price Ranges” from the database

  5. Again I made a GET request for each TT and checked that the two necessary “Price Ranges” were displayed in its response and others were not displayed (for each of the 12 tables – their own)

  6. Then I deleted the next two “Price Ranges” from the database

  7. Again I made a GET request for each TT and checked that the two necessary “Price Ranges” were displayed in its response and others were not displayed (for each of the 12 tables – their own)

  8. Then I deleted the next two “Price Ranges” from the database

  9. Etc.

At the same time, “Price ranges”, which should have been skipped in all tests (cells highlighted in light blue), were not deleted during the tests, since their presence should not have affected the data in the GET request response.

Of course, it was not easy to compile such a table, since at first it was necessary to think over all the parameters that need to be taken into account, as well as all the options for their values.

It was also important here to immediately divide the tests into several tables, since it was immediately clear that there would be a lot of tests, and there is a parameter by which such a division can be made. This reduced the number of tests in one table and made it easier to maintain in the future, as well as the ability to expand tests when new parameters are added.

For such a test design, I spent a total of about 3 days. But after that, I repeatedly used these tables on retests after improvements to this algorithm. Also, all tests from these tables were quickly covered by autotests.

For the tables from the examples above, in the following improvements, more parameters were added, which further increased the number of tests in each of the 12 tables. But little time was spent on expanding, since initially the table format and the set of parameters were chosen well.

I hope that an example of such a test design will inspire someone to start using the Decision Table test design technique for algorithms on their project. This is especially convenient on projects with complex business logic, when there are many conditions and a lot of tests that are difficult to keep in mind or describe for a long time in a more detailed format in the form of test cases, and also if new parameters are constantly added to features.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *