a Introduction to Unit testing
Unit testing is the most important tool for code correctness verification, and is the most important part of system testing. is also the only test method that requires code to be written for testing. In the standard development process, the Code of the Unit test is of equal importance to the code of the actual program. Each unit test is used to target the correct data for the corresponding unit of the test. Unit testing is done by the programmer himself, and ultimately the programmer himself. It can be said that programmers have the responsibility to write functional code, but also have the responsibility for their own code to write unit tests. Performing unit tests is to prove that the code behaves as we expect it to. Unit testing also has several benefits:
1, can help programmers find the exact location of the bug as soon as possible
2. Allows programmers to be more confident in their own programs
3. Enables programmers to make code more robust before committing to a project
4, can help the programmer to develop better
5. Be able to show other programmers how your program should be called
6. Be able to give project managers a better understanding of the current state of the system
? 1.1 to help programmers find out as soon as possible BUG the exact location
In an era of no unit testing, most of our errors were discovered by manipulating the page. When we find an error, we determine which code has a problem based on where the exception was thrown. But most of the time, we don't use try blocks in all methods to handle exceptions (this is also inefficient). Therefore, once an exception is found to be the top-most code thrown, the error is often seen in a deep layer of the underlying object. When we find the method that initially throws the exception, we may not know where this code is going to go wrong. It can only be looked up by line of code, and once an object used in this method has an external registration event, or there are other operations being synchronized with the current method, it is more difficult to find the real reason for the error. Experienced programmers will also know that most of the time, we are not really writing new code, but modifying the error of old code. This ratio is usually greater than 2:8, which is the 28 phenomenon when writing code-the time to write code is two, and the time it takes to find errors and modify errors for this code is eight. In this state, we will compile the whole program directly when we look for the error, and then step through the interface to the wrong place and then find out if there are any errors in the code. This method of finding errors is very inefficient. But when we have unit tests, we do not need to go through the interface to step through the operation, but directly run the method of unit testing, the input conditions are simulated into the error when the input information and the method of the form of the call, so that the error can be quickly restored. This will improve the speed of the solution, and every time you find the error to modify the unit test, then the next time there will not be the same error. If you pass the simulation, and the unit test does not have any exceptions, you can also conclude that the code is not an error, but other related code errors. We only need to debug a few other related code unit tests to find the real error.
? 1.2 Enables programmers to be more confident in their programs
Most of the time, when the supervisor asks us if the program will go wrong again, we will be very difficult to answer. Because we can't estimate what might be wrong with the system. But if we write unit tests for all the code at this point, and the test code is written according to the standard, these tests can be successfully tested. Then we are completely confident to say how much we are sure. Because in the test code, we've already anticipated all the possible scenarios, and the program code also solves the problems that might be expected. So we will become more and more confident about our own programs.
? 1.3 Enables programmers to become more robust before committing to a project
Most programmers when writing code, will first consider the most idealized case of the program how to write, after the completion of the ideal state of the successful compilation, and then enter the ideal data found no problem. They will be self-comforting and say "done." Then maybe in order to catch up with the progress, and then began to make another program. This idealized procedure is more and more in the long time. Once the test is submitted, it is found that there are errors there, and then the programmers come up with the time to fill a loophole there. And in the process of filling the loopholes, may also continue to follow this idealized idea, resulting in the situation where it caused the problem. But if we were to write unit tests for each piece of code at an early stage, and write according to some established criteria, the unit test would tell the programmer in advance where errors would occur. Then they may have dealt with the problems in the non-ideal state in advance of the writing process. This will make our code much more robust.
? 1.4 ability to assist programmers with better development
"Code not moving, testing the current. "This is a programming paradigm advocated in extreme programming. Because we are in the process of writing unit tests, we are actually designing which problems our code will deal with. Unit tests write well, which means that your code is well written. And you will write code based on some of the pre-conceived scenarios of unit tests, and you will not blindly add a property and add a method.
? 1.5 The ability to show other programmers how your program is called
? Typically, the unit test code writes about how to invoke that piece of code under test in various situations. So this unit test also shows the other people how our code should be called? Under what circumstances will the exception be thrown? Wait a minute. Such a unit test becomes a code-supporting document.
? 1.6 Enables project managers to better understand the current state of the system
In traditional management, the progress of the project and the quality of the code are communicated to the supervisor only by verbal means. So sometimes the supervisor gets feedback that might be true. But if a complete unit test system is passed, the supervisor can determine whether the developer's work is actually completed by looking at the running results of the unit tests and the Code coverage of the unit tests.
2.1 Creating unit Tests
The tool can unit test fields, properties, constructors, methods, and so on in any class, interface, struct, and other entities. Creating unit tests can be broadly divided into two categories: first, the overall test is to right-click on the class name and click the Create Unit Test option in the drop-down menu. This allows you to create unit tests for the entire class, and then he adds all the test methods to the entire class that can be tested. Developers add unit test code directly to these automatically generated test methods. Second, test alone, if you want to test a method, property, field only, you can put the mouse focus on the project name to be tested, and then right-click, select the Create Unit Test option in the right-click menu. This allows you to create unit tests for a single method.
? 2.2 Writing Unit test code
After you have created the unit tests, you can write the test code for the unit tests. The writing standard of the specific test code will be described in Chapter three.
2.3 Run unit tests
After the unit test code is written, you can test it by running unit tests. When you need to run unit tests, you need to open the Test Manager window. The window can be opened from the menu "test"-"window"-"Test Manager". After you open the window, you'll see a list of the unit tests we've created in that window. In the list, we can tick the check box in front of a unit test. Then right-click on "Debug Selected Tests" or "Run selected tests" in the right-click menu. When debugging a selected test, we can add breakpoints in the test code or in our own code and run it gradually to see its state. Running a selected test will only run the test and not be able to test it, when the code is run to simulate the actual running of the software. We can select which test to perform according to our actual situation.
2.4 Test Results
After running the test, we need to look at the results of this test. We can open a Test Results window by clicking "Test"-"window"-"Test Results" in the menu. Each test will show us some records in the test results. We can also view detailed result information by double-clicking the test result.
? 2.5 Code Coverage
One of the only criteria that the unit test writes is reasonable or if it meets the requirements is the code coverage for the entire test. Code coverage is actually the coverage of the actual program path that the test code runs to. In the actual program there may be a lot of loops, judgments and other branching paths. A good unit test should be able to move all possible paths, so that you can ensure that most of the cases have been tested. Tools for viewing code coverage are also available in VS2005. We can open the window of code coverage viewing by clicking "Test"-"window"-"Code Coverage Results" in the menu. To check for code coverage, we have to set it up because the system does not have code coverage detection by default. To open the code coverage test for a test, we must click "Test" in the menu--"Edit test Run Configuration"--"local test run ..." "To open a test configuration window. Selecting code coverage in the list on the left side of the window displays the settings for code coverage. In this configuration, the assembly that can be used to detect code coverage in the current solution is displayed, and we will need to check the assembly for coverage and then click on the "Apply" button. Once the setup is complete, we can run the unit test directly after the test passes. We can open the Code Coverage Results window, where we can see how much code is covered by these tests. When we double-click a class here, we can see that VS has changed the color of the code background. The code that is shown as dark brown is the code that is not covered, and we can somehow overwrite the code by adding code in the unit test code. The whole process of such a unit test is complete.
While the code for unit testing can be various, there are rules for writing unit test code. The objects under test are generally divided into methods (including constructors) and properties, so we determine the criteria for unit testing in these two directions. Because most developers haven't really used it yet. NET Unit testing tool, and the level of understanding of unit testing is not high. So it's not easy to make very many standards here. We currently focus on two major aspects of the specification: 1, which code needs to add unit testing? 2. How to code the Unit test?
3.1 ? which code needs to add unit tests
If the project is in the middle of a final sprint, the main coding work is basically done. Therefore, to fully add unit testing, in fact, is a relatively large investment. So unit tests cannot be combined all at once, and we can only test them step-by-step. In the first step, you should add unit tests to the exposed classes in all assemblies and public methods in the exposed classes. The second step is to unit test the constructors and public properties. The third step is to add a full unit test. The first step can be completed before the product is fully submitted, and two or three steps can be added after all other functions have been completed. Because the 23rd step of the addition work is similar to the first step, just in the amount of accumulation, so we first focus on the first step of the situation. In the first step of the unit test add, also need to be selective, we have to grasp the focus of testing. You should first add unit tests for the code that belongs to the framework technology. This includes the components that manipulate the database, the components that manipulate the external WebService, the message receiving send component, the messaging components between the background service and the prerequisite program, and so on. By testing These major reusable codes, the correctness and robustness of the underlying operations can be greatly enhanced. Second, add unit tests to the methods exposed by the business logic layer to the interface. This keeps the business logic right and allows most of the business operations to be summed up in unit tests, ensuring that after a product is released, a bug can be found directly through unit tests of the business logic when a problem arises. The rest of the code is mostly generated by the code generator, and most of the operations are similar, so we can do a detailed unit test for a business logic object first. With this rule, unit tests are added in a much reduced range. If the project is just beginning, you should add unit tests to all exposed methods and properties.
? 3.2 How the unit test code is written
There are a few things to consider carefully when writing unit test code: L, the code coverage of the method being tested must reach 100%. 2. The state inside the code being tested, for example, after a method is executed, whether a property or return value in the class in which the method resides is the same as expected. 3. The state of the external device used by the code being tested, such as whether the database is readable, whether the network is available, whether the printer is available, whether the webservice is available, etc. Each section of the unit test code must take into account the above three issues, and for these problems should be tested accordingly.
3.2.1 Code Coverage Requirements
describes what code coverage and code coverage methods are in section 2.5. Here we focus on how to increase code coverage to 100%. in general, code coverage is low, stating that there is not too much consideration in the test code for certain special cases. Special cases include: l boundary condition data, such as the maximum, minimum, DBNull of value type data, or the conditional boundary used in the method, such as a>100, then 100 becomes the boundary of the data. It is also necessary to test the data beyond the boundary as a test condition at the time of testing. 2 empty data, general null data corresponds to the data of the reference type, which is the null value. 3 malformed data, for reference-type data or structural objects, although the type is correct but its internal data structure is incorrect. For example, a database entity object that requires a property in the database must be non-empty, but at this point we can belong to an empty one. This object belongs to an incorrect database. These three kinds of data are for the external data used in the method being tested. The external data used in the method is nothing more than the property of the object or the data of the field in which the method parameter is passed. Therefore, when writing the test code, you must set the data used to the above data to detect the implementation of the method. This will ensure that the method is written correctly. when writing unit test code, first understand the external data that is likely to be used by the method being tested, and then set the external data to the conditions specified above, and then execute the method. This will basically be able to achieve the external data in all cases can be correctly tested. Unit test code coverage written in this way can typically exceed 80%. 3.2.2 whether the expected value reaches
When writing unit tests, you cannot simply pursue code coverage. Sometimes code coverage has reached 100%, and the program can run normally, but some data may not be expected after the method has finished executing. The result of execution must be asserted. In the Unit test module provided by. NET, you can use some static methods of a class to determine whether a value has reached the expected condition in a unit test. This class is assert. In this class, a lot of methods are disclosed, such as the equivalence of Judgement, the judgment of switching, and the non-cavitation of judgment. These methods allow you to make predictions ahead of time, and once the program executes, if these assertions fail, it means that the code has errors. When using assertions, we require an assertion to reach an average of 5 lines of test code. By adding assertions, we can make a test of the correctness of the data in the execution of the program, to ensure that our program does not have the wrong data or the wrong state of the situation.
3.2.3 test passes when external device status changes
When the code coverage and expected values have reached our requirements, the entire program has essentially reached the quality standards. However, this is not comprehensive, because many programs are used to external devices or programs, such as databases, printers, networks, serial ports, parallel ports and so on. When these devices change or are unavailable, the program may have some unpredictable errors. As a result, a robust program must also take these situations into account, usually by setting these devices to an unhealthy state to detect problems that may occur with the program. These conditions are then added to the test program. The above is only a simple unit test entry level requirements, of course, real unit testing There are many more complex requirements and testing techniques. But for a beginner, the robustness of your code should be able to meet most of the requirements if you can meet the above requirements. It is only when we compare the standard industrial development that we need to deepen the unit testing. If there is time, I will elaborate on the deeper unit test method later.
Unit Test Software Engineering overview