[Tutor] Unit testing infinite loops

James Chapman james at uplinkzero.com
Fri Jan 31 14:12:56 CET 2014


Hmm...

Here is an example of how I'm currently trying to test it:

test_tutor_question.py
-----------------------------
# -*- coding: utf-8 -*-
import unittest
import mock
from tutor_question import Infinite_Loop_Tutor_Question


class Test_Infinite_Loop_Tutor_Question(unittest.TestCase):

    def test_run_forever(self):
        with mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_A')
as start_A:
            with
mock.patch('tutor_question.Infinite_Loop_Tutor_Question.start_B') as
start_B:
                inf_loop = Infinite_Loop_Tutor_Question()
                print start_A.call_count
                print start_B.call_count
                inf_loop.run_forever()
                inf_loop.interrupt_main()
                print start_A.call_count
                print start_B.call_count


if __name__ == "__main__":
    unittest.main()
-----------------------------

As you can see if you run this, the test doesn't reach the lines below
inf_loop.run_forever().

So ideally, I'd need a way of injecting a keyboard interrupt into the
method, I could then check that the exception was handled and that the
start_A and start_B calls were made.

** Obviously the print lines will be substituted for some kind of
assert lines **

FYI I'm using CPython 2.7.<something>



--
James


On 31 January 2014 12:57, eryksun <eryksun at gmail.com> wrote:
>
> On Fri, Jan 31, 2014 at 6:31 AM, James Chapman <james at uplinkzero.com> wrote:
> > try:
> >     while self.attribute:
> >         time.sleep(1)
> > except KeyboardInterrupt:
> >     ...
> >
> > My unit test could then set the attribute. However I'd still have the
> > problem of how I get from the unit test line that fires up the method to the
> > next line to change the attribute.
>
> You could add a method that toggles the attribute, and use a
> threading.Timer to run it after a set interval.
>
> > if it's testable as is, how would I test it?
>
> CPython 2.3+ can interrupt the main thread from another thread using
> the built-in function `_thread.interrupt_main`:
>
> http://docs.python.org/3/library/_thread#_thread.interrupt_main
>
>     >>> import _thread
>     >>> _thread.interrupt_main()
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     KeyboardInterrupt
>
> It's also implemented in PyPy, but not in Jython.


More information about the Tutor mailing list