Udvikling/Tests med Cpp Unit

From The Document Foundation Wiki
Jump to: navigation, search
This page is a translated version of the page Development/Cpp Unit Tests and the translation is 100% complete.

Other languages:
dansk • ‎English • ‎日本語

CppUnit

LibreOffice bruger CppUnit-rammen til sine afprøvninger af C++-enheder. CppUnit is a C++-port til JUnit-rammen og er blevet forgrenet flere gange. LibreOffice vedligeholder sin egen forgrening af CppUnit, som i dag er den sidste aktive forgrening.

Typer af enheds-tests i LibreOffice-koden

Der er mange typer af enhedstest i LibreOffice. Hvis du er usikker på, hvilken du skal bruge, spørg venligst på postlisten LibreOffice development eller på IRCen - se "Talk to developers" på https://www.libreoffice.org/community/developers/ .

Test en funktion/metode

Tag funktionen/metoden og fød den med forskellige data og vurder, om resultatet er korrekt.

Eksempel: test::oustring::StringConcat::checkConcat()https://cgit.freedesktop.org/libreoffice/core/tree/sal/qa/rtl/strings/test_oustring_concat.cxx#n57

Import-test

Til en import-test er to ting nødvendige:

  • et test-dokument - en minimeret version af det dokument, som viste fejlen for første gang. Det er bedst, hvis du kan genskabe dokumentet helt forfra for at undgå fortrolige data i det. Tjek lignende tests på det sted, hvor dokumentet skulle gemmes, sædvanligvis er det i en 'data/'-undermappe.
  • selve testen

Import-testen indlæser så dokumentet som det første, og derefter vurderer du, præcist hvlken egenskab, der blev rettet.

Eksempel: testFdo50665https://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/rtfimport/rtfimport.cxx#n606

Eksport-test

Eksport-testen udvider import-testen ved faktisk at gen-importere to gange:

  • første gang bliver dokumentet læst, og så gemt med det filter, vi vil teste, og
  • anden gang bliver det gemte resultat indlæst igen for at vurdere, om lagringen blev udført korrekt.

Vurderingen af det gemte resultat kan gøres på samme måde som i import-testen (se ovenfor) eller ved at bruge assertXPath-metoden (se nedenfor).

Ekswmpel: testDMLSolidfillAlphahttps://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx#n115

assertXPath-test

I mange tilfælde arbejder vi på XML:

  • ODF og OOXML er XML i en indpakning
  • vi dumper data som XML (med forskelligt debugging-output - som Writer layout-dumpet, EMF/WMF-struktur, XShapes osv.)

Tricket er så at indlæse data som DOM og vurdere forskellige egenskaber gennem et XPath-udtryk.

Eksempel: testBehinddochttps://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx#n610

EMF/WMF-eksempler: https://cgit.freedesktop.org/libreoffice/core/tree/emfio/qa/cppunit/wmf/wmfimporttest.cxx

Enheds-tests dumper et bitmap og resultatet vurderes

EMF+ gemmes i EMF-kommentarer og gengives senere. For at være i stand til at teste dette er det nødvendigt at dumpe det som et bitmap og vurdere, om de forskellige pixels har de rette værdier.

For at dumpe bitmappet først (for at se, hvad du helt præcist vil vurdere) eksporterer du CPPCANVAS_DEBUG_EMFPLUS_DUMP_TO=/tmp/file.png , og bitmappet bliver gemt i /tmp/file.png , når du udfører enhedstesten.

Eksempel: https://cgit.freedesktop.org/libreoffice/core/tree/cppcanvas/qa/extras/emfplus/emfplus.cxx

Layout dump-test

Dette er specifikt for Writer. I nogle tilfælde er det nødvendigt at teste, hvordan dokumentet blev lay-out'et af lay-out-motoren - fx. skulle noget tekst vises på 3. side, mens det tidligere er blevet vist på anden siden og lignende.

Disse tests virker sådan, at filen importeres og layoutet derefter dumpes som XML.

Eksempel: testFdo52052https://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/rtfimport/rtfimport.cxx#n755 .

XShape-test

Denne kan let bruges i chart2 eller Impress. Visningens struktur (det er det, der præsenteres somXShapes hierarki) dumpes som XML, og sammenlignes derefter enten med et reference-dump (mindre pålideligt - da dump-metoden kan ændres i fremtiden) eller tjekkes med assetXpath (den nye metode).

Eksempel (reference): Chart2XShapeTest::testFdo75075()https://cgit.freedesktop.org/libreoffice/core/tree/chart2/qa/extras/xshape/chart2xshape.cxx#n80

Eksempel (assertXPath): Chart2XShapeTest::testTdf76649TrendLineBug()https://cgit.freedesktop.org/libreoffice/core/tree/chart2/qa/extras/xshape/chart2xshape.cxx#n144

Komplekst scenarie-test

Det kan ske, at en fejl har brug for adskillige trin for at kunne reproduceres. Selv det kan testes, når proceduren er pålidelig.

I disse tilfælde er det sædvanligvis en import-test med yderligere trin, som skal gøres - som at markere tekst og udløse en reaktion på det, osv.

Eksempel: testFdo37606Copyhttps://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/odfimport/odfimport.cxx#n477

LibreOfficeKit (LOK)-test

Nogle funktionaliteter (som at trykke på en tast som om det var et rigtigt tastatur-input) er mulige gennem LibreOfficeKit API, men ikke gennem UNO eller det interne API (fx. fordi SwEditWin i Writer ikke er en 'public class' set fra et synlighedssynspunkt).

Hvis du vil bruge det, skal du få fat i oversigt over implementeringen af UNO-objektet, som repræsenterer et dokument. Derefter kan du kalde dets element-funktioner direkte.

Ekssempel: testTdf89954https://cgit.freedesktop.org/libreoffice/core/tree/sw/qa/extras/uiwriter/uiwriter.cxx#n2047

Hastighedstests

Disse tests udføre som del af make perfcheck. De kræver, at valgrind-dev-pakken er installeret. De generer log-filer i workdir/CppunitTest/[testname]/.., som inddeholder valgrind-log-fier..

De kan behandles til at producere en summmarisk CSV-fil med bin/parse-perfcheck.py

Eksempel: sc/qa/perf/scperfobj.cxx

Tilføj en ny test

I nogle tilfælde er enheds-testenes infrastruktur endnu ikke introduceret. I disse tilfælde find venligst inspiration på områder, som har masser af enheds-tests, og opret den nye test på denne måde.

Definer test-klassen

Testene skal placeres i undermappen qa/ i en fil med navnet test_xxx.cxx. Først skal du oprette din test-klasse. Her følger et muligt, grundliggende test-skelet:

// copy here a header from the file TEMPLATE.SOURCECODE.HEADER in the root of the source tree.

#include "sal/config.h"
#include "sal/precppunit.hxx"

#include "cppunit/TestAssert.h"
#include "cppunit/TestFixture.h"
#include "cppunit/extensions/HelperMacros.h"
#include "cppunit/plugin/TestPlugIn.h"

namespace
{
/**
 * Perform tests on MyClass.
 */
class MyClassTest : public CppUnit::TestFixture
{
private:
    /**
     * Tests capability Foo of the class.
     */
    void testFoo();

    // Adds code needed to register the test suite
    CPPUNIT_TEST_SUITE(MyClassTest);
    // Declares the method as a test to call
    CPPUNIT_TEST(testFoo);
    // End of test suite definition
    CPPUNIT_TEST_SUITE_END();
};

void MyClassTest::testFoo()
{   
    CPPUNIT_ASSERT(true); // do the tests here
}

// Put the test suite in the registry
CPPUNIT_TEST_SUITE_REGISTRATION(MyClassTest);

} // namespace
CPPUNIT_PLUGIN_IMPLEMENT();

Skriv en eller flere test-funktioner og test klassens forskellige potentialer. Find flere oplysninger om at teste med CppUnit iCppUnit-øvelser .

Kør test under bygningen

Nu din test-klasse er færdig, skal du kompilere og køre den. Derfor opretter du filen CppunitTest_module_test.mk (erstat modul- og test-navn med det passende) på øverste (komponent) mappeniveau, hvis det ikke allerede eksisterer.

# copy here a header from the file TEMPLATE.SOURCECODE.HEADER in the root of the source tree.

$(eval $(call gb_CppunitTest_CppunitTest,module_test))

$(eval $(call gb_CppunitTest_add_exception_objects,module_test, \
module/qa/cppunit/test_xxx \
))

# add a list of all needed libraries here
$(eval $(call gb_CppunitTest_add_linked_libs,module_test, \
sal \
$(gb_STDLIBS) \
))

$(eval $(call gb_CppunitTest_set_include,module_test,\
$$(INCLUDE) \
-I$(OUTDIR)/inc \
))

Du skal også redigere Module_module.mk og tilføje følgende (eller tilføje det på listen, hvis den allerede findes):

$(eval $(call gb_Module_add_check_targets,module,\
     CppunitTest_module_test \
))

For at bygge og køre testene, kører du simpelthen make check. hvis bygget lykkes, kører testene automatisk.

Så, når dine tests kører, er alt, du skal gøre at rette de fejl, de afslører.

Kør en enkelt test ad gangen

CPPUNIT_TEST_NAME er den miljø-variabel, som skal sættes og indeholde testenes navn. Test-navne skal være fuldt kvalificerede for at blive genkendt.

Eksempler:

CPPUNIT_TEST_NAME="ScFiltersTest::testOutlineODS ScFiltersTest::testRangeNameXLS" make CppunitTest_sc_subsequent_filters_test

CPPUNIT_TEST_NAME="ScFiltersTest" make CppunitTest_sc_subsequent_filters_test