Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Test-Driven Development in GUIs

Reply
Thread Tools

Test-Driven Development in GUIs

 
 
Joe Van Dyk
Guest
Posts: n/a
 
      06-08-2005
Hi,

Anyone have any tips for writing GUIs in Ruby (using Tk, for example)
using a TDD approach?

A google search gave me
http://approximity.com/ruby/rubytk.html#testfirst, which claims that
some guy is writing a book on TDD for GUIs, using Ruby/Tk as preferred
language/toolkit. That section links to
http://www.c2.com/cgi/wiki?TestFirstUserInterfaces, while informative,
doesn't contain any information that I can see on a book.

Say, for the purposes of this discussion, say that you had a small Tk
application that monitored the status of ten websites. If the website
was up and was active and performing well, the GUI would display a
"Working!" message and perhaps showed data about the site (latency,
bandwidth, whatever). The GUI could also display graphs of
uptime/downtime, view history reports, and moderately complex GUI
stuff like that.

How would you go about testing that GUI application? There's a strong
chance that if I get some good ideas from my head and from this
discussion, that I'd write that application and also write a HOWTO on
TDD with GUIs.

Thanks,
Joe


 
Reply With Quote
 
 
 
 
Devin Mullins
Guest
Posts: n/a
 
      06-08-2005
TDDing UI is hard, because it's a side-effect, rather than a return
value or a parameter. I don't know the half of it. Nor, for that matter,
know how to use Tk. I present to you a "Hello world" example.

require 'test/unit'

class Greeter
def self.greet
puts 'Hello, world!'
end
end

class MockGreeter < Greeter
class << self
attr_reader ut
def puts(*args)
@out = @out ? [] : args
end
end
end

class TestGreeter < Test::Unit::TestCase
def testGreet
MockGreeter.greet
assert_equal ['Hello, world!'], MockGreeter.out
end
end

Subclass and override puts. Dependency injection doesn't help here. You
can have greet take a Module as a parameter, and call module.puts, but
you still need to test the container, and make sure it's passing Kernel
to the greet method.

Sorry, that's the short version. I gotta go.

Devin



 
Reply With Quote
 
 
 
 
Joe Van Dyk
Guest
Posts: n/a
 
      06-08-2005
On 6/7/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> Hi,
>=20
> Anyone have any tips for writing GUIs in Ruby (using Tk, for example)
> using a TDD approach?
>=20
> A google search gave me
> http://approximity.com/ruby/rubytk.html#testfirst, which claims that
> some guy is writing a book on TDD for GUIs, using Ruby/Tk as preferred
> language/toolkit. That section links to
> http://www.c2.com/cgi/wiki?TestFirstUserInterfaces, while informative,
> doesn't contain any information that I can see on a book.
>=20
> Say, for the purposes of this discussion, say that you had a small Tk
> application that monitored the status of ten websites. If the website
> was up and was active and performing well, the GUI would display a
> "Working!" message and perhaps showed data about the site (latency,
> bandwidth, whatever). The GUI could also display graphs of
> uptime/downtime, view history reports, and moderately complex GUI
> stuff like that.
>=20
> How would you go about testing that GUI application? There's a strong
> chance that if I get some good ideas from my head and from this
> discussion, that I'd write that application and also write a HOWTO on
> TDD with GUIs.
>=20
> Thanks,
> Joe
>=20


Here's a very simple example of a quick UI app that's unit tested.=20
Comments appreciated.

If you run the application like 'ruby file.rb test', the tests will
get run. If you run it like 'ruby file.rb', the gui will be
displayed. In a real application, the tests would be in their own
file, of course.

As I do more research, I'll post more examples.



require 'tk'
require 'test/unit'

class App
attr_accessor :sum, :inc_button, :display_button, ower_2_button

def initialize
@sum =3D 0

root =3D TkRoot.new :title =3D> 'my app', :geometry =3D> '300x300'

@inc_button =3D TkButton.new(root,=20
:text =3D> "Increment!",
:command =3D> proc { inc }
)
@inc_button.pack :expand =3D> true=20

@power_2_button =3D TkButton.new(root,
:text =3D> "Power of 2",
:command =3D> proc { power2 }
)
@power_2_button.pack :expand =3D> true
end

def inc
@sum +=3D 1
display
end

def power2
@sum *=3D @sum
display
end

def display
puts @sum
end
end


class TestApp < Test::Unit::TestCase
def testInc
app =3D App.new

assert_equal 0, app.sum

app.inc_button.invoke
assert_equal 1, app.sum

app.inc_button.invoke
assert_equal 2, app.sum
end

def testPower2
app =3D App.new

assert_equal 0, app.sum
=20
app.power_2_button.invoke
assert_equal 0, app.sum

app.inc_button.invoke
assert_equal 1, app.sum

app.power_2_button.invoke
assert_equal 1, app.sum

app.inc_button.invoke
assert_equal 2, app.sum

app.power_2_button.invoke
app.power_2_button.invoke
assert_equal 16, app.sum
end
end

if ARGV[0] !=3D 'test'
App.new
Tk.mainloop
exit
end


 
Reply With Quote
 
Joe Van Dyk
Guest
Posts: n/a
 
      06-08-2005
On 6/8/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> On 6/7/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> > Hi,
> >
> > Anyone have any tips for writing GUIs in Ruby (using Tk, for example)
> > using a TDD approach?
> >
> > A google search gave me
> > http://approximity.com/ruby/rubytk.html#testfirst, which claims that
> > some guy is writing a book on TDD for GUIs, using Ruby/Tk as preferred
> > language/toolkit. That section links to
> > http://www.c2.com/cgi/wiki?TestFirstUserInterfaces, while informative,
> > doesn't contain any information that I can see on a book.
> >
> > Say, for the purposes of this discussion, say that you had a small Tk
> > application that monitored the status of ten websites. If the website
> > was up and was active and performing well, the GUI would display a
> > "Working!" message and perhaps showed data about the site (latency,
> > bandwidth, whatever). The GUI could also display graphs of
> > uptime/downtime, view history reports, and moderately complex GUI
> > stuff like that.
> >
> > How would you go about testing that GUI application? There's a strong
> > chance that if I get some good ideas from my head and from this
> > discussion, that I'd write that application and also write a HOWTO on
> > TDD with GUIs.
> >
> > Thanks,
> > Joe
> >

>=20
> Here's a very simple example of a quick UI app that's unit tested.
> Comments appreciated.
>=20
> If you run the application like 'ruby file.rb test', the tests will
> get run. If you run it like 'ruby file.rb', the gui will be
> displayed. In a real application, the tests would be in their own
> file, of course.
>=20
> As I do more research, I'll post more examples.


Here's another iteration, this time the result is being displayed to a
TkLabel. The tests check to see if the label has the correct value.

So, when testing GUIs, is it good practice to have all the (tested)
widgets be available through attr_accessor (or attr_readers)? How
else can you test them?

require 'tk'
require 'test/unit'

class App
attr_accessor :sum, :inc_button, :display_button, ower_2_button,=20
utput_label

def initialize
@sum =3D TkVariable.new
@sum.value =3D 0

root =3D TkRoot.new :title =3D> 'my app'=20

@inc_button =3D TkButton.new root
@inc_button.text =3D "Increment"
@inc_button.command =3D proc { inc }
@inc_button.pack :expand =3D> true

@power_2_button =3D TkButton.new(root)
@power_2_button.text =3D "Power of 2"
@power_2_button.command =3D proc { power2 }
@power_2_button.pack :expand =3D> true

description_label =3D TkLabel.new
description_label.text =3D "Result:"
description_label.pack :expand =3D> true
@output_label =3D TkLabel.new
@output_label.textvariable =3D @sum
@output_label.pack :expand =3D> true
end

def inc
@sum.value =3D @sum.value.to_i + 1
end

def power2
@sum.value =3D @sum.value.to_i * @sum.value.to_i
end
end


class TestApp < Test::Unit::TestCase
def result(app)
app.output_label.text.to_i
end

def testInc
app =3D App.new

assert_equal 0, result(app)

app.inc_button.invoke
assert_equal 1, result(app)

app.inc_button.invoke
assert_equal 2, result(app)
end

def testPower2
app =3D App.new

assert_equal 0, result(app)

app.power_2_button.invoke
assert_equal 0, result(app)

app.inc_button.invoke
assert_equal 1, result(app)

app.power_2_button.invoke
assert_equal 1, result(app)

app.inc_button.invoke
assert_equal 2, result(app)

app.power_2_button.invoke
app.power_2_button.invoke
assert_equal 16, result(app)
end
end

if ARGV[0] !=3D 'test'
App.new
Tk.mainloop
exit
end


 
Reply With Quote
 
Joe Van Dyk
Guest
Posts: n/a
 
      06-08-2005
On 6/8/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> On 6/8/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> > On 6/7/05, Joe Van Dyk <(E-Mail Removed)> wrote:
> > > Hi,
> > >
> > > Anyone have any tips for writing GUIs in Ruby (using Tk, for example)
> > > using a TDD approach?


Tk question: How can I tell, via code, if a button is actually being
displayed on the screen?

Say buttons are being created based on data from a configuration file.
If I have a method that reads the config file and generates buttons,
how can I make sure those buttons are actually going to be displayed
on the screen?

I just ran into this problem when I forgot to 'pack' some buttons,
where 'packing' in Tk makes them visible/active on the screen. But I
don't know how to test for that.


 
Reply With Quote
 
Devin Mullins
Guest
Posts: n/a
 
      06-09-2005
Joe Van Dyk wrote:

>Tk question: How can I tell, via code, if a button is actually being
>displayed on the screen?
>
>

Look at my original response to you. Your unit tests don't need to test
that Tk is doing its job (hopefully the Tk people are doing that, but
seconding that, maybe your functional end-to-end tests are). Your unit
tests only need to test that you are making the right calls to the right
Tk methods.

Devin



 
Reply With Quote
 
Hidetoshi NAGAI
Guest
Posts: n/a
 
      06-09-2005
From: Joe Van Dyk <(E-Mail Removed)>
Subject: Re: Test-Driven Development in GUIs
Date: Thu, 9 Jun 2005 07:59:31 +0900
Message-ID: <(E-Mail Removed)>
> Tk question: How can I tell, via code, if a button is actually being
> displayed on the screen?


Does TkWinfo.mapped?(win) or TkWindow#winfo_mapped? satisfy you?
--
Hidetoshi NAGAI ((E-Mail Removed))


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a scripting tool to build GUIs? Sn0tters@yahoo.co.uk Java 2 07-19-2005 07:56 PM
Testing Swing GUIs Berlin Brown Java 4 07-19-2005 02:49 PM
Can Java do fancy GUIs? Ramon F Herrera Java 56 04-22-2005 11:21 PM
making guis with CreateDialog Stewart C++ 1 09-16-2004 09:07 AM
GUIs and Compilers.. <help> V e X y N C Programming 2 08-22-2003 07:33 AM



Advertisments