This post in an introduction to Fantom via the refactoring of Java code.
TL; DR: Fantom is basically a better Java with a very similar syntax, but with lots of little simplifications and some powerful features such as functions.
This post in an introduction to Fantom via the refactoring of Java code.
TL; DR: Fantom is basically a better Java with a very similar syntax, but with lots of little simplifications and some powerful features such as functions.
On March 18th, I received the following email:
On 18 March 2012 16:26, Jen Rhee <thisisjenica@gmail.com> wrote:
Hi Eric,I came across your site and wanted to share my infographic about Wikipedia and how it’s redefining the way we research. I saw that you had talked about the first wiki developer, Ward Cunningham, which is why I thought you and your readers might find it interesting! Would you be interested in taking a look? Let me know, as I’d love to get your thoughts on it!
Thanks,
Jen R.
I have never heard of that person. I had mentioned Ward Cunningham a couple of times on my blog, although never in relation to wikis. I thought this was a curious email, and decided to ignore it.
Week 2 of the Seven Languages in Seven Weeks book is about the Io Language. Day 3 is more specifically on how the flow of control (how messages are passed to an object or to its parent) can be hijacked to create a DSL.
In this post, I am going to describe an interesting feature in Io, and how I extended it a bit to enhance an XML generator.
Apache VFS is a great way to access different file systems in the same way. I particularly like the custom RAM filesystem in my unit tests in order to check code that eventually accesses the actual file system.
For example:
StandardFileSystemManager manager = new StandardFileSystemManager();
manager.init();
manager.resolveFile("ram://root/file.txt").createFile(); // prepare test harness
...
manager.resolveFile("ram://root/file.txt").getName(); // do something useful
Annoyingly, Apache VFS API provides a way to check if a file/folder is hidden, but, although it is always possible to manually create hidden files on your system, there is no way to mark a file as hidden in the RAM filesystem.
manager.resolveFile("ram://root/file.txt").isHidden(); // returns false
manager.resolveFile("ram://root/.file.txt").isHidden(); // also returns false
The solution is to modify the RAM filesystem and customize its checking of the hidden attribute. This means that we need a new RamFileProvider, a new RamFileSystem and finally a new RamFileObject.
My former colleague David just posted an example of verbose test code on his blog (the parts in French have been translated to English by myself):
/**
*
*/
@Test
public void testGetCustomerOK() {
LOGGER.info("======= testGetCustomerOK starting...");
try {
CustomerDTO targetDTO = this.serviceImpl.getCustomer("ABC99");
// Check.
Assert.assertNotNull("Extra not found.", targetDTO);
Assert.assertEquals("accountIds must be the same.", "ABC99", targetDTO.getAccountId());
} catch (CustomerBusinessException exception) {
LOGGER.error("CustomerBusinessException : {}",
exception.getCause());
Assert.fail(exception.getMessage());
} catch (UnavailableResourceException exception) {
LOGGER.error("UnavailableResourceException : {}",
exception.getMessage());
Assert.fail(exception.getMessage());
} catch (UnexpectedException exception) {
LOGGER.error("UnexpectedException : {}" +
exception.getMessage());
Assert.fail(exception.getMessage());
} catch (Exception exception) {
LOGGER.error("CRASH : " + exception.getMessage());
Assert.fail(exception.getMessage());
}
LOGGER.info("======= testGetCustomerOK done.");
}
Let’s see what I’d do with that.
“Adding manpower to a late software project makes it later”. The so-called Brooks’s Law on productivity of software project is well known, since Fred Brooks’ seminal work The Mythical Man-Month, first published in 1975.
That is one of the reasons I’m wince a little when a company talks about plans to hire lots of software developers.
This recent study by QSM seems to prove me right. Its conclusion seems to be that Brooks’s Law can be extended to projects that are not late. At any rate, code is not produced at a faster pace with more manpower.
Do you know what’s worse that static methods or classes marked as final? I’ll tell you what’s worse: static methods that return final classes. That only provides private constructors.
Here I was, merrily testing my way through a piece of software that sends emails. According to the Java Mail documentation, you are supposed to first create an email session as follows:
Session mailSession = Session.getInstance(properties);
(it is worth noting that all what the getInstance() method does is call the private constructor for Session: new Session(props, null)).
Had Session been a more normal class, I could have mocked it like that:
Session mockSession = mock(Session.class);
and probably checked how it is being passed around like this:
verify(someService).startEmailSession(mockSession);
What follows is what I have to do instead.
Here is a typical example of a test method
@Test
public void should_search_by_path() {
Searcher searcher = new Searcher();
Path location = new Path("somewhere");
String data = "data";
searcher.putAt(data, location);
assertThat(searcher.findAt(location), is(data));
}
It seems that many developers consider this good code. I don’t. My main gripe here is that the presence of variables does not add much useful information. Instead, they make the code too verbose.
A first rewrite would produce something like that:
@Test
public void should_search_by_path() {
Searcher searcher = new Searcher();
searcher.putAt("data", new Path("somewhere"));
assertThat(searcher.findAt(new Path("somewhere")), is("data"));
}
Shorter, which is good. I also like the fact it makes clear that it is the value of the parameters that matter, and not their pointers.
We can go further by leveraging local static methods.
@Test
public void should_search_by_path() {
Searcher searcher = new Searcher();
searcher.putAt("data", path("somewhere"));
assertThat(searcher.findAt(path("somewhere")), is("data"));
}
private static Path path(String path) {
return new Path(path);
}
(a static method is not mandatory, but I think it makes its intention of being a utility method clearer)
And, finally, if this test class is dedicated to the Searcher class, I would probably make the searcher variable a field, as it would be used in most test methods.
private Searcher searcher = new Searcher();
@Test
public void should_search_by_path() {
searcher.putAt("data", path("somewhere"));
assertThat(searcher.findAt(path("somewhere")), is("data"));
}
private static Path path(String path) {
return new Path(path);
}
This is more lines than the original example. However, the searcher variable is on top of the class and the path() method is at the bottom, far out of the way of the test methods. Indeed, I would often have several such static methods at the bottom of my classes (and, rarely, one or two more instance variables at the top). I even tend to do so when I have such a single method using them.
Beside the fact that the method has fewer lines, I also like that it makes for more fluent code. It almost reads like a story “when the searcher is being put a String of value ‘data’ at the path of name ‘somewhere’, then it should be able to assert that the String found at the path of name ‘somewhere’ has value ‘data’”.
Another example, so that my position is clear:
@Test
public void should_find_by_address() {
String aValidAddress = "10 Downing Street";
Person aPerson = new Person("David Cameron");
contacts.put(aValidAddress, aPerson);
assertThat(contacts.get(aValidAddress), is(aPerson));
}
I’d very much rewrite this as follows:
@Test
public void should_be_able_to_find__a_person_when_storing_with_a_valid_address() {
contacts.put("10 Downing Street", person("David Cameron"));
assertThat(contacts.get("10 Downing Street"), is(person("David Cameron")));
}
Any thoughts?
At Devoxx last week, Joshua Bloch argued during his talk “The Evolution of Java: Past, Present, and Future” that varargs are only “somewhat useful”. I think he is overlooking some usages, particularly in tests. Here is my case.
A reminder on how varargs work: essentially, they allow the last parameter of a method to be made of zero to many values of the same type.
For example, a method like this:
int max(int... values) {...};
is used by code like that:
int maximum = max(1, 2, 7, 0); int maximum = max(1);
In truth, that form is only moderately useful in production code. It turns out that, on my projects at least, it is not so common for methods to be called with varying number of parameters. And in those cases, it is often acceptable to simply overload a method with more parameters.
There are however at least two cases where varargs shine.
One is in utilities classes. For example, Math.max() only takes exactly two parameters. Which comparisons between 3 or more elements very awkward. If a varargs had been used, Math.max(3, Math.max(1, 4)) would be written Math.max(3, 1, 4). Agreed, that does not happen that often. But it does occasionally.
(I must admit that I do not understand exactly why Math.max() has not been modified to take a varargs nowadays)
However, the biggest benefit, I believe, is in the writing of tests.
Tests tend to contain lots of variations in the values passed to the code under test. And it is critical to keep the clutter to a minimum.
For example, here is how a typical series of tests might look like
@Test
public void should_find_the_longest_name_for_a_single_user() {
List users = new ArrayList();
users.add(new User("eric"));
assertThat(findLongestName(users), is("eric"));
}
@Test
public void should_find_the_longest_name_when_shorted_is_first() {
List users = new ArrayList();
users.add(new User("eric"));
users.add(new User("cecile"));
assertThat(findLongestName(users), is("cecile"));
}
@Test
public void should_find_the_longest_name_when_longest_is_first() {
List users = new ArrayList();
users.add(new User("cecile"));
users.add(new User("eric"));
assertThat(findLongestName(users), is("cecile"));
}
@Test(expected = RuntimeException.class)
public void should_fail_when_search_for_the_longest_name_with_no_users() {
assertThat(findLongestName(new ArrayList()), is("eric"));
}
Of course, they can be made a bit nicer using the varargs in Arrays.asList():
@Test
public void should_find_the_longest_name_for_a_single_user() {
assertThat(findLongestName(asList(new User("eric"))), is("eric"));
}
@Test
public void should_find_the_longest_name_when_shorted_is_first() {
assertThat(findLongestName(asList(new User("eric"),
new User("cecile"))), is("cecile"));
}
@Test
public void should_find_the_longest_name_when_longest_is_first() {
assertThat(findLongestName(asList(new User("cecile"),
new User("eric"))), is("cecile"));
}
@Test(expected = RuntimeException.class)
public void should_fail_when_search_for_the_longest_name_with_no_users() {
findLongestName(Arrays.asList());
}
However, the real goodness comes when writing our own builder method:
private static List users(String... names) {
List users = new ArrayList();
for (String name : names) {
users.add(new User(name));
}
return users;
}
(side note: I like this type of methods to be private -so that I get notified when they are not used anymore- and static -mostly because they look nicer in italic, which makes it clearer that they are not part of the code being tested-)
which allow our tests to become:
@Test
public void should_find_the_longest_name_for_a_single_user() {
assertThat(findLongestName(users("eric")), is("eric"));
}
@Test
public void should_find_the_longest_name_when_shorted_is_first() {
assertThat(findLongestName(users("eric", "cecile")), is("cecile"));
}
@Test
public void should_find_the_longest_name_when_longest_is_first() {
assertThat(findLongestName(users("cecile", "eric")), is("cecile"));
}
@Test(expected = RuntimeException.class)
public void should_fail_when_search_for_the_longest_name_with_no_users() {
findLongestName(users());
}
Tests become a lot shorter, consistent, and easier to read. In fact, at this point, it is worth grouping the tests (at least those that do not throw an exception) into a single one:
@Test
public void should_find_the_longest_name_for_a_single_user() {
assertThat(findLongestName(users("eric")), is("eric"));
assertThat(findLongestName(users("eric", "cecile")), is("cecile"));
assertThat(findLongestName(users("cecile", "eric")), is("cecile"));
}
@Test(expected = RuntimeException.class)
public void should_fail_when_search_for_the_longest_name_with_no_users() {
findLongestName(users());
}
Final note: I prefer not to group those builder methods into a general utilities class — I tend to duplicate them in each test class. One reason is that I prefer keeping much of the test code close together. Another is that I tend to change the name of the method from test class to test class to make the code more fluent. Also, I think that DRY principles are not as important in the tests as they are in the production code.
Play Framework has a Guice module. Unfortunately, its use is fairly limited compared to what Guice can do. In this post, I describe how it is configured on my current personal project.
In general, when I test classes that have dependencies, my favorite approach is to pass those dependencies to the constructor:
public class MyService {
private final MyDependency myDependency;
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
Which makes creating test harnesses with Mockito reasonably easy:
public class MyServiceTest extends UnitTest {
@Test
public void shouldComputeAResult() {
MyDependency mockMyDependency = mock(MyDependency.class);
when(mockMyDependency.findSomeValue()).thenReturn("some value");
MyService service = new MyService(mockMyDependency);
assertThat(service.computeSomething(), equalTo("result"));
}
}
However, it appears that Guice, at least under version 1.1.1 of its Play module, can only be used with Play to inject into static members:
@InjectSupport
public class MyService {
@Inject
static MyDependency myDependency;
// no constructor (a default constructor will be
// generated automatically by Play Framework)
}
The @InjectSupport is what makes the Guice module detect that the class requires dependencies (a class that extends either com.google.inject.AbstractModule or play.modules.guice.GuiceSupport must also be present in the classpath).
This makes it hard to instrument classes under test, as the value for a mock instance of MyDependency is shared amongst all tests that run currently.
public class MyServiceTest extends UnitTest {
@Test
public void shouldComputeAResult() {
MyDependency mockMyDependency = mock(MyDependency.class);
when(mockMyDependency.findSomeValue()).thenReturn("some value");
MyService service = new MyService();
// static values are brittle;
// they should not be touched in unit tests
service.myDependency = mockMyDependency; // yuck!
assertThat(service.computeSomething(), equalTo("result"));
}
}
Many subtle problems may occur when injecting dependencies in this way. For example, all instances of MyServices used concurrently will point to the same dependencies instances, so it is possible that tests will behave in inconsistent ways. Also, it makes it harder to default to sensible (null) dependencies, since tests running in the same JVM will by default use dependencies set by the first test.
The solution I’m using is to add providers in your Guice module:
public class GuicyModule extends AbstractModule {
@Override
public void configure() {
// no code needed
}
@Provides
public MyService getMyService(MyDependency myDependency) {
return new MyService(myDependency);
}
}
In this way, you are making sure that the dependencies are passed as you wish. Also, it will not be necessary to add any sort of Guice-related code in my services:
public class MyService {
private final MyDependency myDependency;
public MyService(MyDependency myDependency) {
this.myDependency = myDependency;
}
}
The downside is that you do have a few more lines to maintain, which is never fun. Better than the alternative, though.
My thanks to David Gageot who told me about providers in Guice.
I’m returning from CITCON London 2010. What a great conference (and I’m not just saying that just because I helped organize it)!
In fact, I feel it has been the best CITCON so far. I was a bit afraid of the large crowd (150 people registered, a similar number to Paris last year; I’m not sure how many showed up. 120, maybe?), but it turned out easier than expected to discuss with other participants. Also, and most importantly, there was a feeling of a higher level of experience than usual. Few talks about the basics of tests or Continuous Integration (and no “what’s the best CI server” session at all, thank God). Instead, it was “Advanced TDD”, “Share Pair Programming experience”, “Mobile Testing”, etc. All good stuff and, as usual, I just couldn’t attend all the sessions I wanted.
As a side note, there were also less talk related to competing programming environment. Only a few people introduced themselves as working in Java, .NET or another programming environment. I can think of a couple of reasons:
In some ways, the Java world is also calcifying around some tools such as Maven (some contenders are barking at the door, though). But the feeling is that, by and large, things get done is a fairly productive way. (I’ll admit that I can be overly optimistic about this, considering that I am in a Java shop (Algodeal) where the incredible freedom helps us being particularly efficient)
Now, I was surprized that few mentioned up-and-coming languages such as Scala and Clojure. Are they just being lumped into the Java category? Was CITCON London the wrong area to find experts in them?
Other highlights of the conference include the venue. Thank you ever so much, Wendy, for opening the doors of SkillsMatter. You went out of your way. The location was fantastic, and the venue perfect for us. I especially appreciated the powerful wifi internet access, a rarity even in fancy hotels.
I also appreciated the fact that this area London has large pubs that can host all willing participants after the conference is over (this was frustrating in Paris last year, where bars can be small and especially crowded on Friday evenings). Too bad music can be so loud there, making conversations sometimes difficult.
A few things to remember from CITCON London:
For CITCON 2011, there were many votes for Berlin. Sounds like a good destination. Again, it will depend on whether we can get a cheap enough venue there.
Have you noticed that few Agile luminaries earn a living from writing and selling software? Many do write code as consultants. Other are respected authors of non-commercial open-source development tools. Some do work for software companies such as RallyDev or ThoughtWork Studios, though it seems that most visible presenters coming from there are consultants or at least business-facing types. But almost none actually make money directly by doing what they teach others to do.
James Shore mentioned working on his own startup with Arlo Belshee and Kim Wallmark, but that was more than a year ago and we haven’t heard much since. Ward Cunningham is CTO of a website, which come reasonably close to being a software house. In fact, Kent Beck is the only example I know of someone who actually tries to make a living out of writing and selling software (with mixed results). Tellingly, Ward and Kent are not very visible on the conference circuit anymore (though they are certainly interviewed regularly).
This lead to an interesting discussion yesterday on Twitter with Deborah Hartmann Preuss, Alexandru Bolboaca, Willem van den Ende, Brian Marick, and Jeffrey Fredrick (see transcript at the end of this post).
I think most Agile personalities have become addicted to the relatively easy money of consulting. Why would they risk get a software product out in the highly competitive software market? It is so easy to just found your own consultancy. It is probably related to age, too, as you do need to have lots of spare energy for late night coding (Paul Graham once wrote that the ideal age to start a startup was between 23 and 38).
In fact, as I argue below, I do not believe that “being agile” is viewed as a desirable trait for a startup and I’m sure it might even deter some of the most likely candidates to create one, as it is now viewed as a process for medium to large companies. What is viewed as needed is raw hacking powers, even if that means making things hang together with duct tape. Agile techniques might be preferable, but their ROI will become mostly apparent after two years, an eternity for a startup.
So, Agile luminaries are not starting software development ventures, and the founders of successful startups that use Agile techniques probably do not have the time or the will to tell the rest of the Agile world how they did it.
This is regrettable. I wish there was more cross-pollination, like 37signals has done with Getting Real. Where are the others?
Transcript of our conversation on twitter:
For my Remote Pair Programming session with Alexandru Bolboaca, I wanted to work on our actual code, not toy programs. It was hard finding a technical solution to allow this (despite the many suggestions I received on Twitter; the biggest issue is sharing the entire development environment), but I finally settled on LogMeIn. LogMeIn basically lets you create an ad hoc VPN with them serving as a middle man. The great thing with it is that all the configuration is done on the client machines. There is nothing to change on firewalls (especially important for the other people that you are working with).
LogMeIn has a download that seems very simple to use… as long as you are under Windows. It also has a Mac OS X version and a Linux version, but they hardly come with any documentation. What’s worse, it is hard to find additional information on the support site.
So, for your eyes only, here are some instructions on how to get LogMeIn to run under Linux. (this applies only to the client machine; setting up the network can be done entirely on LogMeIn’s website)
My configuration: Ubuntu 10.04 Lucid Lynx 64 bits with LogMeIn Hamachi 2.0.0.11-1. (Hamachi is a protocal that creates a VPN that goes through their servers)
Done! From that point, you can use VNC or anything else to connect to a remote computer. Use something like ifconfig on the remote computer and use the IP address under the ham0 entry (ham is for Hamachi, obviously). The IP address has an unusual value such as 5.18.76.84.
I’ve talked recently with the CTO of a small-but-successful company, trying to explain how we do software development. I realized that many things are difficult for them to copy from us, mostly because we have a different approach to implementing features (in particular, we try to limit GUI-intensive features, while they have a very rich Javascript interface).
One thing, however, that I believe they can adopt without changing their code is the source code management tool Git. However, they had already considered it (they are currently using Subversion) and figured that it does not solve problems they already have.
I’d agree that Git doesn’t fix obvious problems. However, Git is powerful enough (once the complexity is mastered) to make lots of little things easier. Here is what it does for us.
None of these features are absolutely necessary. But all together, they make life easier for us. It even let do serverless CI.
Sebastien Douche has said during a presentation at a recent Paris JUG evening that DVCS are the one thing that all developers should learn in 2010. I think he’s right.
Robert “Uncle Bob” Martin has just blogged on the differences in TDD styles using Clojure, as compared to more traditional languages such as Java. Though I am a Clojure-newbie, I mostly disagree with his conclusions.
His main point is that, because Clojure is a functional language, functions have no side-effects and therefore can be used directly in the tests.
For example, the production code
(defn update-all [os] (update os))
would be tested with something like
(testing "update-all"
(let [
o1 (make-object ...)
o2 (make-object ...)
os [o1 o2]
us (update-all os)
]
(is (= (nth us 0) (update o1)))
(is (= (nth us 1) (update o2)))
)
)
Changing internal values is only one way of creating side-effect. I admit that Clojure encourages coders to write code that does not change variables (if I got it right, it is definitely possible to do so, but with some additional work). However, that effect only stops at the boundaries of the language. At some point, it might access the file system or a database. Clearly, the state might change there.
Bob Martin says: ”this test simply checks that the appropriate three functions are getting called on each element of the list”.
Suppose that the (update) function does not do anything or maybe does something that does not return a value, such as printing out to the console. Then, calling it will have the same effect as not calling it at all. The test above will pass even if the (update-all) function does not provide any implementation at all. When, later, the bug is found, it will be harder to fix.
One of my biggest concerns is that the test looks a lot like the code itself. Looks like duplication of information to the reader.
If there was a mock framework for Clojure, I would expect to see something like
(testing "update-all"
(let [
pre-conditions (
(should-return (update 1) 1.5)
(should-return (update 3) 3.0) )
o1 (make-object 1)
o2 (make-object 3)
os [o1 o2]
us (update-all os)
]
(is (= (nth us 0) (1.5)
(is (= (nth us 1) (3.0)
)
)
But he should also make it clearer that it is lacking a mock framework (he does point to Brian Marick’s work on this).
It should be noted that it is possible to get a similar implementation style in Java as in Clojure, though it is significant work. In fact, that’s often how we use it here at Algodeal. That means mostly relying on immutable objects and state-less methods. Immutable collections from Google Collections help a lot, too. Still, we like to use mocks in our tests (too much for some, probably).
In the end, Uncle Bob’s post is another aspect of the (almost) age-old debate described by Martin Fowler: classicists vs. mockists. If you haven’t already, read Fowler’s article, it’s worth it.