wxTimer in unittest

47 views
Skip to first unread message

Cédric Boudinet

unread,
Nov 8, 2017, 3:47:32 AM11/8/17
to wxPython-users

Hello

I am using a wx.Timer in a gui frame that I want to unit test. The problem is that under windows the timer events seems not to be taken in account when unit testing.

In the frame (wxtimer_unittest.py) when the user clicks the pushbutton, the text label changes to "timer Ok". I want to test this.

The unit test is in the file testgui.py.

When I launch the tests (python setup.py test), under Linux (py3+phoenix), the output is:


running build_ext
test0 (testgui.Tests_GUI) ... timer started
True
MyTimer.Notify
timer received
ok


=> The test is successful, whereas under Windows (still py3+phoenix), the output is:


running build_ext
test0 (testgui.Tests_GUI) ... timer started
True
FAIL
======================================================================
FAIL: test0 (testgui.Tests_GUI)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "f:\allobrogia\trunk\tests_wx\wxtimer_in_unittest\testgui.py", line 22, in test0
    self.assertEqual(self.frame.text.GetLabel(),"timer Ok")
AssertionError: '' != 'timer Ok'
+ timer Ok

----------------------------------------------------------------------


Which means that the wx.Timer.Notify is never called.

Is there a way to make such a test working under windows ?

Regards

Cedric



wxtimer_unittest.py
testgui.py
setup.py

Tim Roberts

unread,
Nov 8, 2017, 12:40:19 PM11/8/17
to wxpytho...@googlegroups.com
Cédric Boudinet wrote:
>
> I am using a wx.Timer in a gui frame that I want to unit test. The
> problem is that under windows the timer events seems not to be taken
> in account when unit testing.
>
> In the frame (wxtimer_unittest.py) when the user clicks the
> pushbutton, the text label changes to "timer Ok". I want to test this.
>
> The unit test is in the file testgui.py.
>
> ...
> Which means that the wx.Timer.Notify is never called.
>
> Is there a way to make such a test working under windows ?
>

You need to THINK about what you're doing here.  wx.Yield says "If there
are any outstanding messages, process them.  Otherwise, return."  At the
time you get to the Yield call, there are no outstanding messages,
because your timer isn't going to fire for another 9.9 seconds.

You don't really need to test the functionality of wx.Timer.  That is a
well-tested and well-understood component.  If you want to test the
timer callback, then just have your test code call the timer callback
directly.

If you really feel that you can't trust the wx.Timer to do what its
contract says, then you will need to have a loop in your test0 code that
calls wx.Yield with a short delay until the label changes.  If you're
really that untrusting, you probably want to check the time before and
after the loop and make sure it is 10 seconds.  But the whole concept of
testing wx.Timer in a unit test seems silly to me.

--
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Robin Dunn

unread,
Nov 8, 2017, 1:42:55 PM11/8/17
to wxPython-users


On Wednesday, November 8, 2017 at 9:40:19 AM UTC-8, Tim Roberts wrote:

You don't really need to test the functionality of wx.Timer.  That is a
well-tested and well-understood component. 



You can also see there the use of some helpers from the base class that assist with testing things like timers or otherwise waiting for things to happen. But, as Tim wrote, it would make more sense for your own tests to focus on your own code, not reinventing the wheel for things that have trusted tests elsewhere.

-- 
Robin Dunn
Software Craftsman
 

Cédric Boudinet

unread,
Nov 8, 2017, 3:32:17 PM11/8/17
to wxPython-users

The argument of wx.Timer.Start is in milliseconds and the argument of time.sleep is in seconds.
So at the end of time.sleep, the timer should have fired 10 times.
I also tried a while loop waiting for the label to change and on Windows it never ends. Whereas under Linux it works fine.

Actually, I don't want to simply test wx.Timer and I have no doubts it is working fine.

I am developing a widget which is embedding some controls and a timer (my widget is some kind of configurable timer). I want to test this behavior as a whole.That's why  I would like to make the wx.Timer work in the unittest. Maybe I will split down my tests in two.

Robin Dunn

unread,
Nov 8, 2017, 4:46:50 PM11/8/17
to wxPython-users


On Wednesday, November 8, 2017 at 12:32:17 PM UTC-8, Cédric Boudinet wrote:

The argument of wx.Timer.Start is in milliseconds and the argument of time.sleep is in seconds.
So at the end of time.sleep, the timer should have fired 10 times.

No. It would have fired 10 times if the event loop was not blocked, but the time.sleep does indeed block. It simply sits there inside that function until the time expires and then returns. It does not do anything to allow events to be fetched from the system and dispatched to handlers. And, since timer events are typically a lower priority than others, when you do allow the event loop to run in wx.Yield the system will probably have discarded those messages when it saw them piling up in the message queue.

Tim Roberts

unread,
Nov 8, 2017, 5:47:28 PM11/8/17
to wxpytho...@googlegroups.com
Robin Dunn wrote:

On Wednesday, November 8, 2017 at 12:32:17 PM UTC-8, Cédric Boudinet wrote:

The argument of wx.Timer.Start is in milliseconds and the argument of time.sleep is in seconds.
So at the end of time.sleep, the timer should have fired 10 times.

No. It would have fired 10 times if the event loop was not blocked, but the time.sleep does indeed block. It simply sits there inside that function until the time expires and then returns. It does not do anything to allow events to be fetched from the system and dispatched to handlers. And, since timer events are typically a lower priority than others,

More than that, on Windows at least, timer events do not accumulate.  If a timer fires when its previous event has not been processed, it will not queue another one.
Reply all
Reply to author
Forward
0 new messages