unit tests

24 views
Skip to first unread message

greenmoss

unread,
Apr 1, 2011, 9:40:21 AM4/1/11
to pyglet-users
All,

Does anyone here use unit tests for your graphics elements? For
example, I would like to test "resize the window, and ensure that
element foo has coordinates x,y". Is this possible?

Thanks

Casey Duncan

unread,
Apr 1, 2011, 12:32:32 PM4/1/11
to pyglet...@googlegroups.com
Yes, although I'm not sure what you mean exactly by "graphics
elements". Typically I try to divide duties so that I can test things
like positioning separately from the drawing itself.

Testing the positioning is just standard unit testing then (they're
just objects with attributes like anything else). Testing the drawing
just involves passing in a minimal "mock" gl (as in pyglet.gl) and
then asserting that the correct drawing commands were executed. I
don't typically do this for specific games, but really just for game
engine type stuff which is highly generalized.

Also why would resizing the window change an elements coordinates? I
would think resizing the window would just change the projection or
the viewport size. But maybe I'm missing something.

-Casey

> --
> You received this message because you are subscribed to the Google Groups "pyglet-users" group.
> To post to this group, send email to pyglet...@googlegroups.com.
> To unsubscribe from this group, send email to pyglet-users...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/pyglet-users?hl=en.
>
>

Jonathan Hartley

unread,
Apr 2, 2011, 7:48:54 PM4/2/11
to pyglet-users
Hey.

Where I work we very thoroughly test GUI code which uses conventional
GUI elements, or which runs in a browser. However, we do not call
these 'unit tests' - we call them system or functional or acceptance
tests (these terms are all synonymous.) We still use unittest.TestCase
to write them though, albeit augmented with many utility methods to do
things like open windows, move the mouse, etc.

Apologies if I'm muddying the waters by quibbling about definitions,
but just in case it's useful to define terms: A unit test of the same
code might call the same functions, but it would pass in harmless
parameters or maybe mock out called subfunctions or submodules in
order to prevent actual interaction with the GUI library. The point
being, you should be able to run unit tests in parallel, or without
any GUI installed, or on a different OS, and that shouldn't affect
whether they pass or fail. Your unit test suite should run in less
than a second, and that's generally not possible if you're actually
opening windows and the like.

However, we only write such system tests for business GUI
applications, using Windows Forms or Django forms, etc. For OpenGL or
pyglet applications, it's much harder to do true end-to-end tests,
because there is no obvious programmatic way to query the resulting
state of the GUI. e.g. there are no equivalents of things like
'assertTrue(checkbox.Enabled)' - because the screen is just a big
unstructured array of pixels.

To my mind, there are a few possible approaches:

1) Write one or two really rough and ready 'smoke tests' that fire up
your applications, assert that a window is openened, that the screen
is mostly color X, that the framerate is within expected bounds, then
quit with a pass.

2) You might write tests which really examine the state of the screen
to be able to assert that the correct menus are displayed, that the
player character moves left and right, etc. I believe that in the
general case, this is very time consuming and isn't worth the effort.
I'd *love* to be shown that I'm wrong, but I think to do this right is
a Hard Problem.

3) Alternatively, you could simply acceptance test your application by
interrogating the state of your own GUI layer. This is the equivalent
of assertTrue(checkbox.Enabled), but instead of 3rd party 'checkbox',
you're using your own GUI classes, whatever they are. These GUI
classes would be unit tested (as would be the rest of your
application.) You'd have no actual assurance that your application
actually worked end-to-end, but I think this approach, coupled with
approach (1), is about the best bang-for-buck you could hope to
achieve.

4) You could mock out layers like OpenGL or pyglet, and assert that
the expected calls were made of them when you put the game into a
particular state. The problem is that the transformation from 'game
state X' to 'opengl calls A,B and C' is quite a complex one, and prone
to frequent change, so this sounds hard to me.

I once asked Kent Beck for suggestions testing fullscreen graphics
apps like games, and he recommended a combination of (1) and (3).

Best regards,

greenmoss

unread,
Apr 4, 2011, 9:38:04 AM4/4/11
to pyglet-users
The reason I posted this question was because I have some complex
scaling interactions:

- a background star field composed of opengl points; the individual
points should always stay in the same relative window position, and
not grow or shrink
- a foreground star field composed of sprites and labels; zoom/pan/
window re-size operations for the foreground star field which only
changes the *positions* of stars/labels relative to all the *other*
foregrounds stars/labels
- zoom/pan/window resize operations for the foreground star field
should *not* affect the sizes of any of the stars or labels, eg they
are sized the same across *all* zoom levels
- a HUD which stays constant across all zoom levels, with the
exception that some HUD elements are anchored to window positions
(think "bottom left portion of window") and thus need to move when the
window re-sizes

I have this all working, but it is "delicate". I've made changes in
the past which introduce errors but are not immediately visible
without manually testing all permutations of options. For instance,
zoom/pan work correctly, but upon window resize I might notice that
the star sprites and labels incorrectly re-size.

So ideally I'd have a unit test ("functional test", or "acceptance
test" as per Jonathan Hartley's comment?) to exercise zoom, pan, and
window re-size. Doing these tests manually would quickly get tedious.

On Apr 1, 12:32 pm, Casey Duncan <casey.dun...@gmail.com> wrote:
> Yes, although I'm not sure what you mean exactly by "graphics
> elements". Typically I try to divide duties so that I can test things
> like positioning separately from the drawing itself.
>
> Testing the positioning is just standard unit testing then (they're
> just objects with attributes like anything else). Testing the drawing
> just involves passing in a minimal "mock" gl (as in pyglet.gl) and
> then asserting that the correct drawing commands were executed. I
> don't typically do this for specific games, but really just for game
> engine type stuff which is highly generalized.
>
> Also why would resizing the window change an elements coordinates? I
> would think resizing the window would just change the projection or
> the viewport size. But maybe I'm missing something.
>
Reply all
Reply to author
Forward
0 new messages