MissingUnitTests

    From The Document Foundation Wiki

    ignored bugs

    100285 100342 101363 107197 108523 114175 118161 130428 130977 131147 131907 135457 136620 136708 138223 145621 38831 39674 43135 47222 49052 56983 65082 70143 77307 80748 85486 88826 89500 89756 93240 94205 94814 97087 97667 54094 128437 33365 34355 77388 121111 129808 163006

    Writing a test for a fix listed on this page

    Finding a suitable bug

    Not all bugs and bug reports are created equal, so finding a good candidate is crucial to successfully writing a test. Here are some things to think about when looking through bug reports.

    1. Find a bug that is obvious to see, a trivial example of this is a bug that causes LibreOffice to crash. It should be obvious to test for a crash, versus testing for a subtle layout issue.
    2. Look for a bug report that is either very new, or where the bug fix is a limited number of lines of code.
    3. Look for clear steps to reproduce the bug.
    4. It is helpful if the bug fix is confirmed in the bug report. If there is no confirmation, the first thing you should do is run LibreOffice and use the steps listed in the bug report to make sure that the bug is indeed fixed.

    We are going to use the bug report from tdf#61000 as an example to go through the process of writing a test from the list.

    Looking at the top comment, you can see that the bug is causing LibreOffice to crash when the attached file is opened. There are clear steps to reproduce the bug in comment 1, and the bug has been confirmed in comment 3.

    Reverting the bug fix

    Using the commit found in comment 8 of the bug report, we can use git to show the bug fix.

    git show dbb74ee9950dc706ea4fde3397a4c1d19b172fa9
    
    commit dbb74ee9950dc706ea4fde3397a4c1d19b172fa9
    Author: Michael Stahl <mstahl@redhat.com>
    Date:   Wed Feb 27 23:20:24 2013 +0100
    
    fdo#61000: writerfilter: filter out unsupported list tab stops
    
    Change-Id: Ic9d31eba84b1d8d9cf93d8289621a65d43521a8b
    
    
    diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx
    index fa59bd2c7062..38b1f07a1c9d 100644
    --- a/writerfilter/source/dmapper/NumberingManager.cxx
    +++ b/writerfilter/source/dmapper/NumberingManager.cxx
    @@ -135,7 +135,13 @@ void ListLevel::SetValue( Id nId, sal_Int32 nValue )
    m_nXChFollow = nValue;
    break;
    case NS_ooxml::LN_CT_TabStop_pos:
    -            m_nTabstop = nValue;
    +            if (nValue < 0)
    +            {
    +                SAL_INFO("writerfilter",
    +                        "unsupported list tab stop position " << nValue);
    +            }
    +            else
    +                m_nTabstop = nValue;
    break;
    default:
    OSL_FAIL( "this line should never be reached");

    If you try to look for the file from the path listed in the commit, you will not find it. When looking at old commits this can happen, sometimes files get moved, so we can search for the relevant function with git grep -n "ListLevel::SetValue" to get

    sw/source/writerfilter/dmapper/NumberingManager.cxx:103:void ListLevel::SetValue( Id nId, sal_Int32 nValue )

    which shows us that the function in question now resides in sw/source/writerfilter/dmapper/NumberingManager.cxx.

    Even though git revert --no-commit can not be used in this case due to the different path, we can see that reverting the bug fix is nevertheless straight forward. The lines that were added can be commented out and the original line that was deleted can be added back to the code.

    Having found the correct file to edit, we get

    break;
            case NS_ooxml::LN_CT_TabStop_pos:
                m_nTabstop = nValue;
                //if (nValue < 0)
                //{
                //    SAL_INFO("writerfilter",
                //            "unsupported list tab stop position " << nValue);
                //}
                //else
                //    m_nTabstop = nValue;
            break;
            default:
                OSL_FAIL( "this line should never be reached");

    Compile and test

    The next step is to build with the bug fix reverted and test that the bug is now present. Testing for the bug is simple in this case, just download attachment 1 from the bug report and try to open it with the bug fix reverted.

    Once we are sure the bug is reintroduced, it is a good idea to create a branch in git and commit the revert. In this way, you will be able to switch between having the bug present, and not present. Once you have your top commit as the bug fix revert, you can use git checkout HEAD~1 to go back one commit, where the bug is fixed and git switch - to go back to the bug being reintroduced. In this way you can easily and quickly switch the behavior of LibreOffice in order to ensure your test is working correctly.

    Deciding on a location for the test

    Now we need to decide where our test will reside. Since the bug shows up when using Writer, we will look in sw/qa/extras

       accessibility  globalfilter  mailmerge    pdf             tiledrendering2  unowriter
       autocorrect    htmlexport    odfexport    README          txtencexport     ww8export
       data           htmlimport    odfimport    rtfexport       txtexport        ww8import
       docbookexport  indexing      ooxmlexport  rtfimport       txtimport
       fodfexport     layout        ooxmlimport  tiledrendering  uiwriter
    

    The README file is very helpful here, anyone writing a test is encouraged to read it as it contains a lot of helpful information. When deciding where to put a test, a few ideas to keep in mind are:

    1. Take note of the file or area of files the bug fix resides in. In this case, source/writerfilter is a clue that this is an export bug.
    2. What file type are we dealing with? A problem opening up a .docx file would suggest that the test may go in ooxmlexport.
    3. Look for similar tests. Sometimes it can be helpful to look through some of the test suites to see if there are other similar tests.

    In this case we’re dealing with a crash when opening a .docx file. This points to ooxmlexport as a good place to put the test.

    Writing and executing the test

    The last part of the process is to actually write the test. In order to test for a crash, we just open the file and see if LibreOffice crashes.

    CPPUNIT_TEST_FIXTURE(Test, testTdf61000)
    {
        // Without the fix in place this crashes on opening
        loadAndSave("tdf61000.docx");
        xmlDocUniquePtr pXmlDoc = parseExport(u"word/numbering.xml"_ustr);
        assertXPath(
            pXmlDoc,
            "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:numFmt"_ostr,
            "val"_ostr, u"bullet"_ustr);
        // Without the fix in place, this would be -540, and the abstractNumId is 4
        // The negative value of the tab stop is the culprit for the crash
        assertXPath(
            pXmlDoc,
            "//w:numbering/w:abstractNum[@w:abstractNumId='1']/w:lvl[@w:ilvl='0']/w:pPr/w:tabs/w:tab"_ostr,
            "pos"_ostr, u"0"_ustr);
    }

    We use loadAndSave to open the file since this is an export test, then we do some checks on the document model using assertXPath. To learn more about using assertXPath you can look in the README file located in sw/qa/extras/README.

    Once the test is written and it fails with the bug fix reverted, you can switch back to a state where the bug is fixed and run the test again.

    If it now passes, you’ve successfully written a test!

    You would now submit the test as a patch to Gerrit.

    For more information about writing tests check out the main article.