First of all, I would like to say that mathematics helps to put our thoughts in order and effectively develops logical thinking, and this is one of the most necessary qualities of software development participants. Speaking of testing, it mainly concerns the behavior of the system, which is orthogonal to the structural representation common to software developers. The difference between structural and behavioral views is that the structural focuses on what the software is, and the behavioral view takes into account what the software does.
One of the difficulties of testers is that basic technical documentation or software development guidelines are usually written by developers and for developers, and the emphasis is mainly on structural rather than behavioral information. Of course, both structural and behavioral parts are very important for testing, since programming errors can be found in each of these parts. That is why we will talk about discrete mathematical methods to show the connection between the structure of the program and its behavior.
In their daily work, software quality assurance (QA) engineers work with formula operations, function behaviors, and data structures. They always monitor and check the ever-changing state of systems, so they need to have algorithmic and mathematical thinking to understand the logic of software.
If a developer uses a mathematical approach in his work, as a result, all logical operations will be linked to each other, actions will follow a logical chain, and each function will be considered structurally.
Discrete mathematics helps us to find the optimal solution in different situations. For example, you can find the most suitable set of test cases (Test cases), not covering all possible options. Moreover, discrete mathematics helps us visualize the exact piece of software that has been implemented and covered in tests.
Unfortunately, we do not live in an ideal world, and the expected actual results of the software application and the actual results may differ. So, the main goal of the quality assurance department (QA) is to cover as many test cases as efficiently as possible.
To show you this concept in more detail, we created the following Venn diagram with an example that we outlined earlier in general:
M1={month:month has 30 days} M2={month:month has 31 days except December} M3={month:month is February} M4={month:month is December} D1={day:1<=day<=28} D2={day:1<=day<=29} D3={day:1<=day<=30} D4={day:1<=day<=31} Y1={year:year is a leap year} Y2={year:year is not a leap year}
Graphs are also fundamental to the software development process. For example, using a graph, we can decompose complex functions into several smaller parts, which helps us more effectively understand business logic.
The graphs can be directed and undirected, which means that we can move from node to node in one direction or in both directions (in the case of a directed graph), or we cannot move from one node to another (if the graph is directed strictly in one direction)
So let's go back to software testing and imagine that we have some process flow (for example, moving a task to some kind of task tracking system); we have a condition of some task, and we can move it to another stage (a directed graph), or we can reach a certain point where we can do nothing with an entity (an undirected graph). With this approach to visualization, we can easily assemble a set of all possible actions available for this entity:
Let's continue and look at the adjacency matrix, which can be constructed on the basis of an undirected graph. In the example below, the elements of the adjacency matrix indicate whether or not pairs of vertices are adjacent:
Now imagine that nodes are the conditions of some entities, and if we build an adjacency matrix for this graph (set of entities), we will see a finite set of actions that we can take. For example, changing the status from node “0” to node “1” is available because they are related to each other. But the essence of "0" can not be changed to stage "2" or "3", as we can see from our matrix - in the cells is written "zero". Using this matrix, we can eliminate unnecessary sets of entity steps and reduce the set of test cases.
Another matrix that we can use to collect test cases is the incidence matrix, which shows the relationship between two classes of objects. In the next figure we see an undirected graph and its incidence matrix: “1”, “2”, “3” and “4” are nodes (entities), “e1”, “e2”, “e3” “e4” are edges of the graph and the matrix illustrates the entities and actions that we can do with them. With node “1” we can perform actions “e1”, “e2” and “e3”, but action “e4” is not available for node “1.”. This method helps a lot when creating a set of test cases.
Imagine that a tester received a list of entities and actions that can be carried out with these entities. With this matrix, it can reduce the set of test cases. Reducing the number of tests is a very important part of the software testing process. Software testing is largely dependent on reducing the number of test cases, and with this approach, test coverage and avoidance of redundancy are maximized.
The goal of software testers is to cover a product using effective test cases that allow you to test all possible combinations of actions. Testers can succeed with minimal effort using discrete mathematics approaches (algorithms) to find the optimal set of test cases and maximize the effectiveness of the software testing process.
Discrete mathematics also helps us understand how software is actually created, because all software uses algorithms and methods of discrete mathematics and mathematical logic. Therefore, if we understand how this works, we may find errors or problems within the program that cannot be detected by the user.
Let's look at an example of how an application works on microservice technology with the help of “Petri nets” (dynamic graph):
Here we see that the system has an initial state and should receive some signal that is sent from another service (a token appears). Depending on the result obtained, the following action should be performed. Thus, the Petri net illustrates the dynamics of the entire system. If any problem exists, we can locate the defect faster.
Artificial neural networks are also based on the principles of the graph. They imitate the ability of information processing by neurons of the human brain. Each part of the neural system is based on a graph that contains "input" nodes, a "hidden" layer and "output" nodes.
Some data arrive at the input layer, and the algorithms of the hidden layer process this data and send the result to the output stage. Thus, the neural network can perform actions based on this data. Neural networks also consist of many similar graphs with different logic, so they can make decisions based on input parameters.
Our final example of using discrete mathematics in testing involves building a software testing process. Currently, there are many methodologies and approaches called “millenium testing”, which were developed long before their actual use, starting in the 2000s, when software development began to evolve rapidly.
BDD (Behavior Driven Development) is part of the so-called Millenium testing, this methodology is an extension of TDD (Test Driven Development). BDD allows testers to establish a closer relationship between acceptance criteria for a given function and tests used to test this functionality. BDD can transform structured natural language operators into executable tests, thereby bringing more clarity and understanding to the business side and the development side, as they begin to speak a common language. The basic structure of the BDD workflow is also based on a dynamic graph (Petri Net).
As can be seen from this structure, each process is accompanied by a different process, and it cannot move to the next stage until the previous stage is completed. Once again, the principles of discrete mathematics help us understand the process more effectively.
Source: https://habr.com/ru/post/451886/
All Articles