This article gives an introduction how to use RTest class to create automatic test harness for your application engines. The RTest class provides a simple console window where you can display the test result. Unfortunately it is not possible to use RTest for GUI testing.
Test harness basically is a black box testing. It calls a function and then compares the result value with a reference value. When the result value is the same with the reference value, the test passes; if they are not the same, then the test fails. RTest will help you to create an automatic test harness; it will display the test result on the screen and panic if one of tests fails.
Using RTest
RTest creates a console window where you can output the test result or check a boolean expression. The expression usually compares a variable or the result of a function call with a reference value.
The RTest class is declared in e32test.h. The following example shows how to use RTest class.
#include <e32test.h>
GLDEF_C TInt E32Main()
{
_LIT(KTestTitle, "My Testing");
RTest iTest(KTestTitle);
iTest.Title();
_LIT(KFirstTest, "First Test");
iTest.Start(KFirstTest);
// Your testing code...
iTest.End();
iTest.Getch();
iTest.Close();
}
The first two lines in the main program, E32Main(), defines an instance of RTest class and gives the title KTestTitle. You can display the title by calling Title() method, like shown in the second line. At the end of the program, all the resources needed by RTest are freed by calling Close() method.
As you see in this example, before starting the test suite, you have to call Start(); and at the end, you have to call End(). Note that Start() must be ended by End(); do not forget to call End()!
Now let’s start with a very simple test, i.e. to compare a defined integer with a constant. Add the following code between Start() and End().
TInt i = 10;
iTest(i == 10);
The first line defines an integer which has the value of 10. The second line calls the operator RTest::() that compares i with 10. This operator will do nothing if the condition is true; and raise a panic if it is false. Since this simple expression above will always return true; the test program will run without panic. If you run the program, you will see the emulator window like Figure 1a.
|
|
Next, try to change the condition to the following statement.
iTest(i == 11);
The statement above will return false; thus if you run the program you will get an emulator window like Figure 1b and your program will panic.
More About RTest::()
There are three variants of RTest::() operator. The first variant, as you see above, requires one parameter, that is the expression to be checked.
The second variant has one additional parameter, that is the line number information. In case of failure, the line number will be displayed on the screen. For example:
iTest(expression, 12345);
The third has one more additional parameter, that is the file name that will be printed on the screen when a failure mode occurs. For example:
iTest(expression, 12345, L"Testing.cpp");
When the expression fails, you will notice that the failure is in Testing.cpp file at line number 12345.
Test Numbering
When your test suite contains of several tests, you can add numbering to them by calling Next() for each test. For example, if you have three tests, you can write a program like the example below.
_LIT(KFirstTest, "First Test");
iTest.Start(KFirstTest);
// The first test...
_LIT(KSecondTest, "Second Test");
iTest.Next(KSecondTest);
// The second test...
_LIT(KThirdTest, "Third Test");
iTest.Next(KThirdTest);
// The third test...
iTest.End();
The output of the example above can be seen in Figure 2a.
|
|
You can also have nested numbering by calling Start() inside another Start(). The following example shows how to have nested numbering like shown in Figure 2b.
_LIT(KTest1, "Test 1");
iTest.Start(KTest1);
// Test 1
_LIT(KTest11, "Test 1.1");
iTest.Start(KTest11);
// Test 1.1
_LIT(KTest12, "Test 1.2");
iTest.Next(KTest12);
// Test 1.2
_LIT(KTest121, "Test 1.2.1");
iTest.Start(KTest121);
// Test 1.2.1
_LIT(KTest122, "Test 1.2.2");
iTest.Next(KTest122);
// Test 1.2.2
_LIT(KTest123, "Test 1.2.3");
iTest.Next(KTest123);
// Test 1.2.3
iTest.End(); // Test 1.2
iTest.End(); // Test 1
_LIT(KTest2, "Test 2");
iTest.Next(KTest2);
// Test 2
iTest.End();
I hope this article will give you an understanding how to create test harness using RTest class. There is another alternative to RTest, called Symbian OS Unit (see the link at the end of this article). It is an open source project, based on JUnit from Java.