Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Using slots in QTest - Test case or slot?



  • I am trying to build a test using qtest, to exercise my library which implements a class that wrapped QWebSocket.

    It looks like QTest will run every method under "private slots:" and thinks that it is test init, cleanup, or a test case.

    However, I am also trying to bring up a server on localhost with which to connect to and that requires slots to be called back when the listener accepts a connection and closes, etc.

    QTest wants to treat those callbacks as test cases, and runs them, which is not correct. How do I tell it "these are slots for your test cases" and "these are slots that are used elsewhere?"

    Consider this test code:

    
    #include <QCoreApplication>
    #include <QtTest>
    #include <QtWebSockets/qwebsocket.h>
    #include <QtWebSockets/qwebsocketserver.h>
    #include <string>
    
    class qtwebstompclientimpl_tests : public QObject
    {
        Q_OBJECT
    
    public:
        qtwebstompclientimpl_tests();
        ~qtwebstompclientimpl_tests();
    
    private slots:
        void initTestCase();
        void cleanupTestCase();
        void onAccept();                 // Wants to run these as test cases, but they are actually slots for QWebSocketServer
        void onAcceptError(QAbstractSocket::SocketError socketError);
        void onTextReceived(QString message);
        void onClientClosed();
        void test_case1();
    
    private:
        QWebSocketServer * m_webSocketServer;
        QWebSocket * m_connectedWebsocketClient;
        bool m_errorOccurred;
        QString m_lastMessage;
    };
    
    qtwebstompclientimpl_tests::qtwebstompclientimpl_tests() {}
    
    qtwebstompclientimpl_tests::~qtwebstompclientimpl_tests() {}
    
    void qtwebstompclientimpl_tests::initTestCase()
    {
        m_webSocketServer = new QWebSocketServer("Test Server", QWebSocketServer::NonSecureMode);
        if( !m_webSocketServer->listen(QHostAddress::Any, 5000) )
        {
            std::string errorMessage = m_webSocketServer->errorString().toStdString();
            throw std::runtime_error("Failed to setup test websocket server - Listen failed");
            connect(m_webSocketServer, &QWebSocketServer::newConnection, this, &qtwebstompclientimpl_tests::onAccept);
            connect(m_webSocketServer, &QWebSocketServer::acceptError, this, &qtwebstompclientimpl_tests::onAcceptError);
        }
    
        m_connectedWebsocketClient = nullptr;
        m_errorOccurred = false;
    }
    
    void qtwebstompclientimpl_tests::cleanupTestCase()
    {
        if( m_connectedWebsocketClient )
        {
            delete m_connectedWebsocketClient;
        }
        delete m_testClient;
        delete m_webSocketServer;
    }
    
    void qtwebstompclientimpl_tests::onAccept()
    {
        if(m_connectedWebsocketClient)
        {
            m_connectedWebsocketClient->close();
        }
    
        m_connectedWebsocketClient = m_webSocketServer->nextPendingConnection();
    
        connect(m_connectedWebsocketClient, &QWebSocket::textMessageReceived, this, &qtwebstompclientimpl_tests::onTextReceived);
        connect(m_connectedWebsocketClient, &QWebSocket::disconnected, this, &qtwebstompclientimpl_tests::onClientClosed);
    }
    
    void qtwebstompclientimpl_tests::onAcceptError(QAbstractSocket::SocketError socketError)
    {
        m_errorOccurred = true;
    }
    
    void qtwebstompclientimpl_tests::onTextReceived(QString message)
    {
        QWebSocket * client = qobject_cast<QWebSocket *>(sender());
        if(client == m_connectedWebsocketClient)
        {
            m_lastMessage = message;
        }
    }
    
    void qtwebstompclientimpl_tests::onClientClosed()
    {
        QWebSocket * client = qobject_cast<QWebSocket *>(sender());
        if(client == m_connectedWebsocketClient)
        {
            m_connectedWebsocketClient->deleteLater();
        }
    }
    
    void qtwebstompclientimpl_tests::test_case1()
    {
        QVERIFY(true);
    }
    
    QTEST_MAIN(qtwebstompclientimpl_tests)
    
    #include "qtwebstompclientimpl_tests.moc"
    
    

  • Lifetime Qt Champion

    Hi,

    Only the private slots are considered test cases, you can either use publics slots, or depending on what you do, a helper class might be cleaner.



  • Here is a worse problem.

    The slots I want to test don't ever get called. I assume because I am already in a slot, which is the test case itself. Therefore I can never test if my websocket client connects, because its slots won't get called to accept a connection.

    QSignalSpy was suggested to me, and it looks like I can examine signals with it, but I still have a problem, in that, QtWebSocket doesn't seem t emit the signal for receiving data, error, etc when its not even connected, and it will never get connected, because the onAccept slot will never be called.

    Not sure how to test this socket code at all beyond just creating a manual test tool. It would be really nice to have some kind of automated tests.

    Am I wrong in my understanding?



  • Solved by using qWait along with the suggested movement of other slots to public scope.


Log in to reply