Background
An efficient software development process is critical for software developers, determining whether development is a painful struggle or a joy of continuous improvement. People's disdain for software blue-collar, the cumbersome and lengthy traditional development process of intolerance, so that most developers are at a loss. Some recently arisen software development process related technologies, provide some more efficient and practical software process development methods. One of the more basic and critical technologies is test-driven development (Test-driven development). Although TDD light is greater than extreme programming, test-driven development can be applied independently. The following is an introduction from the perspective of developers, so that developers can understand, master, and apply this technology as quickly as possible with minimal cost. The following points are discussed in terms of advantages, principles, processes, principles, testing techniques, tips, etc.
Back to top of page
1. Advantages
The basic idea of TDD is to drive the entire development through testing. Test-driven development technology is not just a test effort.
Demand has always been the software development process feel the most difficult to clearly describe, variable things. The requirement here is not just about the needs of the user, but also about the use of the code. What many developers are most afraid of is the late change of the interface of a class or function to modify or expand, why this happens is because the use of this part of the code is not a good description of the requirements. Test-driven development is to write test cases, first of all to consider the use of code requirements (including functions, procedures, interfaces, etc.), and this description is not two-meaning, executable validation.
By writing the test cases of this part of the code, the decomposition of its function, the use of the process, the interface are designed. And the design of the code from the perspective of use is usually more in line with the requirements of post-development. Testable requirements are very useful for improving the cohesion of the Code and for reusing it. Therefore, test-driven development is also a process of code design.
Developers often get bored with writing documents, but often want to have documentation to guide them when they want to use and understand someone else's code. The test case code generated during the test-driven development process is the best explanation for the code.
The basis of a happy job is to have confidence in yourself and confidence in the outcome of your work. Many developers are often worried: "Is the code correct?" "Is there any serious bug in the hard-coded code?" "" Does the new code modified have any effect on the other parts? ”。 This fear even leads to the point where some code should be modified but not modified. Test-driven development provides a test set that can be used as a source of confidence.
Of course, the most important function of test-driven development is to ensure the correctness of the code, to quickly identify and locate bugs. Finding and locating bugs quickly is a dream for many developers. Test sets for critical code, as well as continuous improvement of test cases, provide a condition for quickly discovering and locating bugs.
My piece of very complex code was developed using TDD, and only a few bugs were found in real-world applications, and were quickly fixed. After you apply, you will certainly for that confidence of the development process, the function of increasing, perfect feeling, quickly found, locate the ability of the bug infected, like this technology.
So what are the principles and methods that provide these benefits? Let's look at the principle of TDD.
Back to top of page
2. Principle
The basic idea of test-driven development is to write the test code before developing the functional code. In other words, after you have explicitly developed a feature, think about how to test the functionality, write the test code, and then write the relevant code to meet the test cases. Then loop through the development of adding additional functionality until the full part is functional.
Here we extend the application of this technology from code authoring to the entire development process. You should test-drive all phases of the development process, first think about how to test, validate, evaluate, and write the relevant test documents, then start the next step, and then verify the relevant work. is a more popular test model: V Test model.
"Figure V Test Model"
At all stages of development, including requirements analysis, summary design, detailed design, coding process should consider the corresponding test work, complete the relevant test case design, test plan, test planning. The development phase mentioned here is just an example, adjusted to the actual development activities. The relevant test documentation is not necessarily a very detailed and complex document or form, but it should develop a test-driven habit.
For the test model, there is also the X test model. This test model, I think, is to model the detailed phase and coding phase, and should say more detailed description of the development behavior of the detailed design and coding phases. and a corresponding test-driven development for a feature.
"Figure X Test Model"
The basic principle should be said to be very simple, then how to do the actual operation, the following is a detailed introduction to the development process.
Back to top of page
3. Process
Test-driven development in other stages of software development, according to test-driven development ideas to complete the corresponding test documents. The detailed design and coding phases are described below.
The basic process for test-driven development is as follows:
1) Clear the current function to be completed. Can be recorded as a TODO list.
2) quickly complete the test case writing for this feature.
3) test Code compilation does not pass.
4) write the corresponding function code.
5) test pass.
6) Refactor the code and ensure that the test passes.
7) cycle through the development of all functions.
To ensure that the entire test process is quick and convenient, you can often use the test framework to organize all of your test cases. A free and excellent testing framework is the Xunit series, and almost all languages have a corresponding test framework. I have written an article about Cppunit (http://www.ibm.com/developerworks/cn/linux/l-cppunit/index.html).
During development, the test code and function code are usually stored separately, providing a simple example of a test framework that you can use to understand the test framework. The following is a list of files.
project/ Project Home Directory
Project/test Test Project Home Directory
Project/test/testseq.cppTest the test files of seq_t, and modify the test files of other function files after copying.
Project/test/testseq.h
Project/test/makefileMakefile of the test project
Project/test/main.cppTest the project's main file, no modification required
Project/main.cppThe project's main file
Project/seq_t.hfunction code, tested file
Project/makefileMakefile of the project
The main process is basically the same, but to make your code easy to test, comprehensive and not cumbersome to test, there are many test principles and techniques to consider.
Back to top of page
4. Principles
Test isolation. Tests of different codes should be isolated from each other. Testing a piece of code only takes into account the testing of this code, and does not consider its implementation details (for example, it uses the boundary conditions of other classes).
a hat. Developer development process to do different work, such as: Writing test code, development of functional code, code refactoring and so on. Do different things and take on different roles. Developers should keep their focus on the current work when they do the work, rather than considering the details of other aspects to ensure that there is only one hat on the head. Avoid considering extraneous details too much, unnecessarily increasing complexity.
The test list. There are many functional points that need to be tested. When you want to add functional requirement issues at any stage, attach the relevant feature points to the test list, and then continue to work at hand. And then constantly complete the corresponding test cases, function code, refactoring. One is to avoid omissions and to avoid interfering with current work.
Test drive. This is the core of comparison. To complete a function, a class, first write the test code, consider how it is used, how to test. It is then designed and encoded.
Write the assertion first. When you write a test code, you should first write an assertion statement that determines the function code, and then write the corresponding auxiliary statement.
Testability. function code design, development should have a strong testability. In fact, follow the better design principles of code are good testing. For example, relatively high cohesion, as far as possible to rely on the interface and so on.
Timely refactoring. Whether it is the function code or the test code, the structure is unreasonable, duplicate code and so on, after the test passed, the timely reconstruction. For refactoring, I'll write a detailed analysis.
Step forward. Software development is a very complex work, the development process to consider a lot of things, including code correctness, scalability, performance and so on, many of the problems are caused by too much complexity. Extreme programming puts forward a very good idea is to step forward. Take all the big, complex work and break it down into small tasks to complete. For a class, a function of a function is completed, if it is too difficult to decompose again. The completion of each function goes through the test code-function code-test-refactoring loop. Reduce the complexity of overall system development by decomposing. This effect is very obvious. After a few small function codes are completed, the large function code is almost free to pass without debugging. The implementation of a class of methods will soon see the whole class will soon be finished. It would have been a lot of features that needed to be added and soon you would see few. You'll even be shocked at the speed. (I understand that it's a sense of speed that drastically reduces debug, error time)
Back to top of page
5. Test technology
5.1. Test range, particle size
What features are tested? Will it be too cumbersome? When can I stop testing? These problems are more common. According to master Kent Benk, test the code that you think should be tested. That is, to believe in your own feelings, your own experience. Those important functions, core code should be focused on testing. If you feel tired, you should stop to have a rest. Feel no need for more detailed testing, stop this round of tests.
Test-driven Development stress testing should not be a burden, but should be a way to help us reduce our workload. And for when to stop writing test cases, it should be based on your experience, complex, core functions of the code should write more comprehensive, detailed test cases, or the test process can be.
There is no static standard for the test scope, and it should be possible to change over time. For the function code that did not write enough tests at the beginning, as the bug appeared, the relevant test cases were filled according to the bug.
The principle of small step forward, we need to test the large function block, we should first split into smaller functional blocks for testing, such as a Class A using Class B, C, you should write to a using B, C function test code, complete the test and development of B, C. So what should every small class or small function test? I don't think it is necessary. You should use your experience to test the places that may be problematic, and feel that it is impossible to do something about it when it's really going wrong.
5.2. How to write test cases
The test case is written using traditional testing techniques.
The operating procedure simulates the normal use process as much as possible.
Comprehensive test cases should be done as far as possible branch coverage, the core code as far as possible to achieve path coverage.
The test data as far as possible include: real data, boundary data.
Test statements and test data should be as simple and easy to understand as possible.
To avoid relying too much on other code, you can implement simple pile functions or piles (Mock Object).
If the internal state is very complex or should be judged by the process rather than the state, it can be verified by logging the log string.
Back to top of page
6. Tips
Many friends have doubts, "How is the correctness of the test code guaranteed?" Write a test code or write a test document? "This is not going to fall into the" chicken eggs, eggs and chickens "cycle. Actually, it's not. Usually the test code is very simple, usually a few statements around the correctness of a situation, if too complex, it should continue to decompose. The traditional development process usually emphasizes the test documentation. But as the pace of development accelerates, the user needs are constantly changing, the maintenance of high-level (demand, profile design) test documents can be, the lower cost of testing documents is indeed too large. And the test code that can verify the correctness of the function in real time is the best document for the code.
In the software development process, in addition to adhering to the above mentioned test-driven development of several principles, a need to pay attention to the problem is to beware of over-design. Writing functional code should focus on completing the current function point, passing the test, using the simplest, direct way to encode. Excessive consideration of later extensions, the addition of other functions, undoubtedly increases the complexity of the excessive, easy to produce problems. You should wait for a detailed test-driven development when you want to add these features. By the time, there is a complete set of test cases to build on, and it is easy to add related features through constant refactoring.
Resources
Recommended Kent Beck's book Test-driven Development:by Example, the Chinese version of test-driven development http://www.china-pub.com/computers/common/info.asp?id =14701
Free, excellent test framework *unit series, including:
Junit http://www.junit.org
CppUnit http://cppunit.sourceforge.net/
I have written an article about CppUnit using the handy development tool CppUnit quick Access Guide http://www.ibm.com/developerworks/cn/linux/l-cppunit/index.shtml
Introduction to the test model of the article "This or that, V or X?" "http://www.sdbestpractices.com/documents/s=8815/sdm0208e/
See "Software testing: an indispensable stage" in Chinese translation
Http://developer.ccidnet.com/pub/disp/Article?columnID=291&articleID=37924&pageNO=1 Software test: v-model or X-model? 》
Http://developer.ccidnet.com/pub/disp/Article?columnID=291&articleID=37975&pageNO=1
Unit Test Research Report http://blog.aspcool.com/tim/posts/349.aspx
Reference: HTTP://WWW.IBM.COM/DEVELOPERWORKS/CN/LINUX/L-TDD
Test-driven Development TDD (i) The benefits and introduction of TDD