It can’t be emphasized enough that after correctness, comprehensibility is the most important feature of test code.
Rob Fletcher, “Spock: Up and Running”
Truth.
It can’t be emphasized enough that after correctness, comprehensibility is the most important feature of test code.
Rob Fletcher, “Spock: Up and Running”
Truth.
The WordPress.com stats helper monkeys prepared a 2015 annual report for this blog.
Here’s an excerpt:
The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 24,000 times in 2015. If it were a concert at Sydney Opera House, it would take about 9 sold-out performances for that many people to see it.
Here are the top 10 agile books that all agile software developers should read this year, including some old classics that should be re-read regularly!
The WordPress.com stats helper monkeys prepared a 2014 annual report for this blog.
Here’s an excerpt:
The concert hall at the Sydney Opera House holds 2,700 people. This blog was viewed about 9,000 times in 2014. If it were a concert at Sydney Opera House, it would take about 3 sold-out performances for that many people to see it.
The conventional REST Exception Mapper mechanism in JAX-RS means that exception mapping code is disconnected from the service code, so that developers have to hunt for some remote classes both to understand and to define exception mapping behaviour. It is unnecessarily awkward to trace backwards from a service method to discover what exceptions might emerge and how they might be mapped to HTTP responses.
A declarative annotation-driven approach provides simpler implementation, allows for automated documentation, and enables defining and expressing exception mapping behaviour directly at the point of use.
For REST services, exceptions emerging from lower tiers often need to be converted to an HTTP response
I once worked on a project where we had to expose a large legacy service tier as a REST service. The internal exception model was built for consumption by code in the same environment and to be understood by the same developers. The granularity and information content of the exceptions was not suitable for onward transmission to clients of the REST service, so there was a lot of exception mapping work to do.
The translations involved a lot of detail, but there were only a few simple patterns going on. Given an exception type, choose an HTTP status code. Given an internal error code, choose some external code. Given an exception type, select an error message. Given some combination of type and error code, map to some other status and message and other details.
The usual approach to exception mapping in REST is with javax.ws.rs.ext.ExceptionMapper, eg
public BookExceptionMapper implements ExceptionMapper<BookException> { public Response toResponse(BookException ex) { return Response.status(Response.Status.BAD_REQUEST).build(); } }
When an exception occurs, the runtime will look for an Exception Mapper that can handle that type, or the nearest superclass handler.
A big problem with this is that when looking at the REST service code there’s no obvious local expression of the error responses that may emerge. You have to drill down into the code to see what exceptions might be thrown, then you have to go and find the exception mapper for that type and see what happens to it, eventually uncovering the HTTP status code and other details that will form the end result.
As well as being manual and tedious for the developer to trace, it’s also manual and tedious to document the possible errors that may emerge from the REST service for clients to understand.
Wouldn’t it be nice if the developer could look at the REST service code and immediately see what exceptions may emerge and how they will be mapped to HTTP responses, define new mappings right there, and also automatically generate the client-facing documentation that explains the potential errors and their meanings?
We achieved that using a custom annotation to declaratively express the exception mappings, and an interceptor to process and perform the mapping and translation.
By modifying our REST documentation tool (we were using Enunciate) to pass through our custom annotation, we could also automate the client facing documentation.
We defined the ErrorResponse annotation with the details needed to map an internal exception class to a given HTTP response, the supplementary error code we needed to pass in that error response, and an explanatory description that could be used for documentation:
@ErrorResponse( cause = KaboomException.class, httpStatus = 400, errorCode = 639, description = "This might happen if you've been really bad")
Now, when you look at the REST service interface you can see (and define) the exception mapping right there:
@ErrorResponse( cause = MyException.class, httpStatus = 403, errorCode = 789, description = "Ooh you did it totally wrong") @Path("/things/{thingId}") Thing getThing(@PathParam("thingId") int thingId){ ... }
In some cases we needed to further sub-divide a given exception type into HTTP responses according to some internal details of the exception. We added an optional element to the annotation to create a more-specific mapping, and modified the interceptor to match according to “specificity”, eg:
@ErrorResponse( cause = KaboomException.class, whenKey = SOME_MATCHING_VALUE httpStatus = 400, errorCode = 639, description = "This might happen if you've been really bad")
Note how the first two elements of the ErrorResponse mapping are addressing the cause. When you see this exception containing this value…
The rest of it is specifying the result – use this status code, send an error body containing this error code, and here’s the documentation for what this error means to a client.
The interceptor that processes the exceptions by looking for these annotations can also simplify some other things. For exaample, the interceptor can see which method the exception came from and use a convention to lookup some predefined error message text to add the error response body before sending it to the client. For example, imagine a list of error message text linked to the method name and the status code such as
getThing.400=This is the meaningful description for this error from this method
The interceptor can automatically look up message text according to that convention and so we can separate it from the annotation, leaving the developer to just specify the bits that only change at development time such as the mapping from exception to status code. Message text is now separate and can change at its own pace.
It’s hard to lay it out well in a blog post, but being able to see and to define the exception mapping declarations at the point where those exceptions emerge from the service is so much nicer than having to root around for ExceptionMapper classes that have no direct connection:
@ErrorResponse(cause = MyException.class, httpStatus = 403, errorCode = 789, description = "Incompatible user status") @ErrorResponse(cause = OtherException.class, httpStatus = 401, errorCode = 157, description = "Reading the manual failure") @Path("/things/{thingId}") Thing getThing(@PathParam("thingId") int thingId){ ... }
Being able to automatically process those annotations when generating API documentation is not just a timesaver, but also avoids the inconsistencies that arise from manual updates. Adopting simple conventions for mapping from exception details to things like textual clarification messages also leads to cleaner code and automaton both of execution and documentation.
Just heard an interesting talk by Kevin Rutherford at Agile Manchester about connascence and how it can be used as a guide during the refactor part of the TDD cycle (red-green-refactor).
“Connascence of value”, for example, means that the test code and the production code are coupled by shared knowledge of a value. In other words, there is duplication of a value, such as a price or a limit or a quantity, and that duplication needs to be resolved by refactoring, thereby breaking (or at least weakening) the coupling.
There are 9 kinds of connaescence including connascence of value, of algorithm, of meaning, of execution order, and 5 more, and they can be ordered in terms of criticality. For example, connascence of value is more critical than connascence of meaning. Kevin suggests that if you learn to recognise the different types and tackle them in order of criticality, that it can help you progress through the refactor stage of TDD without getting stuck or going in circles.
It immediately struck me that there is a similarity here with the transformation priority premise. TPP seems to apply more to the “green” phase of the TDD cycle. When you have added a new test (“red”) you have made the test suite more specific, and now you need to generalise the code to make it pass the more specific tests. Uncle Bob noticed that the transformations you apply to the code tend to occur in similar patterns at similar times, and more importantly in some order. By identifying and ordering those transformations, does the “green” stage become a little easier to do without getting stuck if you can recognise what transformation should come next?
For example, a test that expects the answer “50” can be satisfied by code that always replies “50”. Add another test, thus making your test suite more specific, and you have to generalise the code to pass both tests, perhaps by adding a conditional.
Add another test, increasing specificity of the test suite, and you have to further generalise the code to pass the tests, perhaps by transforming the conditional into a loop.
If you become familiar with the idea that very often a conditional expression may survive a few iterations of the TDD cycle until a more specific test forces some transformation, and that the transformation is usually to a loop, could it make you go faster and more easily through the TDD process? By recognising a pattern and knowing the step that usually follows, do you have to think less? Does it make it easier to build the “instinct” that TDDers gain from years of practice and experience? Could it give a head start to those who haven’t spent years internalising the techniques?
If connascence and TPP capture some common patterns that experienced programmers instinctively use when doing TDD (and just when coding), can they be refined and cleanly expressed in a way that creates a more insightful degree of guidance than can be gained from simply saying “factor out duplication” and “write the code to pass the test”.
Are connascence and TDD alternate expressions of the same concept or are they distinct? Complementary? Can they be codified, even automated into static analysis tools or refactoring shortcuts or code completion suggestions?
Further work needed….
Option Explicit Sub Test() Dim myFolder As MAPIFolder Dim Item As Variant 'MailItem Dim xlApp As Object 'Excel.Application Dim xlWB As Object 'Excel.Workbook Dim xlSheet As Object 'Excel.Worksheet Dim xlRow As Long Dim Lines() As String Dim aLine As String Dim FileName As String FileName = "C:\Data\inbox.xls" Dim I As Long 'Try access to excel On Error Resume Next Set xlApp = GetObject(, "Excel.Application" ) If xlApp Is Nothing Then Set xlApp = CreateObject( "Excel.Application" ) If xlApp Is Nothing Then MsgBox "Excel is not accessable" Exit Sub End If End If On Error GoTo 0 'Add a new workbook Set xlWB = xlApp.Workbooks.Add Set xlSheet = xlWB.ActiveSheet 'Access the outlook inbox folder Set myFolder = GetNamespace( "MAPI" ).GetDefaultFolder(olFolderInbox) 'Visit all mails For Each Item In myFolder.Items If TypeOf Item Is MailItem Then If Item.Subject Like "*keyword*" Then xlRow = xlRow + 1 Lines = Split(Item.Body, "," ) For I = 0 To UBound(Lines) aLine = Trim(Lines(I)) aLine = Replace(aLine, vbCr, "" ) aLine = Replace(aLine, vbLf, "" ) xlSheet.Cells(xlRow, I + 1) = aLine Next End If End If Next With xlApp With xlWB .SaveAs FileName:=FileName .Close End With .Quit ' Close our copy of Excel End With Set xlApp = Nothing ' Clear reference to Excel End Sub
Took me a while to get this working. Requires a hosted version of WordPress; I don’t think this sort of thing is possible if you’re using a free WordPress.
Here’s the code you need
add_action( 'pre_get_posts', 'my_query' );
function my_query( $wp_query ){
if(is_admin() || !$wp_query->is_main_query()){
return;
}
if ( is_category() ){
$wp_query->set( 'order', 'ASC' );
}
}
Does white space matter?
You bet it does.
Is it easy to define the rules for something as simple as when you should and should not insert a blank line?
No. I’ve never written or read a concise and unambiguous declaration of what should be a simple style tip.
Let’s go back to my assertion that white space matters. Does it? Why does it?
It matters because when you write code you aren’t writing your shopping list. You’re not writing for the compiler. You’re not writing instructions for a machine. You are writing for an audience. You are writing code that will be read by another coder and it is your job to express yourself clearly.
Express your intent. Express the nature of the problem that you are trying to solve. Express the forces compelling you to choose one solution above any other. Explain the details of your solution in a way that the reader will be able to follow without having to unpick your work. Don’t make the reader have to go back to the very beginning and rebuild the same understanding that you have achieved, following all the same reasoning you had to work through.
You are writing to explain yourself to a reader.
Writers of fiction understand how to present their words in ways that make it easy for the reader to tune into their ideas. Along with all the rules of grammar and the conventions of expression and idiomatic speech that are quite different in English compared to Java, there are also widely followed rules of style that apply equally to computer languages as they do to creative prose.
Here’s one rule that relates very closely to the use of white space in code: The paragraph.
Stephen King writes about the use of paragraphs in his book “On Writing”. Think about the way you layout code as you read this.
Before leaving the basic elements of form and style, we ought to think for a moment about the paragraph, the form of organization which comes after the sentence. To that end grab a novel… Open the book in the middle and look at any two pages. Observe the pattern – the lines of type, the margins, and most particularly the blocks of white space where paragraphs begin or leave off.
You can tell without even reading if the book you’ve chosen is apt to be easy or hard, right? Easy books contain lots of short paragraphs and lots of white space. Hard books, ones full of ideas, narration, or description, have a stouter look. A packed look. Paragraphs are almost as important for how they look as for what they say; they are maps of intent.
In expository prose, paragraphs can (and should) be neat and utilitarian. The ideal expository graf contains a topic sentence followed by others which explain or amplify the first.
Even in the informal essay it’s possible to see how strong the basic paragraph form can be. Topic-sentence-followed-by-support-and-description insists that the writer organize his thoughts.
Writing is refined thinking. If your thesis is no more organized than a high-school essay, you’re in big trouble.
Here’s what the author’s bible, Strunk and White’s ‘The Elements of Style’, has to say:
Ordinarily a subject requires division into topics, each of which should be dealt with in a paragraph. The object of treating each topic in a paragraph by itself is, of course, to aid the reader. The beginning of each paragraph is a signal that a new step in the development of the subject has been reached.
In general, remember that paragraphing calls for a good eye as well as a logical mind. Enormous blocks of print look formidable to readers, who are often reluctant to tackle them. Therefore, breaking long paragraphs in two, even if it is not necessary to do so for sense, meaning, or logical development, is often a visual help. But remember, too, that firing off many short paragraphs in quick succession can be distracting.
When you look at densely packed code, do you instinctively know you’re in for a rough time?
Can you tell just by the shape of the code in a method or a class that you’re going to have to re-write it, before you even read any of the individual words?
Do you take care to break up related blocks of code like loops and return statements by inserting blank lines at carefully chose points?
Do you notice deviations from symmetry in neighbouring lines of code and re-organise your method parameters and return types to achieve symmetry and a consistent level of abstraction?
If you don’t, then I urge you to read Clean Code and to watch the Clean Coders videos.
Finally, I urge any programmer who wants to write clean code to read Strunk and White. People have been writing, and writing about writing, for a very long time, and some important lessons about writing well can quickly be learned and applied when writing code.