XpdWiki

FrontPage
RecentChanges
XtC
FindPage
PageIndex
XpApprentices

Set your name in
UserPreferences

Edit this page

Referenced by
XtC1999




JSPWiki v2.0.52


XtC28091999


XtC21091999 Next: XtC05101999


Meeting Tuesday 28th September 1999

Possible Agenda:

  • We have a primitive Wiki working, we need to ramp it up with an Edit form etc. We will pull out the next story and map out some engineering tasks. We also need to put up our work so far on this site.
  • Let's look at Paul's 'Refactoring in 15 minutes' --RichardEmerson, pie fan.

Did anything happen? Some of us look forward to these reports, you know! Yes ,see below ...


https://xpdeveloper.com/servlet/com.xpdeveloper.PageSaver?browse=FrontPage

Try things like https://xpdeveloper.com/servlet/com.xpdeveloper.PageSaver?edit=FrontPage

That about sums it up, except I have to rescue the second pairs work from a VAJ repository, on a broken machine -- OliBye


Group 2 (TimM, IvanMoore & SteveFreeman) fixed a bug in the link parser that couldn't handle links with trailing punctuation, e.g. "_LinkWord?_." Tim and Ivan did the first cut which changed Link.Split() to split tokens on underbars, rather than white space. They then reassembled the link tokens with leading and trailing underbars. This gave the right behaviour and left Link.renderWholeString() unchanged but required two loops to handle essentially the same decisions Changes:
  • Code Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?r1=1.1.1.1&r2=1.1.1.2&only_with_tag=g2_1_13_1
  • Test Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestLinks.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g2_1_13_1
  • Final Code Version: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_13_1

Then Steve had a go with Ivan and merged split() and renderWholeString() to produce a single loop that tokenized on underbar and did not have to reassemble the link tokens. This seemed much simpler and required only one loop. This became version The emphasis wasn't on efficiency - it was simply much less code - it was more controversial becuase it wiped out a few tests

Changes:

  • Code Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?only_with_tag=g2_1_14&r1=1.1.1.3%3Ag2_1_14&tr1=1.1.1.3&r2=1.1.1.1%3Ag2_1_12&tr2=1.1.1.3&f=h).
  • Test Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestLinks.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g2_1_13_1
  • Final Code Version: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_14
  • Approach Difference between groups: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?only_with_tag=g2_1_14&r1=text&tr1=1.1.1.3&r2=1.1.1.2%3Ag2_1_13_1&tr2=1.1.1.3&f=h

Points

  • we tried two versions because Tim and Ivan disagreed with Steve and wanted to simply plug in a solution the preserved the intent of the original tests that were in the code (triple pairs is generally a bad idea (OliBye had to separate them using short straws)). While this appeared to be a reasonable approach - these tests later proved to be a legacy of incremental development and were no longer necessary. Sometimes you have to step back a little to find TheSimplestThing? - In fact the tests that were in place were more indicative of a more traditional bottom up approach to XP where at the lowest level you assume that you need to be able to ask someone whether something is a link or not - and so you write and test this responsibility. In fact, the overriding intent of the story is to simply display some words in HTML showing links - and so the lower level objects were not needed at this point.

  • When you have a disagreement, rolling up your sleaves and doing it twice is not a bad approach. You learn a lot this way (the second idea can generally be improved from lessons in doing the first idea). You only loose 30-60 mins, and end up with a better all round solution that probably incorporates both solutions.

  • There's also the question of when to remove interim or low-level unit tests. Just because something works doesn't mean you keep it.

  • working through this excercise revealed some new unit tests. What do we do with link tokens that contain white space, e.g. "This is a _link token_"? The new implementation will create a link around link token. We also have to check for phrases like, "", "_ _", "get the_latest _HotLink?_".

  • while the released version was the simplest, we will probably need something closer to the other version as things get more complicated (however we don't need it yet, and with good version control we can get it back later - or better still, didn't write it in the first place).


Meanwhile Group 1 (OliBye & RichardEmerson) were working on the "edit" story. They started with g2.1.12 (https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_12), which could already handle an HTTP GET to retrieve different named pages, and could (sort of) save new text into those pages if you supplied an extra parameter on the GET query string.

The story's intent was to have edit boxes like other Wikis. We had two engineering tasks:

  • Make the servlet handle HTTP POST to save a page.

  • Handle an "edit" parameter (on GET) and return a HTML form with an edit box in, which the user can then use to do the POST.

So here's what we did:

1. We knew we wanted a test called something like testPostingAKnownString. We almost wrote one that did an HTTP POST and then an HTTP GET and compared the result with what it had POSTed. This felt pretty simple. But there was already a test called testDisplayingAKnownString, which just stuffed a string directly into the PageSaver class using a method call, then checked that an HTTP GET with the same page name gave back the same string. What we wanted was the same thing but the other way round - and a method call is simpler than an HTTP GET. So in the end our simplest test was to do an HTTP POST and then use a direct method call to check it worked. We ran all the tests and of course our new one failed (we hadn't written anything to make it pass yet).

2. We wrote a bit of the servlet's doPost method and then ran the tests again. Something failed, but not what we expected at all - some weird exception was being thrown elsewhere, in one of the tests (I think it tested the doGet method) that passed before we wrote our couple of new lines of code. How had we broken this other code? As it turned out it wasn't our fault: VisualAge's servlet test environment (or Windows 2000) was holding onto sockets but telling us it had let them go. When we restarted VisualAge, our new test still failed (fine) but the old one passed again (phew). Just to be sure, we added a stopServletRunner call in the testing class' main method.

3. So now we finished off the doPost method in the servlet. There's only a few lines to it and we were pretty sure it was ok. Run the tests; the test still fails! This time our test was wrong: we'd misunderstood the way you have to do POST requests with Java's URL classes (you can't have any parameters on the URL line, you have to put them all in the POST body). It took about 20 seconds to fix it and we ran the tests again - success! This deserved a new version, g1.1.13, and another beer.

4. For the next test we almost overdid it again: we thought we wanted to test that the servlet could give us the right HTML form for editing a page, and that when we POSTed from the form, our new text got saved correctly. But of course we'd already done the second part in our previous test. All we really needed in this test was to do an HTTP GET including the "edit" parameter and check the HTML page that we got back. Again we could use a direct method call to find out what text should be inside the returned form's edit box. This test was easy to write, although we ended up with a big string literal that was being compared with what the servlet returned. Run the tests! The new test fails - no problem.

5. We changed the servlet to handle the "edit" parameter. Actually it already did this but it didn't return an HTML form. The form needed the servlet's own address in it so that the browser knew where to POST to. For a while we got horribly sidetracked trying to find a smart way to get a servlet's own URL from Sun's servlet classes, then we suddenly realised that of course we weren't DoingTheSimplestThing. So the servlet got a great big string literal as well - exactly the same one as the test of course. It was shouting to be refactored but no - run the tests first! They all passed.

6. Now we got to refactor that horrible great big string literal. OliBye had clearly done this before and introduced a sneaky use of java.text.MessageFormat, which lets you use strings like "My first param is {0} and my second is {1}" and then substitute an array of values for the {}s. We used {}s for the servlet's own URL (to go in the form), the page name, and the page content. Both the servlet and the test now use the same string literal with the {}s in. Run the tests! Everything passed - so we made this version g1.1.14 (https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g1_1_14).

You can see the testing code we added at https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestServlets.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g1_1_14

And the implementation changes at https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/PageSaver.java.diff?r1=1.1.1.3&r2=1.1.1.4&only_with_tag=g1_1_14 - see what we mean about that big string literal? ;)

Just for fun (or perhaps because we're still not used to trusting the tests enough) we left the servlet test environment running, and tried our changes out in a browser. They worked fine, but we realised we'd missed something out: the POST needed to return something like "Thanks for your edits", or the new page content. Was this missing from the original story or just from our 'engineering task' interpretation of it? We weren't sure, but all our tests ran and we'd done enough so we noted it down on the story card and left it for next time.

  • Once again we were rushing to get something done inside our FifteenMinuteTimeBoxes - either a new test, or making a test pass, or refactoring. We started off badly and went way over time for our first TimeBox?, but once we got going we were ok.

  • We kept spotting things that suggested we should Wiki.RefactorMercilessly?, but by the end of the night we hadn't refactored them: for example, all these bits of code that keep doing HTTP GETs in the tests are certainly not in there Wiki.OnceAndOnlyOnce? - they even have duplicate string literals in them for the "/servlet/" part of the URL. We felt we weren't being extreme enough about refactoring, and the code was right there to prove it. It was interesting how uncomfortable this made us feel, now that we're becoming more aware of how to refactor. More refactoring needed next time.


UnitOfLoadFactor?

After the session, TimM, OliBye and SteveFreeman got into a discussion about the granularity of LoadFactor. After much to-ing and fro-ing (do we measure per-individual, per-subgroup, per-group, etc), we came down to the notion that you should measure the LoadFactor of the the unit that you're scheduling. For example, in the PlanningGame, the unit is the entire group. For CommittmentSchedules? the unit may be individual developers (according to KentBeck's EmbracingChange? book); TimM prefers still to schedule by the group. OliBye has only tried doing it at the group level and looks forward to trying the other levels to see if they're useful. Previous: XtC21091999 Next: XtC05101999


Meeting Tuesday 28th September 1999

Possible Agenda:

  • We have a primitive Wiki working, we need to ramp it up with an Edit form etc. We will pull out the next story and map out some engineering tasks. We also need to put up our work so far on this site.
  • Let's look at Paul's 'Refactoring in 15 minutes' --RichardEmerson, pie fan.

Did anything happen? Some of us look forward to these reports, you know! Yes ,see below ...


https://xpdeveloper.com/servlet/com.xpdeveloper.PageSaver?browse=FrontPage

Try things like https://xpdeveloper.com/servlet/com.xpdeveloper.PageSaver?edit=FrontPage

That about sums it up, except I have to rescue the second pairs work from a VAJ repository, on a broken machine -- OliBye


Group 2 (TimM, IvanMoore & SteveFreeman) fixed a bug in the link parser that couldn't handle links with trailing punctuation, e.g. "_LinkWord?_." Tim and Ivan did the first cut which changed Link.Split() to split tokens on underbars, rather than white space. They then reassembled the link tokens with leading and trailing underbars. This gave the right behaviour and left Link.renderWholeString() unchanged but required two loops to handle essentially the same decisions Changes:
  • Code Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?r1=1.1.1.1&r2=1.1.1.2&only_with_tag=g2_1_13_1
  • Test Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestLinks.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g2_1_13_1
  • Final Code Version: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_13_1

Then Steve had a go with Ivan and merged split() and renderWholeString() to produce a single loop that tokenized on underbar and did not have to reassemble the link tokens. This seemed much simpler and required only one loop. This became version The emphasis wasn't on efficiency - it was simply much less code - it was more controversial becuase it wiped out a few tests

Changes:

  • Code Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?only_with_tag=g2_1_14&r1=1.1.1.3%3Ag2_1_14&tr1=1.1.1.3&r2=1.1.1.1%3Ag2_1_12&tr2=1.1.1.3&f=h).
  • Test Diff: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestLinks.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g2_1_13_1
  • Final Code Version: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_14
  • Approach Difference between groups: https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/Link.java.diff?only_with_tag=g2_1_14&r1=text&tr1=1.1.1.3&r2=1.1.1.2%3Ag2_1_13_1&tr2=1.1.1.3&f=h

Points

  • we tried two versions because Tim and Ivan disagreed with Steve and wanted to simply plug in a solution the preserved the intent of the original tests that were in the code (triple pairs is generally a bad idea (OliBye had to separate them using short straws)). While this appeared to be a reasonable approach - these tests later proved to be a legacy of incremental development and were no longer necessary. Sometimes you have to step back a little to find TheSimplestThing? - In fact the tests that were in place were more indicative of a more traditional bottom up approach to XP where at the lowest level you assume that you need to be able to ask someone whether something is a link or not - and so you write and test this responsibility. In fact, the overriding intent of the story is to simply display some words in HTML showing links - and so the lower level objects were not needed at this point.

  • When you have a disagreement, rolling up your sleeves and doing it twice is not a bad approach. You learn a lot this way (the second idea can generally be improved from lessons in doing the first idea). You only loose 30-60 mins, and end up with a better all round solution that probably incorporates both solutions.

  • There's also the question of when to remove interim or low-level unit tests. Just because something works doesn't mean you keep it.

  • working through this excercise revealed some new unit tests. What do we do with link tokens that contain white space, e.g. "This is a _link token_"? The new implementation will create a link around link token. We also have to check for phrases like, "", "_ _", "get the_latest _HotLink?_".

  • while the released version was the simplest, we will probably need something closer to the other version as things get more complicated (however we don't need it yet, and with good version control we can get it back later - or better still, didn't write it in the first place).


Meanwhile Group 1 (OliBye & RichardEmerson) were working on the "edit" story. They started with g2.1.12 (https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g2_1_12), which could already handle an HTTP GET to retrieve different named pages, and could (sort of) save new text into those pages if you supplied an extra parameter on the GET query string.

The story's intent was to have edit boxes like other Wikis. We had two engineering tasks:

  • Make the servlet handle HTTP POST to save a page.

  • Handle an "edit" parameter (on GET) and return a HTML form with an edit box in, which the user can then use to do the POST.

So here's what we did:

1. We knew we wanted a test called something like testPostingAKnownString. We almost wrote one that did an HTTP POST and then an HTTP GET and compared the result with what it had POSTed. This felt pretty simple. But there was already a test called testDisplayingAKnownString, which just stuffed a string directly into the PageSaver class using a method call, then checked that an HTTP GET with the same page name gave back the same string. What we wanted was the same thing but the other way round - and a method call is simpler than an HTTP GET. So in the end our simplest test was to do an HTTP POST and then use a direct method call to check it worked. We ran all the tests and of course our new one failed (we hadn't written anything to make it pass yet).

2. We wrote a bit of the servlet's doPost method and then ran the tests again. Something failed, but not what we expected at all - some weird exception was being thrown elsewhere, in one of the tests (I think it tested the doGet method) that passed before we wrote our couple of new lines of code. How had we broken this other code? As it turned out it wasn't our fault: VisualAge's servlet test environment (or Windows 2000) was holding onto sockets but telling us it had let them go. When we restarted VisualAge, our new test still failed (fine) but the old one passed again (phew). Just to be sure, we added a stopServletRunner call in the testing class' main method.

3. So now we finished off the doPost method in the servlet. There's only a few lines to it and we were pretty sure it was ok. Run the tests; the test still fails! This time our test was wrong: we'd misunderstood the way you have to do POST requests with Java's URL classes (you can't have any parameters on the URL line, you have to put them all in the POST body). It took about 20 seconds to fix it and we ran the tests again - success! This deserved a new version, g1.1.13, and another beer.

4. For the next test we almost overdid it again: we thought we wanted to test that the servlet could give us the right HTML form for editing a page, and that when we POSTed from the form, our new text got saved correctly. But of course we'd already done the second part in our previous test. All we really needed in this test was to do an HTTP GET including the "edit" parameter and check the HTML page that we got back. Again we could use a direct method call to find out what text should be inside the returned form's edit box. This test was easy to write, although we ended up with a big string literal that was being compared with what the servlet returned. Run the tests! The new test fails - no problem.

5. We changed the servlet to handle the "edit" parameter. Actually it already did this but it didn't return an HTML form. The form needed the servlet's own address in it so that the browser knew where to POST to. For a while we got horribly sidetracked trying to find a smart way to get a servlet's own URL from Sun's servlet classes, then we suddenly realised that of course we weren't DoingTheSimplestThing. So the servlet got a great big string literal as well - exactly the same one as the test of course. It was shouting to be refactored but no - run the tests first! They all passed.

6. Now we got to refactor that horrible great big string literal. OliBye had clearly done this before and introduced a sneaky use of java.text.MessageFormat, which lets you use strings like "My first param is {0} and my second is {1}" and then substitute an array of values for the {}s. We used {}s for the servlet's own URL (to go in the form), the page name, and the page content. Both the servlet and the test now use the same string literal with the {}s in. Run the tests! Everything passed - so we made this version g1.1.14 (https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/?only_with_tag=g1_1_14).

You can see the testing code we added at https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/TestServlets.java.diff?r1=1.1.1.4&r2=1.1.1.5&only_with_tag=g1_1_14

And the implementation changes at https://xpdeveloper.com/cgi-bin/cvsweb.cgi/xtc/com/xpdeveloper/PageSaver.java.diff?r1=1.1.1.3&r2=1.1.1.4&only_with_tag=g1_1_14 - see what we mean about that big string literal? ;)

Just for fun (or perhaps because we're still not used to trusting the tests enough) we left the servlet test environment running, and tried our changes out in a browser. They worked fine, but we realised we'd missed something out: the POST needed to return something like "Thanks for your edits", or the new page content. Was this missing from the original story or just from our 'engineering task' interpretation of it? We weren't sure, but all our tests ran and we'd done enough so we noted it down on the story card and left it for next time.

  • Once again we were rushing to get something done inside our FifteenMinuteTimeBoxes - either a new test, or making a test pass, or refactoring. We started off badly and went way over time for our first TimeBox?, but once we got going we were ok.

  • We kept spotting things that suggested we should Wiki.RefactorMercilessly?, but by the end of the night we hadn't refactored them: for example, all these bits of code that keep doing HTTP GETs in the tests are certainly not in there Wiki.OnceAndOnlyOnce? - they even have duplicate string literals in them for the "/servlet/" part of the URL. We felt we weren't being extreme enough about refactoring, and the code was right there to prove it. It was interesting how uncomfortable this made us feel, now that we're becoming more aware of how to refactor. More refactoring needed next time.


UnitOfLoadFactor?

After the session, TimM, OliBye and SteveFreeman got into a discussion about the granularity of LoadFactor. After much to-ing and fro-ing (do we measure per-individual, per-subgroup, per-group, etc), we came down to the notion that you should measure the LoadFactor of the the unit that you're scheduling. For example, in the PlanningGame, the unit is the entire group. For CommittmentSchedules? the unit may be individual developers (according to KentBeck's EmbracingChange? book); TimM prefers still to schedule by the group. OliBye has only tried doing it at the group level and looks forward to trying the other levels to see if they're useful. ³rev³42³host³³date³April 16, 2001³agent³Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 4.0)³XtC2809199 ³³XtC28091999


Edit this page   More info...   Attach file...
This page last changed on 16-Apr-2001 16:39:24 BST by unknown.