Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] QTest framework: initialize data driven tests
Forum Updated to NodeBB v4.3 + New Features

[Solved] QTest framework: initialize data driven tests

Scheduled Pinned Locked Moved General and Desktop
8 Posts 2 Posters 6.0k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    andre
    wrote on last edited by VRonin
    #1

    I am using the QTest unit testing framework to unit test a class. I am using the data driven method like this:

    private slots:
    void test();
    void test_data();
    

    That makes sure that my test() method is called as many times as I have created cases in my test_data(). Nice.

    There also is an init() and an initTestCase() method that you can use for initialization. However, those are generic. The one is called before each test, the second only before the first test. However, in my case, I am trying to test an object that can be initialized in different ways. What I would like to do, is initialize the object, run a testcase on it (created in test_data()), and after the last test, destroy the object again to clean up for the next test.

    So, what I'd like to have is basically this:

    private slots:
    //test 1
    void test();
    void test_data();
    void test_init();
    void test_cleanup();
    
    //test 2
    void test2();
    void test2_data();
    void test2_init();
    void test2_cleanup();
    

    So basically, give each test its own init and cleanup functions, though I could do without the cleanup one I guess.

    I could prepend a special data point in the test data to trigger initialization inside the test() function itself, but that is a bit messy really. Any suggestions of better ways to do this?

    1 Reply Last reply
    0
    • T Offline
      T Offline
      tobias.hunger
      wrote on last edited by
      #2

      Why don't you just call test2_init() and test2_cleanup() from test() as needed?

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #3

        How would I know inside test2() if the case I'm testing from test2_data() is the first or the last one?

        1 Reply Last reply
        0
        • T Offline
          T Offline
          tobias.hunger
          wrote on last edited by
          #4

          I don't think you can know that.

          Are you really having one test case only if you need to know which data set you are currently testing?

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            The idea is that one test (wich has one data set) can test one configuration of the object. For that, I need to initialize the object for that test, and I'd prefer to do that once per test, not once per test data.

            Perhaps I could abuse test_data() to also do the initialization, but that would be relying on an undocumented order of calls to methods. For all I know, the framework first calls all _data methods and only then the actual tests.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              andre
              wrote on last edited by VRonin
              #6

              OK, I think I found a solution.

              In my declaration, I do this:

              private slots:
                  void init(); 
              
                  void test();
                  void test_data();
              
              protected slots: //any invokable method will do, except for private slots
                  void test_init();
                  void test_cleanup();
              

              Then I implement the init() slot like this:

              void DateParseTest::init()
              {
                  static QByteArray lastTestFunction;
              
                  if (!lastTestFunction.isEmpty() && strcmp(lastTestFunction.data(), QTest::currentTestFunction()) == 0)
                      return;
              
                  if (!lastTestFunction.isEmpty()) {
                      //we're going to run a new test, so run the test cleanup function of the previous test if it exists...
                      QByteArray cleanupMethod(lastTestFunction);
                      cleanupMethod += "_cleanup";
                      int index = metaObject()->indexOfMethod(cleanupMethod + "()");
                      if (index != -1) {
                          metaObject()->invokeMethod(this, cleanupMethod.data(), Qt::DirectConnection);
                      }
                  }
              
                  lastTestFunction = QTest::currentTestFunction();
              
                  //we're going to run a new test, so run the test init function if it exists...
                  QByteArray initMethod(QTest::currentTestFunction());
                  initMethod += "_init";
                  int index = metaObject()->indexOfMethod(initMethod + "()");
                  if (index != -1)
                      metaObject()->invokeMethod(this, initMethod.data(), Qt::DirectConnection);
              }
              

              That is: I abused the init() call that is executed before running each and every test case to manually call a cleanup and and init method if those exist.

              1 Reply Last reply
              0
              • T Offline
                T Offline
                tobias.hunger
                wrote on last edited by
                #7

                That should work, but I'd still just use the normal methods and split up the whole thing into different sets of unit tests.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #8

                  I think it makes sense to test a single class from a single test. Anyway, I filed a "suggestion":https://bugreports.qt-project.org/browse/QTBUG-25975 in Jira to add this to the framework.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved