<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        
                                        
                                            
                                        
                                        
                                        Hi all. Raoul asked me to chime in on this conversation about moving to pytest fixtures. <div><br></div><div>I ran into a whole bunch of segfaults when running the TestOpenLP test class. (tests/functional/openlp_core/test_app.py) Raoul's link #4 is a link to my merge request that ran into this issue. <span style="font-size: 10pt"><a href="https://gitlab.com/openlp/openlp/merge_requests/19#note_224757584">this gitlab comment</a> and the containing thread have a more thorough explanation of the issue and some ideas about what might be causing the segfaults.</span><div><br></div><div>The main idea behind pytest fixtures is very similar to the existing setUp and tearDown method overrides on the TestCase class. They essentially provide a method for setting up and tearing down the environment and required objects for a particular test. The practical upshot of using pytest fixtures instead of the setUp and tearDown methods is that they are the 'official' pytest way of setting up and tearing down tests and I have found that pytest has far better failure messages when running a 'pytest' test versus a 'unittest' test.</div><div><br></div><div>I had a branch with the TestOpenLP class rewritten to use pytest fixtures that passed all tests locally. So it is completely doable given enough time. H<span style="font-size: 10pt">owever, I did run into the segfaults when I started rewriting more of the tests to use pytest fixtures. The linked merge request touches on this issue a bit. </span></div><div><span style="font-size: 10pt"><br></span></div><div><span style="font-size: 10pt">The basic problem is that the QApplication object is only meant to be instantiated once for the lifetime of the application, which is what happens during the normal execution of OpenLP, but during testing, the QApplication is created and destroyed many times and references to the object may not always be torn down between tests. I personally suspect (though I have not had a chance to fully investigate) that the Settings object or some of the singleton objects may be keeping references to the QApplication object. </span><span style="font-size: 13.3333px">(for instance, I know that the Registry singleton is explicitly given a reference to the QApplication object and I don't think the Registry object is destroyed between tests). This makes it very difficult to pinpoint the actual point of failure for a test because the point of failure may be caused as a side effect of another test failing to tear the environment down properly. (i.e. one that initialized the Registry and gave it a QApplication reference, but did not reset the Registry).</span></div><div><span style="font-size: 13.3333px"><br></span></div><div><span style="font-size: 13.3333px">I'm not sure what to do about this underlying problem.</span></div><div><span style="font-size: 13.3333px"><br></span></div><div><span style="font-size: 13.3333px">The migration to pytest fixtures, if done carefully, might be able to help solve the QApplication object's problems. (As an important note, the QAppplication problem only arises in the tests as a side effect of running multiple tests with new/shared QApplication object instances. It does not occur in the regular execution of OpenLP because only one QApplication object is ever created.)</span></div><div><span style="font-size: 13.3333px"><br></span></div><div><span style="font-size: 13.3333px">A potential solution could be to manage some of the singleton classes differently. This would cut down on the potential for references to leak between tests.</span></div><div><br></div></div><div>Thanks and sorry about the long message.</div><div><br></div><div>Ben</div><blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">On 10/8/2019 4:42:43 PM, Raoul Snyman via openlp-dev <openlp-dev@openlp.io> wrote:</p><div style="font-family:Arial,Helvetica,sans-serif">Hello everyone!<br><br>A while back we decided to switch to using pytest[0] for running our <br>tests. It's much faster than nose[1], and pretty actively developed. For <br>the most part, pytest can run tests written for the built-in unittest[2] <br>framework (which is what nose uses). Unfortunately there seem to be some <br>unintended consequences of this, and that is that sometimes the OpenLP <br>application object is not disposed of correctly, causing segfaults. <br>We've been skipping the tests for the OpenLP application object because <br>of this[3].<br><br>Benjamin was running into this issue[4], and being familiar with pytest, <br>figured he should use pytest fixtures (aka, The Right Way) to fix this <br>problem. Because of our history of nose -> nose2 -> pytest, we haven't <br>actually converted our tests to use pytest fixtures[5]. You can think of <br>a fixture as a way to run the setUp and tearDown methods without needing <br>a class.<br><br>I'd like to propose that we move to pytest fully. This, like all things, <br>will need to be an incremental change, but I reckon we can probably <br>start with the OpenLP application object tests.<br><br>What do you guys think?<br><br><br>[0] https://pytest.org/en/latest/<br>[1] https://docs.nose2.io/en/latest/<br>[2] https://docs.python.org/3/library/unittest.html<br>[3] <br>https://gitlab.com/openlp/openlp/blob/master/tests/functional/openlp_core/test_app.py#L161<br>[4] https://gitlab.com/openlp/openlp/merge_requests/19<br>[5] https://pytest.org/en/latest/fixture.html<br><br>-- <br>Raoul Snyman<br>raoul@snyman.info<br>_______________________________________________<br>openlp-dev mailing list<br>openlp-dev@openlp.io<br>https://lists.openlp.io/mailman/listinfo/openlp-dev<br></div></blockquote></div>