]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/test/doc/tutorials/new_year_resolution.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / test / doc / tutorials / new_year_resolution.qbk
CommitLineData
7c673cae
FG
1[/
2 / Copyright (c) 2003 Boost.Test contributors
3 /
4 / Distributed under the Boost Software License, Version 1.0. (See accompanying
5 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 /]
7
8[section:bt_and_tdd Test driven development with Boost.Test]
9
10Today is a momentous day - first day of new year. Today I am going to start a new life. I am going to stop eating a
11greasy food, start attending a fitness club and ... today I am going to test programs I am writing. I can start right
12after the last line of a program is completed or, even better, I can write tests while I am coding. And maybe next time
13I will write tests before the coding, during the design stage. I have read a lot of literature on how to write the
14tests, I have the unit test framework in hand and an idea of new class. So let's get started.
15
16Let say I want to encapsulate an unchangeable C character buffer with a length into the simple class `const_string`.
17Rationale: a string class that does not allocate a memory and provide a convenient read-only access to the preallocated
18character buffer. I will probably want `const_string` to have an interface similar to the class std::string. What will I
19do first? In my new life I will start with writing a test module for future class `const_string`. It will look like
20this:
21
22[import ../snippet/snippet13.cpp] [snippet13]
23
24Now I can compile it and link with the unit test framework. Done! I have a working test program. It is empty, so when I
25run the program it produces following output:
26
27``*** No errors detected``
28
29
30
31Well, now it could be a good time to start a work on `const_string`. First thing I imagine would be good to have is a
32constructors and trivial access methods. So my class initial version looks like this:
33
34[import ../snippet/snippet14.cpp] [snippet14]
35
36Now I am able to write a first test case - constructors testing - and add it to a test suite. My test program became to
37look like this:
38
39[import ../snippet/snippet15.cpp] [snippet15]
40
41The constructors_test test case is intended to check a simple feature of the class `const_string`: an ability to
42construct itself properly based on different arguments. To test this feature I am using such characteristics of
43constructed object as a data it contains and a length. The specification of the class `const_string` does not contain
44any expected failures, so, though the constructor can fail if I would pass a pointer to an invalid memory, error check
45control is not performed (can't require what was not promised :-)). But for any valid input it should work. So I am
46trying to check a construction for an empty string (1), a NULL string (2) a regular C string(3), an STL string(4), a
47copy construction(5) and so on. Well, after fixing all the errors in the implementation (do you write programs without
48errors from scratch?) I am able to pass this test case and the unit test framework gives me the following report:
49
50``Running 1 test case...
51
52*** No errors detected
53``
54
55Encouraged I am moving on and adding more access methods:
56
57[import ../snippet/snippet16.cpp][snippet16]
58
59I added the new feature - I need a new test case to check it. As a result my test suite became to look like this:
60
61[import ../snippet/snippet17.cpp] [snippet17]
62
63In the data_access_test test case I am trying to check the class `const_string` character access correctness. While tests
64(1) checks valid access using `const_string::operator[]` and test (2) checks valid access using method
65`const_string::at()`, there is one more thing to test. The specification of the method `const_string::at()` contains
66validation for the out of bound access. That was test (3) is intended to do: check that the validation is working. A
67testing of a validation and error handling code is an important part of a unit testing and should not be left for a
68production stage. The data_access_test test case passed and I am ready for the next step.
69
70[import ../snippet/const_string.hpp] [import ../snippet/const_string_test.cpp]
71
72Continuing my effort I am able to complete class `const_string` (see [@../snippet/const_string.hpp Listing 1
73=const_string.hpp=]) and testing module for it (see [@../snippet/const_string_test.cpp Listing 2 =const_string_test.cpp=])
74that is checking all features that are presented in the class `const_string` specification.
75
76
77
78Well, I am step closer to fulfilling my new year resolution (we should see about this fitness club sometime next ...).
79What about you? Your testing habits could be a little different. You could start with a class/library development and
80then at some point start writing test cases on feature basis. Or you can, given a detailed specification for the future
81product, including expected interfaces, immediately start with writing all test cases (or it could be a different
82person, while you working on implementation at the same time). In any case you should not have any problems to use
83facilities provided by the Boost.Test unit test framework and, let me hope, be able to write a stable, bulletproof code.
84And what is even more important is your confidence in an ability to make changes of any complexity without involving a
85lengthy regression testing of your whole product. Your test module and the unit test framework will stay behind your
86back to help you with any occasional errors.
87
88
89[endsect]