Test
In the process of application development, testing is very important. Testing requires checking by repeating, and it is a boring process. For this reason, it might be very useful to automate this process.
Unit Test of the Model
In this session, we will try to check if the model works the right way. The test framework follows TestLib attached by Qt (please check out the documentation for more details).
Let’s test the Blog model code that we made in the tutorial. Make a common library for the model in advance. At first, we will create a working directory in the test directory.
$ cd test
$ mkdir blog
$ cd blog
We will try to create the test case for creating and reading of the Blog model.
For example, let’s set the name of the implementing test as follows: TestBlog. The source code with the following content is saved as a file named testblog.cpp.
#include <TfTest/TfTest>
#include "models/blog.h" // include the model class
class TestBlog : public QObject
{
Q_OBJECT
private slots:
void create_data();
void create();
};
void TestBlog::create_data()
{
// definition of test data
QTest::addColumn<QString>("title");
QTest::addColumn<QString>("body");
// adding to test data
QTest::newRow("No1") << "Hello" << "Hello world.";
}
void TestBlog::create()
{
// acquisition of test data
QFETCH(QString, title);
QFETCH(QString, body);
// logic of the test
Blog created = Blog::create(title, body);
int id = created.id();
Blog blog = Blog::get(id); // Getting model ID
// verification of result execution
QCOMPARE(blog.title(), title);
QCOMPARE(blog.body(), body);
}
TF_TEST_MAIN(TestBlog) // specify the class name you created
#include "testblog.moc" // charm. Make the extension .moc
As supplemental comment, among this, create() method can do the test, and QCOMPARE macro can check the real returning value. The create_data() method works as passing test data to the create_data() method. The rule is always to put ‘_data’ at the end of the method name.
In this example, I am doing the following in create_data() method.
- QTest::addColumn() function: Define the name and type of test data.
- QTest::newRow() function: Add test data.
The following is done in the create() method.
- Fetch the test data.
- Run the test logic.
- Verify that the result is correct.
Next, create a project file to make the Makefile. The file name is testblog.pro, saving the contents as the following.
TARGET = testblog
TEMPLATE = app
CONFIG += console debug c++14
CONFIG -= app_bundle
QT += network sql testlib
QT -= gui
DEFINES += TF_DLL
INCLUDEPATH += ../..
LIBS += -L../../lib -lmodel
include(../../appbase.pri)
SOURCES = testblog.cpp # Specifying the file name
After you save the project file, you can create a binary by running the following command in its directory:
$ qmake
$ make
Next, some little configuration needs to be done for the testing process.
Because of the need to refer to the various configuration files, the test command requires a symbolic link to the config directory. Its location should be directly below of the test command. When SQLite is used for the database, we need to make a symbolic link to the db directory as well.
$ ln -s ../../config config
$ ln -s ../../db db
If you use Windows, an exe file of the test is created in the debug directory, so that a symbolic link is created there. Please be careful: it is NOT a shortcut! To create a symbolic link, you must run the command from the command prompt launched with administrator privileges.
> cd debug
> mklink /D config ..\..\..\config
> mklink /D db ..\..\..\db
Furthermore, take the path to the common library including the Blog model.
In the case of Linux, set the environment variable as follows:
$ export LD_LIBRARY_PATH=/path/to/blogapp/lib
If you use Windows, add the setting to PATH variables like this:
> set PATH=C:\path\to\blogapp\lib;%PATH%
Then check the connection information for the database. In the unit test, the connection information in the test section in the database configuration file (database.ini) is used.
[test]
DriverType=QMYSQL
DatabaseName=blogdb
HostName=
Port=
UserName=root
Password=
ConnectOptions=
The configuration is now complete. Next, the test needs to be executed. If the test was a throughout success, you can see the following message on the screen:
$ ./testblog
Config: Using QtTest library 5.5.1, Qt 5.5.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.4.0 20160609)
PASS : TestBlog::initTestCase()
PASS : TestBlog::create(No1)
PASS : TestBlog::cleanupTestCase()
Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestBlog *********
In the case of Windows, please execute the test on the TreeFrog Command Prompt.
If, however, the result is not what was expected, you will see the following message.
********* Start testing of TestBlog *********
Config: Using QtTest library 5.5.1, Qt 5.5.1 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 5.4.0 20160609)
PASS : TestBlog::initTestCase()
FAIL! : TestBlog::create(No1) Compared values are not the same
Actual (blog.body()): "foo."
Expected (body): "Hello world."
Loc: [testblog.cpp(35)]
PASS : TestBlog::cleanupTestCase()
Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted
********* Finished testing of TestBlog *******
Make a test case for each each model. Then please do the test. The key to a good Web application development is to be sure that the model is working properly.