<div dir="ltr">Neil, you might also bring this up on the <a href="http://lists.idyll.org/listinfo/testing-in-python">http://lists.idyll.org/listinfo/testing-in-python</a> list as I suspect people there have opinions on this topic.<div><br></div><div>-gps</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Aug 21, 2017 at 9:07 AM Ned Batchelder <<a href="mailto:ned@nedbatchelder.com">ned@nedbatchelder.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div bgcolor="#FFFFFF" text="#000000">
    On 8/20/17 9:32 PM, Neil Girdhar wrote:<br>
    <blockquote type="cite">
      <div dir="ltr">This question describes an example of the
problem: <a class="m_-9032352457554463881moz-txt-link-freetext" href="https://stackoverflow.com/questions/8416208/in-python-is-there-a-good-idiom-for-using-context-managers-in-setup-teardown" target="_blank">https://stackoverflow.com/questions/8416208/in-python-is-there-a-good-idiom-for-using-context-managers-in-setup-teardown</a>.
         You want to invoke a context manager in your
        setup/tearing-down, but the easiest way to do that is to
        override run, which seems ugly.
        <div><br>
        </div>
        <div>Why not add two methods to unittest.TestCase whose default
          implementations are given below:</div>
        <div><br>
        </div>
        <div>
          <div>class TestCase:</div>
          <div><br>
          </div>
          <div>    @contextmanager</div>
          <div>    def method_context(self):</div>
          <div>        self.setUp()</div>
          <div>        try:</div>
          <div>            yield</div>
          <div>        finally:</div>
          <div>            self.tearDown()</div>
          <div><br>
          </div>
          <div>    @contextmanager</div>
          <div>    def class_context(self):</div>
          <div>        self.setUpClass()</div>
          <div>        try:</div>
          <div>            yield</div>
          <div>        finally:</div>
          <div>            self.tearDown()</div>
        </div>
        <div><br>
        </div>
        <div><br>
        </div>
        <div>Then, if for example someone wants to use a context manager
          in setUp, they can do so:</div>
        <div><br>
        </div>
        <div>
          <div>class SomeTest(TestCase):</div>
          <div><br>
          </div>
          <div>    @contextmanager</div>
          <div>    def method_context(self):</div>
          <div>        with np.errstate(all='raise'):</div>
          <div>            with super().method_context():</div>
          <div>                yield</div>
        </div>
        <div><br>
        </div>
        <div>Best,</div>
        <div><br>
        </div>
        <div>Neil</div>
      </div>
      <br>
      <fieldset class="m_-9032352457554463881mimeAttachmentHeader"></fieldset>
      <br>
      <pre>_______________________________________________
Python-ideas mailing list
<a class="m_-9032352457554463881moz-txt-link-abbreviated" href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a>
<a class="m_-9032352457554463881moz-txt-link-freetext" href="https://mail.python.org/mailman/listinfo/python-ideas" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a>
Code of Conduct: <a class="m_-9032352457554463881moz-txt-link-freetext" href="http://python.org/psf/codeofconduct/" target="_blank">http://python.org/psf/codeofconduct/</a>
</pre>
    </blockquote>
    <br></div><div bgcolor="#FFFFFF" text="#000000">
    I've achieved a similar effect with this:<br>
    <br>
    <blockquote>def setup_with_context_manager(testcase, cm):<br>
          """Use a contextmanager to setUp a test case.<br>
      <br>
          If you have a context manager you like::<br>
      <br>
              with ctxmgr(a, b, c) as v:<br>
                  # do something with v<br>
      <br>
          and you want to have that effect for a test case, call this
      function from<br>
          your setUp, and it will start the context manager for your
      test, and end it<br>
          when the test is done::<br>
      <br>
              def setUp(self):<br>
                  self.v = setup_with_context_manager(self, ctxmgr(a, b,
      c))<br>
      <br>
              def test_foo(self):<br>
                  # do something with self.v<br>
      <br>
          """<br>
          val = cm.__enter__()<br>
          testcase.addCleanup(cm.__exit__, None, None, None)<br>
          return val<br>
    </blockquote>
    <br>
    I think the use is easier than yours, which needs too much super and
    @contextmanager boilerplate.</div><div bgcolor="#FFFFFF" text="#000000"><br>
    <br>
    --Ned.<br>
    <br>
  </div>

_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div>