
I must say I’m quite impressed.
Today, I was watching a conversation on the TDD list about how “bugs” got into NUnit if it was built using TDD. Charlie Poole gave a great rebuttal, but one of his responses caught my attention:
>>>* NAnt build script failing under Linux due to use of
>>> backslash as a
>>> file separator.
>> That’s not a bug, it’s a build issue.Sure, and it would be better to catch it. The problem is, nobody actually builds NUnit under Linux until after we release it. There’s someone out there who could solve that problem for us. You know who you are. You know what to do. :-)
Well, heck, I love NUnit. I also run Linux. So I shot an email off to Charlie, and it turned out that no one was running builds of NUnit on Linux until after it was released. I offered to fill that role, and he suggested I grab the latest version and try to build it.
Build it? Surely it uses csc.exe or at least NAnt? And indeed, upon getting the source, it has a nunit.build. Undeterred, and knowing that they are running NUnit on Linux, I decided to give it a go with Mono.
First, I headed over to the Mono projects downloads page and found they had a universal installer. Gentoo had Mono in Portage, but it didn’t seem to be the latest version yet. I downloaded the installer, followed the Simple instructions, and whammo, had Mono on the system.
Feeling particularly good, I Googled for “NAnt Mono” and sure enough, came across an excellent reference on the Mono site. So I grabbed the latest NAnt source tarball, ran make and make install, and noticed that suddenly I could type in nant -help and, sure enough, had the NAnt help screen.
Feeling inspired by the Olympics streaming from the TV in the living room, I decided to go for gold. I changed over to the NUnit src directory, and ran NAnt. And it died. It was having problems with mcs, the mono C# compiler. Actually, it couldn’t find it. Luckily the error was enough to make me realize that somewhere there was a symbolic link reference to it that was being used by bash, and sure enough, in my ~/.bashrc file I had a reference to the mono-1.1.6 bin directory as I had deleted it (and not uninstalled it). Cleaning that up, I reran the NUnit build with:
foyc@dilbert ~/apps/nunit/2.3.6050/build/mono/1.0/release $ ~/apps/nant/bin/nant mono-1.0 release build test
And it worked.
Well, some of the tests failed. But, I had a build/mono/1.0/release directory that contained (among others) nunit-console.exe. And running it nunit-console nunit-console.tests.dll worked.
So, I must say that I am quite impressed. Even the MonoDevelop IDE seemed like a decent IDE (though I didn’t spend much time with it). And I think I’ll be playing with it some more.
Great job Mono, NAnt and NUnit teams, and all the developers that work to make this possible.
There is a great thread on the XP list right now discussing Metaphors in the context of XP. Metaphors are basically a common language of how a system works, ideally based on domain terms. However, I found the following post by Kent Beck to be particularly enlightning:
Teams work more effectively when members have personal perspectives on a shared understanding of the system and the problems it addresses. When I want to gauge a team’s shared understanding, I ask members individually to explain their system to me using four objects. If everyone comes up with similar objects, they share a metaphor. Wildly divergent objects suggest the team could benefit from working on shared understanding.
It really is amazing how much having a clear language between customers and developers (and even managers) impacts a project. One of the first things I do is have our customers explain how they define specific terms. Or, have them explain to me what they think our terms mean. For example, we ran into a recent situation where we told the customer we would deploy a sample report with test data so they could practice integrating it with their systems. They then proceeded to call us back and tell us that things were horribly bad because the data didn’t change when they tried other requests.
We found out that the problem was in the lack of definition of the term “deploy” and “sample report”. But because we thought we were clear enough, and felt like they understood it well enough (without actually asking them), it led to miscommunication.
On the flip side, we worked on a project several years ago where we defined very clearly the domain terms between the customer and the developers. The project couldn’t have gone any smoother – their expectations from us where clear, and we delivered the expected features on time.
If anyone is going to NFJS, or will be in the St. Louis area on Friday, March 3rd, the St. Louis Ruby User’s Group is putting together a dinner during the Friday night dinner slot at NFJS. Here’s the announcement:
We are going to have a dinner gathering of Rubyists in St. Louis during the No Fluff Just Stuff conference. This will celebrate the 1 year anniversary of the St. Louis Ruby Users Group and give us a chance to meet fellow Rubyists who may be in from out of town.
Friday, March 3 at 6:30pm we are hosting a Rubyist get together over dinner, to include out-of-towners who will be here for the No Fluff Just Stuff, Gateway Software Symposium. This may include some surprise “guest stars” (no guarantees, though). This will also celebrate the 1 year anniversary of the St. Louis Ruby Users Group. If you want to come, add your name to this list by Monday, February 27th so we can make reservations:
http://stlruby.org/ruwiki/ruwiki.cgi/Default/RubyDinner
If possible, we will make reservations at the conference hotel (Mariott St. Louis West, 660 Maryville Centre Drive, St. Louis, MO 63141). But if we have too many people we may have to go elsewhere.
I’ve been working with the great Ruby Eclipse project (which if you haven’t played with, download and then go through the tutorial. It’s been working flawlessly on my XP Laptop, but I hadn’t been able to get it to work on my Linux box. Basically, with both 0.6 and 0.7 versions, I would go to Project->New->Ruby and would get an error that it could find the class org.rubypeople.rdt.internal.ui.wizards.NewProjectCreationWizard. There was very little info on the web about it, but I had a hunch.
I was running Eclipse 3.1, but it got to 3.1 bu /upgrading/ from 3.0. My laptop had a fresh install of 3.1. And sure enough, removing the 3.0/3.1 app files and running a fresh 3.1 install with the RubyEclipse plugin added worked like a charm.
I had gotten this several months back from Kelly Anderson, but since he’s posted it for the world to see I’m going to pass it along:
The FrAgile Manifesto (Version 2.2)
We are uncovering more profitable ways of developing software by doing it fast and making lots of money.
Through this work we have come to value:
- Profits and deadlines over individuals, interactions, processes and tools.
- Mostly working software over elegant software
- Customers whose checks clear over customer collaboration directly with development
- Responding to changing directives based on market research over following a technical plan
That is, while there is value in the secondary items, we value the primary items more.
We follow these principles:
Our highest priority is to satisfy the customer through rapid and on time delivery of software that mostly works, and to provide affordable (but profitable) customer service in those cases where it doesn’t work out.
We code to the requirements, because the development cycle is too short to implement any changes (unless those changes are absolutely necessary). If there are no requirements, we do the best we can.
We deliver working software frequently, every few months. Not during actual development, because customers or other departments might ask for changes that would make meeting deadlines harder if they knew what we were really developing. Developers must never communicate directly with customers. Under no circumstances should developers ever communicate directly with sales or marketing unless fighting over a parking space.
Business people and developers must work together every now and again throughout the project. But not too often, because programmers don’t like meetings and it wastes time that could be spent hacking in code for the latest marketing checkbox.
Development must not provide code or executables to test until the official test cycle begins. To do so earlier might result in feedback, and we all know what that sounds like. Feedback slows development because we might develop the wrong thing, and if we had feedback we might have to start over. It’s much easier to say, “It’s too late in this cycle to change that.”
Build projects around individuals who like to get paid. They’ll do what you ask without much pushback. Give them a computer and supervise them continuously until the job gets done.
The most efficient and effective method of conveying information to and within a development team is to ask for surprise demonstrations with only a few minutes notice.
Kind of working software is the primary measure of progress. Integration should be delayed until late in the process so that nobody gets distracted by other people’s work. This recognizes that all developers think that all other developer’s work is crap. Avoiding technical arguments is key to the FrAgile process.
FrAgile processes promote not putting too much effort into development and even less into design. The sponsors, developers, and users should be able to maintain a constant pace indefinitely. Except when they must work overtime during integration, and then we recognize them publicly for their extra effort in keeping management looking good.
Every developer is responsible for their own work, and is not strongly encouraged to share code with one another; communication takes time, and makes meeting deadlines harder. It’s cheaper to rewrite code over and over than to have valuable programming time spent talking about esoteric subjects like “architecture”. Every programmer should use only the tools and class libraries that they are already familiar with, because learning stuff takes time away from meeting deadlines.
Simplicity is important, but maximizing the amount of work done is essential. Doing your own design and implementation independently of other programmers helps to ensure that your code can’t get more complex than you can understand by yourself.
The best architectures, requirements, and designs emerge from self-organizing teams. But we recognize that you don’t need any of these to make buckets of money. This is especially the case if individual programs don’t get too large and unwieldy. The program as “object” keeps programs from getting out of hand.
Meetings of any kind involving developers are to be avoided if at all possible. Meetings take time away from producing code. Communication between programmers can only lead to coding standards and architecture, which only distract programmers from the immediate task at hand; building programs that reach the market first so they can be sold quickly and profitably. There is no shame in being second, but there is no profit either. The first vendor to lock in the customer base wins.
Keep projects small. No project should require more than two man years of development. If projects accidentally get large due to their popularity, release maintenance releases with gradual evolutionary improvements or break it up into separate individually maintainable products.
Under no circumstances ever throw away old code. We recognize the value of code that’s kind of worked for many years. It’s been tested by hundreds of users and it’s been sort of fixed over the years. That gives it value. New code will have new bugs. Never, under any circumstances refactor code unless absolutely necessary.
Change and retraining are expensive. New development technologies should be adopted only when the old development technologies are no longer viable. Only those technologies that are widely accepted by the entire software development industry should be entertained. Choosing a new development technology is primarily a business function, not a technical one.
Avoid the implementation of standard file formats and data interchange methodologies insofar as is possible. If you create a migration path for your customers to escape, many will undoubtedly do so over time. Obscure binary file formats are our friends.
Always pick projects that are neither too vertical (such as internal enterprise applications), nor too horizontal. Find a niche market where the customers are non-technical. This is important to avoid competition from those pesky open source communists in Europe.
Branching code in your revision control system is a great way to stay out of the other programmer’s way. Time wasting multi file refactoring is thus discouraged, because it would make merging branches later too difficult.
We value swamp guides over architects. Building a four lane highway across the swamp tomorrow is less important than keeping the alligators from chewing body parts off today.
Always remember that while the programmers down the street working for the struggling startup are writing elegant code, our paychecks are actually signed.
In a recent post, I showed you how to create a basic Fitnesse ColumnFixture test using C#. However, ColumnFixtures are but one test table style available in Fitnesse. I was asked in the comments of my last post to do a tutorial around another style – the ActionFixture.
What is an ActionFixture? Let’s say you have a test which is a sequential series of steps. For example, suppose we have a simple calculator. Users can add numbers together to get the sum, and clear the display. So we may want to test that when a user presses 2, hits add, presses 4, and hits equals, the display shows the number 6. ActionFixtures are made for this kind of thing. However, actually getting them to work in C# can be a little tricky, but nothing that one can’t overcome.
We’ll start with our Calculator class. We have add, clear and display methods, in addition to methods for each digit. To sum, we just split on the plus sign, and add up the numbers:
using System;
using System.Text;
namespace FitnesseTutorial
{
public class Calculator
{
private StringBuilder displayLine;
public Calculator()
{
displayLine = new StringBuilder();
}
public void add()
{
displayLine.Append("+");
}
public void clear()
{
displayLine = new System.Text.StringBuilder();
}
public string display()
{
return displayLine.ToString();
}
public void sum()
{
String line = displayLine.ToString();
String[] numbers = line.Split('+');
int total = 0;
foreach(String number in numbers)
{
int num = int.Parse(number);
total += num;
}
displayLine = new StringBuilder();
displayLine.Append(total.ToString());
}
public void one()
{
displayLine.Append("1");
}
//same as one for the other digits
}
}
With that code in mind, our Fitnesse test seems pretty easy. We want a way to enter numbers, press sum, and check the display. Something like:
|check|display|blank|
|press|one|
|check|display|1|
|press|add|
|press|2|
|press|sum|
|check|display|3|
would be fantastic. So how do we get there? Looking again at the ActionFixture, it looks like we should create a fitnesse test like:
!define COMMAND_PATTERN {%m %p}
!define TEST_RUNNER {dotnet\FitServer.exe}
!define PATH_SEPARATOR {;}
!path C:\FitnesseTutorial\bin\Debug\FitnesseTutorial.dll
|Action Fixture|
|start|!-FitnesseTutorial.CalculatorTest-!|
|check|display|blank|
|press|one|
|check|display|1|
|press|add|
|press|two|
|press|sum|
|check|display|3|
To create my test fixture, I’m going to have to duplicate a lot of the methods from my calculator so I can delegate them to it. (This was one of the few instances where I wished for multiple inheritence so I could just subclass ActionFixture and Calculator, but I digress).
using System;
using fit;
using fitnesse;
namespace FitnesseTutorial
{
public class CalculatorTest : fit.ActionFixture
{
private Calculator calculator;
public CalculatorTest() : base()
{
calculator = new Calculator();
}
public void add()
{
calculator.add();
}
public void clear()
{
calculator.clear();
}
public string display()
{
calculator.display();
}
public string sum()
{
calculator.sum();
}
public void one()
{
calculator.one();
}
//more number delegation
}
}
So, we’ve got our Fitnesse test, we’ve got our fixture, and we’ve got our target class. We should now be ready to run the test and see a nice green bar:
Ah, forgot the namespace. ActionFixture is in the fit namespace, so I’ll just add that to the test by saying:
|!-fit.ActionFixture-!|
(The !- -! around the name escapes it from being treated as a Wiki word. Without this, Fitnesse will see it as “fit.ActionFixture?” because that’s what the wiki makes it to be if you don’t have a page defined for that word)
Ok, with that hiccup, let’s get that green bar:
Huh. Well, I can’t even add the image, because it’s too big. But, every method after start failed with:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at fit.CellOperation.GetAccessor(Fixture fixture, String memberName)
at fit.CellOperation.Check(Fixture fixture, String memberName, Parse cell)
at fit.ActionFixture.Check()
--- End of inner exception stack trace ---
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean verifyAccess)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodInfo.Invoke(Object obj, Object[] parameters)
at fit.MethodAccessor.Set(Fixture fixture, Object value)
at fit.ActionFixture.DoCel
ls(Parse cells)
After some digging, and discussion on the Fitnesse mailing list, I discovered that there seems to be a bug in ActionFixture for C#, so we need so subclass it and set a variable so the parents know what the object we are working on is. In other words, change your Fitnesse test to look like:
|!-FitnesseTutorial.CalculatorTest-!|
|start|!-FitnesseTutorial.CalculatorTest-!|
|check|display|blank|
|press|one|
|check|display|1|
|press|add|
|press|two|
|press|sum|
|check|display|3|
meaning your Fitnesse test will use your fixture instead of the base ActionFixture. Then, modify the constructor for your fixture to look like:
public CalculatorTest() : base()
{
targetObject = this;
calculator = new Calculator();
}
the change is bolded above. targetObject is a protected field from ActionFixture that isn’t set for some reason, even though it is needed. So, with that change, we rerun the test:
And we have a green test!
So, lessons learned. Writing an ActionFixture is pretty straightforward, as long as you remember to have the Fitnesse test use your custom fixture instead of the base ActionFixture.
Code:
I subscribe to an excellent magazine from O’Reilly called MAKE Magazine. It is aimed at DIY hobbiests, and includes things such as how to build your own portable Atari system, and how to build a digital camera for kite flying.
It also includes articles that can cause more harm if you don’t know the basics of electricity. And even if you follow the instructions, you could still get in trouble if you think that is all you need to do, as referenced by the following email I got yesterday:
The “How to Build a Power Tap” page in MAKE 05, page 112, contains an error that could cause an unsafe wiring situation. Before attempting this project, please read the corrections posted at http://makezine.com/05/quickanddirty.
PLEASE DO NOT BUILD THE POWER TAP AS SHOWN IN THE ILLUSTRATION.
The illustration shows a dual plug receptacle, which, when wired improperly, can cause a short circuit. Do not attach the wires from the extension cord to the screws on the same side of the receptacle, because it will create a short circuit.
My Beyond Java review finally got posted to Slashdot (only two months after I submitted it ;). I was pleasantly surprised at the conversation it sparked about various languages (even Lisp!), dynamic typing, and a host of other things. I’d recommend popping over to it (with the threshold on 4) and checking it out for the interesting links.
One of the things I miss in going from .NET back to the Java world is .NET properties. Yes, it was just a code hack that was really rewritten as setters in the CLR, but it was a /nice/ hack. ;)
In other words, I could get and set what appeared to everything to be a field, but was really a method. So I could say myObject.Name = "My Name" with the following code:
public String Name
{
get{return name;}
set{name = value;}
}
where value is a special keyword for the value passed in for setters.
I find myself mostly wanting this in the Java version of Fitnesse where to have it set values you have to expose a public field. Since technically your class Fit is calling should just immediately delegate off to the real business objects, it’s not usually a big deal. However, since the Python and .NET versions allow it, and the Java one doesn’t, I wanted to get it working.
It turns out that it is a fairly painless change, but requires modification to three core files in the fit package of Fitnesse. So, first, you need to download the source, and make sure you also have Ant so that you can build the package.
Got it? Good. The first file to change is fit.Fixture (Fixture.java in the fit directory). At line 310, add the following (where commented – surrounding text is the context):
else if (type.equals(Date.class))
{
return DateFormat.getDateInstance(DateFormat.SHORT).parse(s);
}
//Add to handle void objects
else if (type.equals(void.class))
{
return s;
}
//End Add
else if (hasParseMethod(type))
{
return callParseMethod(type, s);
}
Next, modify fit.TypeAdapter (TypeAdapter.java) to handle VoidAdapters. The first change is at line 58, to add a void handler:
if(type.equals(boolean.class)) return new BooleanAdapter();
//Add for VoidAdapter
if(type.equals(void.class)) return new VoidAdapter();
//end Add
throw new UnsupportedOperationException("can't yet adapt " + type);
Second, at line 137 to actually define a VoidAdapter:
// Subclasses ///////////////////////////////
//Add VoidAdapter
static class VoidAdapter extends TypeAdapter
{
public void set(Object i) throws IllegalAccessException, InvocationTargetException
{
Object[] params = new Object[]{i};
method.invoke(target, params);
}
}
//End Add
static class ByteAdapter extends ClassByteAdapter
{
public void set(Object i) throws IllegalAccessException
{
field.setByte(target, ((Byte) i).byteValue());
}
}
Finally, we change fit.Binding (Binding.java) so that when a column matches the normal field regex, it tries to instatiate a method as well as a field. Change the method makeAdapter to the following:
private static TypeAdapter makeAdapter(Fixture fixture, String name) throws Throwable
{
Matcher matcher = methodPattern.matcher(name);
if(matcher.find())
return makeAdapterForMethod(name, fixture, matcher);
else
{
TypeAdapter adapter = null;
matcher = fieldPattern.matcher(name);
if(matcher.find())
{
try
{
adapter = makeAdapterForMethod(name, fixture, matcher);
}
catch(NoSuchMethodFitFailureException ex)
{
adapter = makeAdapterForField(name, fixture);
}
}
else
{
adapter = makeAdapterForField(name, fixture);
}
return adapter;
}
}
and change makeAdapterForMethod to the following:
private static TypeAdapter makeAdapterForMethod(String name, Fixture fixture, Matcher matcher)
{
Method method = null;
if(GracefulNamer.isGracefulName(name))
{
String simpleName = GracefulNamer.disgrace(name).toLowerCase();
method = findMethod(fixture, simpleName);
}
else
{
String methodName = matcher.group(1);
method = findMethod(fixture, methodName.toLowerCase());
}
if(method == null)
throw new NoSuchMethodFitFailureException(name);
return TypeAdapter.on(fixture, method);
}
With these changes all Unit and Fitnesse tests should pass – save one: testUseOfGracefulNamingForMethods() in fit/BindingTest.java. To make it pass, I changed all of the checkForMethodBinding calls to true:
public void testUseOfGracefulNamingForMethods() throws Throwable
{
checkForMethodBinding("intMethod()", true);
checkForMethodBinding("int Method?", true);
checkForMethodBinding("int method?", true);
checkForMethodBinding("intmethod?", true);
checkForMethodBinding("Intmethod?", true);
checkForMethodBinding("IntMethod?", true);
}
Once you’ve made the changes, run build.xml and move the fitnesse.jar file that is created into your Fitnesse installation directory (you probably should rename the existing fitnesse.jar in case anything goes wrong) and start up your Fitnesse server. I used a test like:
|com.cornetdesign.fitnesse.examples.MethodSetTest|
|methodSet|valueSet?|
|test|test|
|booyah|booyah|
with code:
package com.cornetdesign.fitnesse.examples;
import fit.ColumnFixture;
public class MethodSetTest extends ColumnFixture {
private String val = "";
public void methodSet(String value)
{
val = value;
}
public String valueSet()
{
return val;
}
}
and voila! You should have a green test.
I’ve already sent this off to the Fitnesse guys, but haven’t had any reply from the Java maintainers as to whether this would be usable – so if it is something that is worthwhile to you let me or them know.