[TFUI] Unit Testing a Smalltalk GUI

Phlip <phlipcpp-/[email protected]>
Newsgroups gmane.comp.programming.test-first-user-interfaces
Message-ID <[email protected]>
From the XP newsgroup:

Phlip wrote:

> danp wrote:
>
> > Ive bitten the bullet and unit tested a few simple
> > dialog boxes. Much
> > easier
> > than I first though. However, encountered 
> > a couple of problems:
>
> Post some code. You even neglected to reveal 
> what GUI Toolkit you use!

Im using Smalltalk (VSE). Its a legacy system that we
have been enhancing and revitalizing recently. We put
in acceptance test first, and started unit testing.
Now I want to test the gui. There are a lot of badly
designed windows with a lot of domain logic tied up
inside, so the job is messy, but worth while. The
first thing I tried was to create a new open method
that didn't paint the window, and opend it up
non-modal. It went something like this.

    openForUnitTest
        self createViews.
        self dontPaint.
        self openModeless.

A setup would be...

    setUp
        window := ADialog new.
        window openForUnitTest.

Then I simulated gui events and test the outcome.

    test1
        (window paneNamed: #address)
            value: 'buckinham palace';
            triggerEvent: #changed with: 'buckingham
palace'.
        (window paneNamed: #ok) triggerEvent:
#clicked.
        self assert: window address = 'buckingham
palace'.

> >     setup and teardown of window still quite slow
> > (1/2 second), even
> > without a paint.
> >     Probably to do with the dev envionment Im
> > using.
> >
> >     Because the windows are not being displayed,
> > you cant test whether widgits that
> >     are selectively hidden/show are working
> > properly. Im not too fussed about that.
>
> Some issues, such as each little color or geometry,
> you must punt, and some
> issues the library makes you punt.
>
> >     Dialogs that pop up dialogs - how do I
> > intercept that and break that
> > action?
>
> By intercepting it and breaking up the action. Build
> a mock object and plug
> it into the senior dialog. It will only test the
> senior tried to raise it.
> In production code, plug a real junior dialog in.

Ive though about that. Perhaps having an instance
variable that stores an object that you ask for input.
In production you put in the junior window:

    window := ADialog new
        aJuniorWindow: AJuniorWindow;
        yourself.

... and in test, you send it your mock:

    window := ADialog new
        aJuniorWindow: aMockObject;
        yourself.

I also thought about sending an event or signalling a
Notification when you are about to open a window. In
production you would ignor the signal, but in testing
you would assert that this notification should be
raised. But I though it would be more difficult to
test the outcome of the completed operation, since you
would have to curtail the process on the signal,
otherwisee the junior dialog box wouuld appear.

Thats where I am now

Dan

Terry wrote:

> that you really don't need to test the user
interface
> elements.  Somebody else (Microsoft? Sun? You don't
> mention what
> API/language you're using)

Smalltalk (VSE)

> presumably wrote that code, and even if you *did*
> find bugs in it, you can't really fix it.
>
> Just separate your action code (e.g. what happens
> when a button is clicked) so
> that it can be tested in the absence of the UI.
>
> As far as testing whether some elements are
displayed
> or hidden, again, about
> all you can do is make the logic that determines
that
> as independent of the UI
> elements as possible.  One trick you could use is to
> write virtual methods
> that do the actual fiddling with the UI elements
> (show, hide, etc).
> These
> would usually contain only a single method call
(e.g.
> "myWindow.Show()").
> Then, in your tests, derive a test class and 
> override the virtual methods.
> Then you can test to see whether they were called.

But then what if the production implementation of
myWindow.Show() causes a walk back? You would never
get coverage of that code. To get coverage, how about
sending out a Notification (which is a resumable
Exception who's default action is a nop) when ever
myWindow.Show() is called.  Our method would look like
this (appologies for switching to Smalltalk):

    hide
        (self paneNamed: #options) hide.
        PaneHidden signal: (self paneNamed: #options)

In production, the notification would be ignored. We 
can test like this:

    testHiddenPane
        self
            should:
                [(window paneNamed: #checkBox)
                    checked;
                    triggerEvent: #checked]
            raise: PaneHidden. "should also test the
parameter"

I don't know how people feel about exception - some
people hate them. Mind you it would be pretty
difficult to implement sunit with out them.

> You can also use mock objects in place of real UI
> elements.
>
> Yep, that's a lot of non-production code.  On my
last
> project, there was
> probably more test code than production code.  But I
> still think I saved
> time over not testing and trying to debug later.

Yep

> Terry

Dan

Phlip writes:

Is there a Smalltalker in the house?


=====
Phlip
  http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces


		
__________________________________
Do you Yahoo!?
Yahoo! Mail - Helps protect you from nasty viruses.
http://promotions.yahoo.com/new_mail


------------------------ Yahoo! Groups Sponsor --------------------~--> 
Yahoo! Domains - Claim yours for only $14.70
http://us.click.yahoo.com/Z1wmxD/DREIAA/yQLSAA/nhFolB/TM
--------------------------------------------------------------------~-> 

To unsubscribe, email:
TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org
 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
     http://groups.yahoo.com/group/TestFirstUserInterfaces/

<*> To unsubscribe from this group, send an email to:
     TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org

<*> Your use of Yahoo! Groups is subject to:
     http://docs.yahoo.com/info/terms/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.