Showing posts with label tdd. Show all posts
Showing posts with label tdd. Show all posts

Monday, February 28, 2011

Linkage

Monday, April 13, 2009

TDD for Ontologies

As it was said to me recently, very often something goes from being mysterious and magical to obvious (I'm looking at you not-so-magical-anymore Grails wiring). So it goes with test driving ontologies (or at least it did for me). One of the standard methodologies for ontology development is creating competency questions for an ontology to successfully answer. This generally means gathering requirements, use cases, organising the data and ontology, testing them and maintenance. Doesn't that sound an awful lot like waterfall? It would appear obvious, that just like code, ontologies could be developed using test driven design (neh development) instead. This should have the same benefits as agile code - like being more adaptable to change.

The closest paper I've come to that talks about this idea is, "Unit tests for ontologies" (and there's also bachelor thesis, Unit Testing for Ontologies). Unfortunately, it talks about adding tests during the maintenance of software. Luckily, it talks about using them as a way to initially build the ontology and surely that would be a way to drive out an ontology. Good stuff. I could imagine that certain good patterns of ontology design like making them small, self consistent, fast, intuitive, etc. would all come naturally out of applying TDD techniques.

As an aside the unit testing paper also mentions the usefulness of autoepistemic operators (K and A). You can state that for a given instance there must exist a certain property, for example, a country must have a capital city.

Thursday, February 12, 2009

LOL (List of Links)

Wednesday, September 19, 2007

Beautiful or Otherwise

Two of the chapters from Beautiful Code Alberto Savoia chapter Beautiful Tests and Simon Peyton Jones on concurrency are available in PDF form. Beautiful Tests covers most of the different kinds of tests and how to make changes to code to make it more testable and starts to cover creating and validating theories.

Speaking of tests, Scala, DSLs, Behavior Driven Development?, talks about how Java is poor at creating DSLs specifically compared to Scala. And what's the application? Behavior driven development in a Java project called beanSpec (which superficially looks similar to Instinct probably as they're both based on RSpec and using the same stack example). So you have this neat sort of convergence where people are looking at testing Java better in ways that are more declarative (functional even).

Making Java more functional is on the cards for Java 7 in, Will Java 7 be Beautiful?, it links to point free programming in Java and Haskell and how the new language proposals (closures) make Java 7 look a lot like Haskell with the suggestion that all Java 7 functions should be curried.

While the syntax is potentially getting more beautiful, the user interfaces are traditionally pretty poor in Java (even with OS X support) but even that is changing. I've been following Chet Haase's blog and recently Filthy Rich Clients was made available to purchase. It's all about improving the look and feel of Java and to finally approach the richness of native OS X and Windows applications. He even has some links about language proposals too, including bringing back line numbers. Some examples of their work are on the web site and on Roman Guy's blog which includes an entry called Beautiful Swing.

Roman also linked to a movie of *7 the prototype handheld device running Green (Java). Who knew Duke had a house?

Wednesday, August 22, 2007

Result

The previous issue of IEEE is avaiable to Xplore subscribers. It is an issue dedicated to TDD and agile development.

Mock Objects: Find Out Who Your Friends Are highlights the oft discussed criticisms of test driven development including: breaking encapsulation, hard to read, increased code fragility and whether it is a valuable use of developer time. Of course, these differences can be resolved in a typical XP way:
My point is that plenty of well-written code is produced without relying on mocks or Tell, Don’t Ask. On the other hand, I also encounter plenty of TDD novices who produce poor code and poor tests. Can Steve and Nat’s approach consistently help novices write better code and tests? It could be. At this point, I remain open minded and am ready to pair-program with Steve or Nat to learn more.

The second article, is about the studied effect of TDD on the quality of code, TDD: The Art of Fearless Programming. Pretty much every study showed an increased effort (15-60%) and an increase in quality (5-267%). The ratio of effort to quality is 1:2 - so it seems to pay. Example definitions of quality were "reduction in defects" or "increase in functional tests passing". In general:
All researchers seem to agree that TDD encourages better task focus and test coverage. The mere fact of more tests doesn’t necessarily mean that software quality will be better, but the increased programmer attention to test design is nevertheless encouraging. If we view testing as sampling a very large population of potential behaviors, more tests mean a more thorough sample. To the extent that each test can find an important problem that none of the others can find, the tests are useful, especially if you can run them cheaply.

Via Mock Objects

Monday, April 02, 2007

Testing and AJAX

Two completely unrelated areas of interest.

The first is Unitils which automates a number of testing tasks. It includes:
* Equality assertion through reflection, with options like ignoring Java default/null values and ignoring order of collections.
* Support for database testing involving test data management with DbUnit, automatic maintenance of unit test databases and automatic constraints disabling
* Hibernate integration features such as session management and testing the mapping with the database
* Integration with Spring, involving ApplicationContext management and injection of spring managed beans
* Integration with EasyMock and injection of mocks into other objects

The cookbook offer concrete examples to do things like mock object injection and the like.

The second is Slingshot: Desktop Apps via Rails, "Slingshot looks like it wraps up a Rails app and packages it in such a way that the user is opening up a Site Specific Browser that accesses your world". It's seen as an alternative to the Firefox 3 or Apollo.

Friday, November 10, 2006

Mocking the Inspector

TDD Anti-Patterns "The Mockery - Sometimes mocking can be good, and handy. But sometimes developers can lose themselves and in their effort to mock out what isn’t being tested. In this case, a unit test contains so many mocks, stubs, and/or fakes that the system under test isn’t even being tested at all, instead data returned from mocks is what is being tested."

"The Inspector - A unit test that violates encapsulation in an effort to achieve 100% code coverage, but knows so much about what is going on in the object that any attempt to refactor will break the existing test and require any change to be reflected in the unit test."

Wednesday, July 19, 2006

Test Driving Interface Usage

One of the neat things (or drawbacks) with Generics in Java is that the left hand side of an assignment can't always be treated separately to the right hand side because of type inferencing.

A simple example is Collections.emptySet(). By itself it will produce an empty set of Objects. If the left hand side defines a Set of Integers (or you use a cast) then that's what it will return.

Unexpectedly, this makes it possible to enforce an interface on the left hand side of an assignment without using something like Checkstyle or other ways of enforcing coding conventions.

The answer seems to be to create a generic object factory which wraps using reflection to create an object. The simplest API would be something like:
<T> T create(Class<T> concreteClass, Object... values).

To create an empty ArrayList and an ArrayList with a default capacity of 255 you would write:
List list = creator.create(ArrayList.class);
List list = creator.create(ArrayList.class, 255);

This allows you to create expectations such that a call to create must return an interface. Using EasyMock test code is something like (from memory):
List list = createMock(List.class);
creator.create(ArrayList.class);
creatorControl.andReturn(list);

The following creates an exception as it causes the wrong type to be created (an ArrayList not a List):
ArrayList list = creator.create(ArrayList.class)

When the API is this simple it can become quite difficult to work out which constructor should be called. The simplest, at least initially, is to fail when there are multiple constructors of the same length or to create a more complicated API where you specify the constructor types. You could also have more complicated behaviour like calling the most specific constructor, where there are multiple matches for the given objects, could create a more sophisticated version. Starting with the constructor arguments and matching against the objects seems like a quicker implementation than trying to match the objects against the constructors.

Monday, July 17, 2006

Achieving Quality

Technology: Can You Automate Software Quality? "A lot of the debate has been focused on testing. Total Quality, however, would suggest that although testing is necessary, it's not sufficient. Testing focuses on inspection, not on prevention. To over-simplify, you test in hopes of demonstrating that the software has no defects (because you have a good high-quality development process), not to detect the defects that are present, but should not be there (because you don't have a good high quality development process). After several years of significant effort, the code my client was developing (and testing) still isn't of the high quality they are looking for. So we decided to go back, start from some basics, and look again at the issue of software quality."

Goes through the processes to ensure quality software: code quality (using TDD), functional quality (giving the customer what they want), non-functional quality (security, privacy, compliance, etc), deployment and production quality, and maintenance.

"This probably seems like a lot of additional work for the development organization. And it is. But the costs of defective code in the production environment (both direct, in terms of sustaining engineering, and indirect, in terms of lost revenue and reputation) was becoming significant. Management felt it had no choice but to focus on improved quality, and turn to the productivity issues later. So far, despite the added burden of all these quality–related activities (many of which already took place, but simply weren't very effective) we have not seen a slowdown in software availability. Some teams are actually moving faster than before, despite the new work they have to perform, because they spend much less time and effort on remediation and last-minute adjustments to code to fix issues that only show up as the code is transitioned to production."

Wednesday, June 28, 2006

Agile Anchors

XP2006 Patterns lists a summary of experiences in adopting agile development practices including anti-patterns: Unpaid Debt, Lots of Bugs Found by Customer. Some metrics to help drive agile software development with this not so contraversial claim, "Code coverage metrics measure the percentage of methods and classes under test. Developers should strive for 100% test coverage on classes that are behaviorally intense. The CCN can be used as a baseline for the number of tests required per method. If a method has CCN of three, a good starting point to exercise all paths through code would be three tests. Additional tests may be required that exercise error conditions and alternate behaviors. A robust suite of unit tests provides the courage necessary to refactor." Also mentioned, in "Examining Test-Driven Development, "The reality is that your unit tests form a large part of your design specification, and similarly acceptance tests form a portion of your requirements specification..."

Wednesday, June 21, 2006

Test First Saves Time

To obtain good code, writing tests and code is faster then code alone "Ron Jeffies, one of the XP gurus stated that "in order to obtain good code, writing tests and code is faster then just code". To find out if this is true or not let's make a small experiment."

Thursday, June 15, 2006

Mule with a Spinning Wheel

For some time now, I've been reading Jeff Langr's series on TDD (including testing equality, refactoring tests, and driving UIs). I now feel compelled to make sure I link to it as it's up to the 13th installment "Nine Reasons Why You Should Be Using TDD".

"A lot of the duplication in a system isn’t evident until you start refactoring. Once you begin refactoring, you start recognizing potential for reuse. You’re more likely to recognize that a small, newly extracted method could be called by another method, which in turn simplifies the other method. You start to build simpler classes that do fewer things. Often, having a smaller class increases the likelihood that other classes can reuse it."

I'd like to call this the "Tetris effect" of refactoring code. You get methods/classes/lines of code looking the same, all at the same level of abstraction and any extra complexity can then be easily removed.

"I used to think that I was a pretty good coder. I would spend an afternoon slamming out code. I’d integrate the code and run some manual tests late in the afternoon. Sometimes it wouldn’t work—imagine that! I’d then be forced to spend another few hours unraveling the mess I’d built."

"With TDD, every piece of code exists because it was required by a test. That rule, in turn, means that we have solid unit test coverage. (We don’t have exhaustive coverage, which would be virtually impossible to provide.) Defect rates should come down significantly. Martin Fowler and Ron Jeffries talk about shops that severely reduced their numbers of defects. Most teams working on moderate-sized applications (several hundred thousand lines of code) have defect rates in the hundreds or even thousands per year. Shops doing TDD can achieve rates of less than a dozen per year (but they probably need to be adhering to other proven disciplines as well)."

"The amount of time I feel compelled to go off into a dark cube and think about a problem has been minimal since I’ve been doing TDD."

Wednesday, June 14, 2006

Test Driving Java 5

I was wrong that you can't test drive generic types in Java. There is a getGenericType and getDeclaredAnnotations. More information, "Reflecting generics". It is a pain though with the methods returning an interface that has to be cast up and the implementations live in the sun.* package.

Tuesday, May 30, 2006

Organising Test Cases

One of my recent delvings into test driven code is how to ensure that all classes that implement an interface follow a given contract with the minimal amount of rework per class. In "Organising design-by-contract test code" it suggests creating "...abstract test cases for each of your (work) interfaces. These abstract test cases are specifically geared at testing the contract promoted by the (work) interfaces, and not things like setup, initialization or destruction code...Create concrete subclasses for these abstract test cases, which feed the superclass an instance of an implementation of the (work) interface that is being tested. These concrete classes are responsible for creating mock objects of the dependencies, doing any neccessary initialization, etc."

This is something I have used in the past, in something like JRDF there's abstract test cases that keep the creation of various objects hidden from the tests themselves.

My preference now is a little different - instead of using inheritance I use composition and I think that better reflects the flexibility of interfaces. Another advantage I've found is that ability to cross cut certain behaviours between these composed objects such as exception handling.

Wednesday, April 26, 2006

Links


  • On setters, constructors and modelling reality "In my experience there are almost no situations where a setter method is a good idea...I often see setters used where information relating to an object is not known at construction time, and needs to be added later. This is usually a symptom of choosing the wrong class to store that data...Note that just because all the fields are final and there are no setters, this doesn't mean that the object is immutable. It just means that its behaviour more closely models reality, and your interactions with it will be far more meaningful."

  • ABC Video On Demand including all your Chaser needs.

  • Agile Development: Schema Evolution "One of the characteristics of agile development is that designs are often refactored. As result, the data model may evolve during the lifetime of a project. What happens if the data model of the db4o databases is changed?"

  • Smalltalk to Java - the Good, the Bad, and the Unbelievably Ugly "The Smalltalk code was "too Smalltalky" for the translation (again, design is language specific IMHO). They had DNU handlers, descendants from nil, #perform, etc. Then there's the whole utility class issue - final classes in Java (String, Date) that would simply be subclassed in Smalltalk. Joshua Bloch, call your office :/"

  • Running Code Doesn't Lie "This statement pretty much sums up why agile software development practices like eXtreme Programming and Getting Real are so powerful. Instead of business analysts or programmers writing pages of documentation for what they think the system does, the system tells you what it does. I like to call this a Self Describing System."

  • TestDox "TestDox creates simple documentation from the method names in JUnit test cases."

  • Multi-core Processors: transputers reborn "
    In the Eighties, there were only a small number of people who were interested in fast drawing of Mandelbrot sets. The same is true today. But today, everyone is interested in having their web sites scale well in terms of performance and in terms of price. The killer application of parallel computing is all around us. It is called the Web."

Sunday, April 02, 2006

Many Mock Frameworks

Mock frameworks - the two main ones for Java are EasyMock and JMock. My current preference is EasyMock. Largely because EasyMock is not tied to extending a test case. This allows the shortcuts to move into test utilities - a common one is a controller factory that lets you rollup the reply/verify methods into single calls instead of calling each controller separately.

Paul King, has written up a little example of Mock Alternatives describing using EasyMock, JMock, RMock and Groovy. Tom has also made his slides available from a recent talk he gave about what I'll call Mock driven design (MDD - see "Why and When to Use Mock Objects"). Take that TDD (Test Driven Developer/Test Driven Design) or BDD (behavior driven design). Much of the interesting stuff was around the discussions and shared frustrations - especially which stage people were at with respect to what level of testing various developers and organizations were at. I think it's also important to devise strategies on how to work with different levels of tests and developers.

Monday, March 27, 2006

All Code is Agile Code

Refactoring Test Code
Includes a list of code smells specifically for test code and this reason as to why test code is important: "The downside of having many tests, however, is that changes in functionality will typically involve changes in the test code as well. The more test code we get, the more important it becomes that this test code is as easily modifiable as the production code."

"The most common case for test code will be duplication of code in the same test class. This can be removed using Extract Method (F:110). For duplication across test classes, it may provide helpful to mirror the class hierarchy of the production code into the test class hierarchy. A word of caution however: moving duplicated code from two separate classes to a common class can introduce (unwanted) dependencies between tests."

Friday, March 24, 2006

Making Things Easy

Sometimes you just need a little refactoring and time to solve an issue. In JRDF you used to have to do the following to remove triples as a result of find:
iter = graph.find(ANY_SUBJECT_NODE, ANY_PREDICATE_NODE, ANY_OBJECT_NODE);
while (iter.hasNext()) {
iter.next();
iter.remove();
}

What users really wanted to do but couldn't because it would throw a ConcurrentModificationException is:
ClosableIterator iterator = graph.find(ANY_SUBJECT_NODE, ANY_PREDICATE_NODE, ANY_OBJECT_NODE);
graph.remove(iterator);

By putting this first bit of code inside of the remove(Iterator) method the operation can then be performed much more simply by the user. The only implementation issue was determining whether the iterator was from the source graph or not.

For some reason, this solution did not present itself before - I'm putting it down to the code being more consistent (mainly the implementation of the iterators). The main reason has to be though that someone asked the question, again, why did it need to be so complicated.

It seems very similar to the situations I increasingly find when you combine TDD, 100% code coverage, zero duplication and reflecting on the design. The solutions just seem to fall out a lot more easily.

Wednesday, February 22, 2006

Boost

For a little while I've had this idea to create an open source library for utilities used for test driving. It seems that I'm not alone in this and recently the Boost library was made available. You can download the JAR (boost/boost) from the latest build.

For an even more eXtreme view, ContractualJ. Includes: all constructors are declared private and throw java.lang.UnsupportedOperationException, unless they are implicit constructors of anonymous classes and all contracts (interfaces) declare one (and only one) operation, unless they are composite interfaces, in which case, they make an effort to approach "Perfect Symbiosis of Contractual Operations" (to be defined). The only reference I found via Google was "How many bad ideas at once?" - an uninteresting post with some interesting discussion.