[TDD with run.r] Help needed please...
[1/10] from: melatiah::gmx::net at: 8-May-2007 16:00
Hi All, I'm a newbie to REBOL and TDD/run.r I like the the concept of TDD. I have read through the case study by the author of run.r ( a great program) I can see how the test framework operates on the maths functions presented. But how would it be applied to functions that operate on strings or perhaps to display a button object? Perhaps its my understanding of TDD at fault, but TDD encourages testing everything to get good coverage, well ideally 100%. For example if I wrote a program that simply display a button, I should also write a test case that tests the button has indeed been displayed. Traditionally the program would be run and the appearance of the button noted - test complete. Which is all well and good until code changes then these tests should be repeated. I see where a test framework is very useful to save time and accuracy. For example, say I code a button like this: (so easy in REBOL - cool!) view layout [ button "Click Me" ] How can I code this in a way that will allow the run.r framework to operate on it? That's in advance for your time and help. Sash -- Feel free - 10 GB Mailbox, 100 FreeSMS/Monat ... Jetzt GMX TopMail testen: http://www.gmx.net/de/go/topmail
[2/10] from: anton:wilddsl:au at: 9-May-2007 20:23
Hi Sash, Well, I guess it's hard to check the output of LAYOUT, which is a very complicated function, and VIEW, which rests upon the underlying internal View system. However, you make some basic checks to see that the layout was created ok with the button inside at the right position. Example: view/new layout [ button "Click Me" ] use [window button][ window: system/view/screen-face/pane/1 button: window/pane/1 object? button ; == true button/style ; == 'button button/offset ; == 20x20 button/size ; == 200x24 ; etc. unview/only window ] Note, I only checked out run.r a long time ago. Hope that helps, Anton.
[3/10] from: gregg:pointillistic at: 9-May-2007 5:58
Hi Sash, I like the concept of TDD, but I'm not a fan of the xUnit model; %run.r is an excellent implementation though (IMO). Testing GUIs is not easy. I worked on some ideas with Robert Muench that work at the level of programmatically inserting data, checking what value a face has, etc. That doesn't tell you anything about the rendering level though, which Anton's message alludes to. And as soon as you start using style sheets, things might change even more. You can check for some things automatically, like whether any faces in a pane fall outside its boundaries, or what color they are (by facet value), but it's a lot of work, and still may not help find problems that occur when a user is actually using the app. Maybe Robert will have some words of wisdom. My thoughts on non-UI unit testing will have to wait for another message. :) -- Gregg
[4/10] from: pwawood::gmail::com at: 9-May-2007 20:25
Hi Sash I have been using RUnit and TDD development of Rebol scripts and find it to be a very productive way of working. Most of the xUnit testing frameworks aren't really designed for testing GUI's. The general advice seems to be to separate as much of the program logic as possible from the GUI so that it can be tested. Also most of the test frameworks are designed for testing object methods though of course RUnit can be used to test any named block of code. So building on Anton's suggestion, for testability you could adopt an approach along these lines : my-gui-back-end: make object! [ button-maker: func [caption [string!] [ layout reduce ['button caption] ] ] with a test file along these lines: setup: does [ do %my-gui-back-end.r ;; load the object for testing ] test1: does [ my-button: button-maker "click here" assert object? my-button ] test2: does [ my-button: button-maker "click here" assert-equal button/style 'button ] etc. etc, (Apologies for any errors in the View code, I haven't really used it). As for 100% test coverage of the code, it's good but isn't the guarantee some people seem to indicate. "Data coverage" is equally important. For example, take this trivial function: div: func [a b] [ a / b] Now 100% code coverage is easy: assert-equal div 2 1 2 but there is much more to test: div "1" 2 div 1 0 and so one. So for me a good set of unit tests is a balance between code and data coverage. Regards Peter On Wednesday, May 9, 2007, at 06:23 pm, Anton Rolls wrote:
[5/10] from: melatiah:gmx at: 10-May-2007 15:20
Thanks Anton for your help. :) The code provided has given me some new thoughts on the subject. I'm using tester.r instead of run.r as I have managed to get it to run, this is down to my hamfistedness. :) Cheers, Sash -- Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kanns mit allen: http://www.gmx.net/de/go/multimessenger
[6/10] from: melatiah::gmx::net at: 10-May-2007 15:32
Thanks Gregg for the thoughts. I think when I get more to grips with REBOL and TDD I will be able to make better use of the great info you and others have provided. Thanks, Sash -- Psssst! Schon vom neuen GMX MultiMessenger gehört? Der kanns mit allen: http://www.gmx.net/de/go/multimessenger
[7/10] from: melatiah:gmx at: 10-May-2007 16:18
Hi Peter, First thing I realise is from what you wrote is RUnit and run.r are different. RUnit I gather is a much more complete testing framework. I will delve deeper to find out how to use RUnit.... I like the idea I could at least create objects and interrogate those objects. I will work on this. I appreciate your comments on "Data coverage". More valid test cases the better... At the moment my approach is to psuedocode the program logic and also separately psuedocode the test cases I am likely to need. Doing this I find has the effect of altering my original program logic as it evolves to embrace new test cases thought of. Of course when I actual code the test cases I work on one at a time until passed to conform to XP principles. Thanks, Sash -- Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
[8/10] from: GedB::Rushcoding::co::uk at: 10-May-2007 15:37
On 5/8/07, melatiah-gmx.net <melatiah-gmx.net> wrote:
> Hi All, > > I'm a newbie to REBOL and TDD/run.r > > I like the the concept of TDD. I have read through the case study by the author of run.r ( a great program) > > I can see how the test framework operates on the maths functions presented. But how would it be applied to functions that operate on strings or perhaps to display a button object? > > Perhaps its my understanding of TDD at fault, but TDD encourages testing everything to get good coverage, well ideally 100%. >
Melatiah, One of the great benefits of TDD is that it encourages separating out your code into reusable, testable modules. This first problem is telling you something very clear: you're design is too tightly bound to your user interface. If you can't test your code without using the GUI, then you can't use the code without using the GUI. What if, later on, you want to add a web or command line interface? When writing real applications you'll never want to write something that just pushes a button. Pushing a button is just the users way of indicating an action. When the user clicks on the button, what is supposed to happen? For example, perhap a user pushes the button to add another item to an order. In which case you actually want to test AddItemToOrder. After the call, ensure that the order has one more item, and that the new item is the on you added. What you are doing is starting with the Test inteface rather than the Graphical User Interface. The Test Interace is extremely simple, making it easy to write and easy to automate. It also provides a cheap interface that you are more willing to throw away if you find your initial designs are off. When you have built up a healthy test interface, then you can add a View, HTML, Ajax, Command Line or whatever. For an example of where this approach can read, take a look at Ruby on Rails ( www.rubyonrails.org ) or Naked Objects ( www.nakedobjects.org ) These frameworks allow the GUI to be automatically generated from the domain object model. Ged.
[9/10] from: robert::muench::robertmuench::de at: 13-May-2007 13:35
On Wed, 09 May 2007 14:25:15 +0200, Peter Wood <pwawood-gmail.com> wrote:
> Most of the xUnit testing frameworks aren't really designed for testing > GUI's. The general advice seems to be to separate as much of the > program logic as possible from the GUI so that it can be tested.
Hi, and that's the general problem with such tools. It's like testing a motor without the car. It just can't work. Either the tools can test my complete app and if not, the concept is of no value. The problem with Users is, that they don't follow the steps the programmer has though about. A GUI is a highly unordered event thing controlling your app. Can you be sure if sequence A and B lead to the same result? Testing functions is good, but not enough. As soon as the user comes into play, things get hard ;-) -- Robert M. M=FCnch Mobile: +49 (177) 245 2802 http://www.robertmuench.de
[10/10] from: GedB::Rushcoding::co::uk at: 13-May-2007 15:40
Robert, And that is the difference in philosophy. I've been dragged into too many projects where they build the whole interface before testing the functionality. Then the functionality proves unfit for purpose, but everything has been lumped together into the interface and its just too expensive to put anything right. In my experience GUI isn't difficult at all, as long as you take a contractual approach to the design rather than sequential. When the user does this, the preconditions must be satisfied. After the application has changed state then the postconditions must be satisfied. It doesn't matter what sequence the events occur in, the contracts always remain the same. Then you can make certain that the postconditions of A satisfy the preconditions of B. If they do not, then you have a problem. Either a contract is not being satisfied or the contract is missing an important detail. My personal experience is that everything becomes much easier once the user comes into play. Then you get to find out what is really needed. The sooner you can bring them in, the better. Ged On 5/13/07, Robert M. M=FCnch <robert.muench-robertmuench.de> wrote: