Recently because of scientific research needs, has been studying Google's Open source RE2 library (regular expression recognition library), the Library source volume is large, written in C + +, for me this previously for the Java people is really a very painful thing, a day can only chew a little bit. Today, I studied the test methods used in the next, feel very good, take to share with you! (Ha ~c++ Daniel not to spray)
For me, the Rookie of C + +, usually write a few functions want to test is usually in main one of the test, because no C + + wrote the project, there is no more than n methods so in main test is not laborious. But for a project, more or less there are more than n methods, if one test in main, not only inefficient but also prone to error missing something. So how do you test it? Seems to have a lot of C + + automated testing tools, anyway, I was a useless, and can not evaluate. I'll say Google in the RE2 library is how to test it.
Let's start with a super simple example: Test two methods Getasciinum () and Getnonasciinum () to find out the number of ASCII characters in the flow and the number of non-ASCII characters, respectively.
The first step: Write a head file, define the class and test methods used for the test.
Test.h
#define TEST (x, y) \
void x# #y (void); \
testregisterer r# #x # #y (x# #y, # x "." # y); \
void x# #y (void)
void registertest (void (*) (void), const char*);
Class Testregisterer {public
:
testregisterer (void (*FN) (void), const char *s) {
registertest (FN, s); c13/>}
};
Parsing: First look at the defined class Testregisterer, there is a construction method, two parameters:
1. A function pointer: void (*FN) (void) that points to the name of the test method that we specifically want to write;
2. A string: Constchar *s, which belongs to the description information of the test method.
This constructor calls another function Registertest (), which is specified below.
Then look at the macro test (x, y) defined above, and replace it with the Testregisterer r# #x # #y (x# #y, # x, # y), where x# #y作为方法名, # x "." # y as descriptive information. There may be some of the entry-level people like me that don't understand this macro, because you don't know what the x# #y (void) is. At first I also did not want to understand, because the words will be an error, and then through the GCC-e option to activate the macro-compilation, looked at the next compile period unfolded into what looks like. Here is a simple example to illustrate: Suppose X is test,y flow, if not before and after that, then the expansion of the Testregisterer Rtestflow (Testflow, "Test.flow"); This is obviously a function declaration, there are two arguments, and the second is a string, so what's the first one? The compiler thinks it's a function name (and it's actually), but this function is clearly undefined before, and it will report an error that cannot find the declaration of this function, so you need to add void x# #y (void), declare the function, and of course the light declaration does not implement the same error in the link, so you need to add void X # #y (void) For specific implementation, note that there is no comma, there is no specific implementation of {}, because this is a macro, Google's test functions are written in this way:
TEST (x, y) {
.... . Concrete Implementation
}
So the above example test (test, Flow) {...//concrete implementation}, after the overall expansion is like this:
void Testflow (void);
Testregisterer Rtestflow (Testflow, "Test.flow");
void Testflow (void) {
.... Concrete Implementation
}