Improve the quality of code with Unit Test
Introduction
When programming in MQL4, I have dealt with some ready-made programs in MQL4, as well as write more than a dozen of his. In the end I came to the conclusion that MQL4 - this is a very favorable environment for creating low-quality programs. That’s why I think so:
- MetaTrader 4 does not have built-in debugger. The process of finding bugs is sometimes quite painful.
- MQL4 has no built-in exception handling, how it is implemented in C + + or Java.
- Programs in MQL4 are often written in haste, with a greater focus on the idea, rather than the quality of the code.
All of this leads to the fact that reducing the quality of code, which in turn implies:
- Malfunctions advisers, wrong algorithm works (especially critical when working on real).
- The slow execution speed. Makes the optimization very slow.
- Poor handling error situations. Adviser may be unusable.
Just want to say that all the above does not apply to experienced MQL4 programmer with years of experience. Experienced programmers find ways to write quality code.
As my main work involves testing the quality of software, I was interested in the existence of any material for testing and debugging of MQL4 programs. But I could not find many such articles. So I want to put before one of the ways to improve program quality. If the topic will be interesting in future articles, please consider other issues.
A bit of theory on Quality
So, a little Googling, we learn that:
Quality - a set of properties and product characteristics that give it the ability to meet or due to expected demand.
For software, the program can be considered high quality if it meets the needs of the customer and correctly performs all the functions assigned to it.
In order to get a quality program, usually requires two activities:
- Quality Assurance - measures aimed at preventing the occurrence of defects.
- Quality Control - check the quality of the finished program to detect defects, if QA does not work:). It should be understood that the defect is unlikely to be corrected, if it is not found. The situation will not look nice, if a defect was discovered by the customer …
Quality Assurance - is a complex matter. It ranges from a comfortable job and ends with the introduction of programming complex business processes. We will not touch it until, let’s talk about quality control.
The more quality control - the higher the probability that the program will work as expected:) Ideally, quality control (or, in other words, testing) should be carried out at each stage of development:
- Test specification (Terms of Reference) - based on incorrect TK can not develop correctly working program.
- View the source code (Code Review). Search deficiencies, inefficient code, the violation of the rules of coding errors are obvious.
- Testing of individual functions of the program in automatic mode (Unit Testing and Unit Testing).
- Testing of all of the resulting program in manual mode. People (tester) verifies whether the program works.
- Testing program in unattended mode (automated testing and Automated Testing). This is when the robots themselves check the quality of the program. It sounds utopian, but sometimes works:)
- Testing program by the customer.
etc. Types of testing there are many …
From all this variety of tests we are most interested can Unit Testing.
A bit of theory on Unit Testing
Google gives us the following definition of unit tests. Unit Testing - a method of validating an application in which the programmer checks the individual units (blocks) of the source code for their suitability for use in the rest of the program. Unit - the smallest suitable for testing the program. In functional languages ??(Kojima is MQL4) per unit can take a separate function.
Unit testing is most often done automatically. That is, write a program that calls the function under test with different parameters, then generates a report about the correct values ??returned on or off.
Unit tests can be extremely useful for the following reasons:
- If a failure is detected - it is easy to understand its cause. Since tested only one function. If a failure is detected in the whole application, you should still take the time to find a function which generates the issue.
- It is easy to verify fixes a bug or not. Simply start again automatically Unit Test. No need to restart the entire application. For example, there are errors that occur rarely in certain circumstances that are difficult to recreate. In the case of Unit boarded the problem disappears.
- You can easily optimize the function code and absolutely no fear that something will break. Unit test will always show, continues to function normally work or not.
- You can identify problems that are not show themselves immediately, but can play back the customer and then require many hours of debugging and searching.
- You can apply modern Test Driven approach. When first written Unit Test, and only then developed function. Developed to function as long as the unit tests will not be passed. This approach was also tried for the first time me in the same application in C + + and has proved to be the best side. I had a feeling incommunicable delight as the end of a function, I was completely confident in their performance, and their further use in the program did not generate any problems.
How it looks. Suppose we write the square root function:
y = sqrt (x)
Accordingly, for our test, we will write another function that will work out as follows:
- verify that the sqrt (-1) == error
- verify that the sqrt (0) == 0
- verify that the sqrt (0.01) == 0.1
- check that sqrt (1) == 1
- verify that the sqrt (4) == 2
- verify that the sqrt (7) == 2.6 ….
We can write a function to check before we write the main function. So we like to define requirements that must be met under development function. This will be our approach, the use of Test Driven. It was only after the Unit test run for our error-free, we can safely use the main program.
It remains an open question: how to choose a set of test parameters for the test function? Of course, ideally you want to use all possible values, but almost always it is impossible or difficult. On the topic of selecting test values ??can write a separate article. Here I will try to give some general guidelines:
- Be used as valid data and information leading to the error. Since must not only verify that the function performs its responsibilities, but also how well it handles errors.
- You must use the boundary values. For example, if the range is from 0 to 100, should be used to test the value raavnye and 0 and 100. If the input string - need to try to empty string and a string with a maximum length.
- You must use the values ??that go beyond what is permitted. If we take the example of the previous section, you will need to use the value 101, -1, meaning long lines for max +1.
- We must try to partition the set of all possible values ??for a subset similar to the behavior of which will be the same (called equivalence classes). And for each class to choose a single value. For example, does not make sense to check both sqrt (4) and sqrt (9). Much more interesting to check sqrt (4) and sqrt (5), because In the second case, the function returns the value of the irrational, and in the first case unit.
- If the function has a branch (if, switch), you should try to have each of the branches was affected by unit tests.
See Also