jeudi 28 janvier 2016

How does one unit test all paths of a C++ sequence (single or multiple functions or classes)?

I am asking for a suggested implementation to test that a function, or a set of functions, followed a certain path. This will provide a reasonable way to check state and ensure errors are handled in the exact methodology desired and intended. I am looking for unit test framework independent discussion.

Suggestions?

I've sketched up a current concept as a starting point for thought.

Note: this example is extremely simplified. And looks like a trivial case, but it easily extends into more complicated checking.

Integer tracking of a code path in the example could be replaced with strings as desired, and it's pretty easy to get more extravagant from here, but I wanted to gather other's takes on what could be done, before continuing.

#include <QDebug>
#include <QtGlobal>
#include <QVector>

#define RUN_TEST

#ifdef RUN_TEST
#define inheritTestableOnly : public Testable
#define inheritTestableToo  , public Testable
#define appendCodePath(a) addCodePath(a)
#else
#define inheritTestableOnly
#define inheritTestableToo
#define appendCodePath(a)
#endif

class Testable
{
public:
    void addCodePath(qint64 newCode)
    {
        codePath.append(newCode);
    }

    void clearCodePath()
    {
        codePath.clear();
    }

    QVector<qint64> const & getCodePath() const
    {
        return codePath;
    }

private:
    QVector<qint64> codePath;
};




class ToTest inheritTestableOnly
{
public:
    ToTest(){}
    virtual ~ToTest(){}

    void testFunction(bool pathSelect1, bool pathSelect2)
    {
        bool pathSelect3 = false;

        if(pathSelect1)
        {
            if(pathSelect2)
            {
                appendCodePath(1);
            }
            else
            {
                appendCodePath(-2);
                pathSelect3 = true;
            }
        }
        else
        {
            appendCodePath(-1);
        }

        if(pathSelect3)
        {
            qDebug() << "Success!";
            appendCodePath(2);
        }
    }
};



int main(int argc, char *argv[])
{
    ToTest t;
#ifdef RUN_TEST
    t.testFunction(true, true);
    qDebug() << t.getCodePath();
    t.clearCodePath();
    qDebug() << t.getCodePath();

    t.testFunction(false, false);
    qDebug() << t.getCodePath();
    t.clearCodePath();
    qDebug() << t.getCodePath();

    t.testFunction(true, false);
    qDebug() << t.getCodePath();
    t.clearCodePath();
    qDebug() << t.getCodePath();
#else
    t.testFunction(true, true);
    t.testFunction(false, false);
    t.testFunction(true, false);
#endif

    return 0;
}

Output when RUN_TEST is defined:
QVector(1)
QVector()
QVector(-1)
QVector()
Success!
QVector(-2, 2)

Output when RUN_TEST is not defined:
Success!

Aucun commentaire:

Enregistrer un commentaire