 Hi everyone, this is Chisco Fabuli and today I'm going to talk about how to write your first test for LibreOffice. I hope everyone is safe and doing okay. And yeah, let's get started. So a little bit about me. Yeah, I've been working for the Document Foundation for the last four years as a keyway engineer and I find unit tests are really important and a crucial part of the project and of any project in general. So yeah, the motivation for this talk I extracted this from a talk Kohei gave in a conference. So Kohei was a calc developer and he was talking about a refactor he did in calc and then he ended the talk saying that well a bug fix with our unit test will get broken again in the future and then a bug fix with a unit test will remain fixed forever. So the question is which one would you choose and the answer is obvious. We should always go for writing a unit test when possible. So yeah, regarding this talk I'm going to talk about two main topics. The first one is how to write your unit test in Python, which are mainly used for testing the UI and how to write your test in CPP unit test. I'm going to explain how to use it for testing the import and export of different formats how to use assert xpath for testing XML and then how to test the layout of a document. So yeah, the prerequisites for someone who is interested in writing a first unit test well obviously you need the LibreOffice source code downloaded in your computer then you also need some knowledge in Python and C++ some like basic knowledge should be enough and the same goes for Git. We use Git as a version control so then you need some basic knowledge to get along and yeah, you also need an accounting unit which is the platform we use to review patches so if you write your unit test then you submit it to Git and someone else will review it and last but not least you need desire to learn and I can tell you that if you write unit test you're going to learn a lot. Yeah, and a disclaimer about this talk I'm going to focus mainly on writer test although if you want to write unit test for other modules like Calculus Impress the same principles apply, it shouldn't be much different but yeah, this talk is about writing mainly. So let's start with Python UI testing so some information about it, it was written or implemented by Marcus Mohan four or five years ago and it inherits from the unit test.testcase framework which is the one on the standard in Python so anything that you use in that framework you can use it in the UI testing framework so let's say any asset you have in that framework you can use it in the UI testing framework and as the name says well it's mainly used for testing the UI at the moment we have 600 existing tests and in writer they are under SWQA UI test so let me show you so I have my LibreOffice source built here so in SWQ in QA we have everything related to QA and then in the child directory UI test we have everything related to UI testing and the same goes if you instead of SWQ you change it to SC which is calc, you have the same and the same for Impress there are not many but yeah so one disadvantage of the Python UI testing is that they run slower than CPP unit test so when possible it's always desirable to use CPP unit test and another disadvantage is that it only runs on Linux so if you want to or either if you work on Windows or if you want to implement a test for a bug that is only happening on Windows a UI bug then you cannot do it yeah and then if you have or if you want more information more detailed information about UI test everything is in this URL so yeah let's write our first UI test let me check if everything is recording on the time 5 minutes so first of all I'm going to write a UI test for you and I'm going to show you how to do it from scratch so before we write anything we are going to call or execute LibreOffice with this variable here which is going to allow us to record everything we do in the UI so basically what we are saying is that okay I want to collect all the UI information in this document so let me show you real quick so now I'm executing LibreOffice with that variable I close the navigator so let's say I want to insert the table and now I change something here so I click on this text box and then I say Ctrl A I delete this and I use a new name which is my table and then I insert it and I have a table here so finally I close LibreOffice and now I have everything locked here so let me copy this so basically what we are doing so I close the navigator here so we are not going to use this so basically what I did was to insert the table then a dialogue open then I type in the element name edit I type Ctrl A then backspace and then I wrote my table finally I click on OK in the insert table dialogue and then I created a table and yeah I close LibreOffice so once we have this lock we can translate this into Python code and for that I already have this test created because I don't have much time for this talk so I'm going to explain you every step and yeah you're going to see it's really simple so basically I have a class which I can name it with any name I want I call it force them and then it is from UI test case and then I have the function which must start with test underscore and then the name of the function so in this case I call it insert table but I could call whatever one and yeah then we start the test by creating a doc in a star center so in this case we are creating a writer doc but I could also say instead of writer I can call it calc calc or impress or whatever so yeah we already have a writer document created and now what we are going to do is to execute a dialogue through command which is the insert table which is this one here so we execute that unicomand and we open the dialogue and once we open the dialogue we use this function to get the top focus windows which is at the moment the insert table and we put it in this variable which is x dialogue now what's next we use control A and then backspace and then we write my table so for that I get the element which is named it so I can say okay x dialogue, get style, name it I put it in this variable and then I execute the action which is type we see here type and then key code, control A backspace, my table so at this point we already have we change the text box which was first it was table one and we changed it to my table so once we done with that we click on the okay element and finally we close the dialogue with this element so now we are back to the document so we can get the document and analyze it so we use this get component to get the document and finally we can assert that the document has indeed one table which is here and then we can assert the table the first table the name of it is my table so let me execute this test and for that we have this little script which you can find here in this URL so basically you just have to tweak it a little bit to point to your own LibreOffice build and then change the file parameter so in this case the name of my test is test one so if we execute this one we can see that now it launch LibreOffice it opens right there it opens the dialogue and then it change it change the name and then it inserts the table that's really quick so for that we can use some time some time slip for instance we open the dialogue here then we change the name of the table and finally we insert it in the document so now if we execute it again now it pauses a little bit it changes the name now we insert the table and finally it closes LibreOffice so that's how UI tests are written pretty straightforward and we can for instance once we open the dialogue we can say ok print which is here some useful prints when working with UI tests so for instance if I want to see the children of the dialogue I can use xDialog the children so if I execute it again time here but yeah I see all these elements in the dialogue so we have for instance the ok button hell button the warning name did so these are all the elements in the dialogue so then we can use if we want to change for instance the number of rows we can use this one here so yeah you just need to check which one you need to use and use that one so another interesting print that we can use it's so once we have the child we can use get state as dictionary it's name edit so now we can see all the states of an element so here this is the name edit element so for instance we see the id but then we see that it's visible we see the text of it which is the property text which is table one at the moment nothing is selected so yeah for instance we can use it like in here before we change the name textbox and we write anything we can assert that by default the text is table one and finally another interesting print is to use there in a document and the text tables let's get the first one so if I execute it again now we see that a lot of information so we have all these properties in a document so we can get the auto styles or world count or whatever we want to get text frames, text fields we can use it to get anything in a document and here we see the properties of a table so anchor text wrap, whatever we want to use so this is the way we check the properties of a document while we are writing UI test so yeah, 17 minutes so yeah let's move on now we are going to write a cpp unit test so in writer they are under this folder and yeah, for instance for oddity we use it swqa extras, odf import and the layout so it's very once you are in swqa extras you can see by the name of the folder what the test in those folders are about at the moment we have around 3000 existing tests you have a lot of detailed information in the readme and also in this url so the way because for the UI test you can run the test and visualize what's going on and here you can't so you have to use the make of the module, so for instance if you are writing a test in OOXML export 16 then you can use this command here or if and this will run all the test in that module and then if you want to run a particular test you can use you can indicate the name of the test like this one here and then the name of the module so yeah for import and export we have three kind of cpp unit test we have the import test that load the specific file to a mx component which represents a UNO model of the document then we have the export test which basically do the same than same as the import test but they first import the document then they export the document and then they re-import the document again and finally we have the export only test which only export the document yeah so let me show you real quick how to write cpp unit test for import and export so let's say I have a new document and I want to test for instance that when we export this document to let's say docx the text is still for them so I have this the quality and for instance I can insert an image so now I want to write it this is going to I'm going to test that it's an export test so I'm going to extras and I'm exporting this to docx so OOXML export and then here we have all the modules so I'm going to use export 16 which is the last one so I can copy this one for instance paste it here and now I say the name of the test is going to be first them and then the name of the document is first them oddity so I want to check that there is one shape in the document for instance so I can say get shapes the number of shapes is one and I want to test that the first paragraph it's first them so for that I can and the pages for example one page, there is one page in the document and also the first paragraph it's first them so for that I can say it's first them and here I get paragraph one and then get a string I delete this and now I'm going to execute this test first them so let's change it so it's going to fail let's I hope it works 23 minutes and it's taking a while and yeah now it's my computer is not super fast so yeah and it fails because 43 oh yeah I didn't the document I created I didn't put it extras OXML export data and it's called first them so now if I execute it again sorry I had a previous document without an image that's why it's failing here so it's expecting one shape or one image and it didn't work because there are zero in my previous document if I execute it again now yeah it says it's expecting first them it's expecting X first them and the paragraph it's first them so I should if I change this here then it should pass but yeah let's move on because I have 5 minutes left or less and yeah for the AssetX path so here we are using cppunitest AssetEquival if I AssetX xpath okay let me show you another AssetX so here what we are doing it's a okay I'm importing this document then I export in it so in this case I'm exporting only so this is an only export test and then I pass the export I put it in this variable and then I pass the variable this is how the XML looks like and this is what I'm inserting so how to get this so one way of doing that so let's say I have a document so I'm going to choose this one for them and now I change this and I say let's change the answer whatever I change it to first them first them with bold letters and I change it to first them to so now I can use one tool you have some of the tools to analyze the documents here so one of them is oddif so these tools allows me to div the two documents so I'm going to test the first document without the bold letters and the second with the bold letters so yeah this is information about the generator and here yeah there is one image another that is not there another document without an image but yeah with that I see here for instance that in one document we have this is a text style we have first them and in the other one we don't have it we also don't have the image so then we can use this XML two parts which is an asset that for instance the document is there so this is one way to use XML passing and finally if we want to yeah so if we want to test the layout we have this so okay now so now I have this document here which I can open and now I have the layout as an XML document and yeah that's 30 minutes and then you can also assert its path the document so some useful information if you want to write your first test today you can have it you have a list of missing python UI test here and the same for the CPP unit test here and thank you for watching and hope you write your first unit test you are not going to regret bye bye