On 6/8/05, Joe Van Dyk <> wrote:
> On 6/7/05, Joe Van Dyk <> 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