Lasse Koskela

author
+ Follow
since Jan 23, 2002
Merit badge: grant badges
Cows and Likes
Cows
Total received
In last 30 days
0
Forums and Threads

Recent posts by Lasse Koskela

Congratulations to all winners! I hope you enjoy the book and find it useful. And if you do – please tell your friends all about it ;)
11 years ago

Zico Gupta wrote:I consider myself one of the lucky person having received one on one training from you in junit.


That's nice to hear In case you're interested in TDD (or some of your colleagues are), I'm running a one-day workshop on TDD in Bangalore next week during the Agile India conference. I believe there's still seats available in that workshop.

Zico Gupta wrote:Coming to the new book, does it cover unit testing code which is written to run a multi threaded environment?


Not in very much detail. The most in depth coverage is in chapter 5, which describes a test smell called "sleeping snail" – a test that uses Thread.sleep(...) to wait that some thread has managed to complete its work before the test continues with assertions or further invocations.

In fact, Test Driven covers it in more detail than Effective Unit Testing – the whole chapter 7 is dedicated to dealing with threads.

Zico Gupta wrote:Also please recommend some mocking tool.


My personal favorite is Mockito. I'm sure some other libraries have some really advanced functionality that Mockito's missing but so far I haven't found a need for anything more capable. Actually, most of the time when I feel like I'm stretching Mockito to its limits, the real issue isn't Mockito but the design of the code I'm trying to mock.
11 years ago

qunfeng wang wrote:I don't see a topic of test-driven development in the table of contents. What's your opinions on this topic? Is that a way not preferred to use in your book?


I'm very fond of test-driven development. TDD and writing unit tests are two different concepts, however, and I wanted to write a book that specifically helps people write better unit tests – regardless of whether they write them before the implementation or after.
11 years ago

Thad Humphries wrote:Do you have an advice on automated testing for images and PDFs? I must generate TIFF, JPEG, PDF, etc. by merging database records, text files, format files, and other images. All the JUnit testing I can think to are things like size, depth, and dpi, things that are done by the 3rd party libraries and not by me. I have to check my code's results manually: Is the right font used? Is the text or image correctly placed? Are things scaled correctly on the page? Any ideas or libraries for automating more of that would be appreciated.


What I'd look at doing would be to detect each aspect individually by, for example, looking for specific shapes in the resulting bitmap to detect the correct font being used and checking the position of a known image in the resulting bitmap. Some of these tests would make heavy use of image processing algorithms (which likely means you wouldn't implement them just for one or two tests' needs) and while some tests can be made simpler with smart setup (e.g. using a solid red image that's easy to look for in the resulting bitmap), these tests will certainly look and feel quite different from the kind of tests you'd write for typical application logic.
11 years ago

Yvette Schat wrote:How would you rebut the counter argument that tests need (too much) maintenance of their own?


Probably by pointing out that tests that feel like a burden to maintain or the code they're testing haven't been refactored enough.

Unit tests should be small and focused, which means that they're only interested in a very specific behavior or interaction. That would also mean that those tests shouldn't break unless the specific API's they're interested in are changed.

Besides, which would you rather maintain - a code base with too many tests or one with too few tests?
11 years ago

Geroen Joris wrote:Needless to say I've become quite the heavy user of PowerMockito - sometimes to grand dismay of my co-workers.


Sounds like you're aware of the trade-offs you're making. That's hardly ever a bad thing!

Geroen Joris wrote:What do you consider boundaries for a unit test (which is actually what this is all about)? Do you mock all constructor calls and static classes, or not? How far would you go in controlling the "environment" for your unit? Or do you rely on the constructors and statics?


I'd like to not have more than a handful of static methods in a code base – and none that I'd want to stub in tests. (I'd also like a red Ferrari that goes a hundred miles per gallon and never breaks down.) In practice it's often a trade-off decision between how far you refactor now and how quickly you proceed with adding new functionality. Sometimes I end up refactoring away from static methods and sometimes I end up working around them. Sometimes I even skip writing a test altogether because it isn't easy enough.

You mentioned the java.io.File API as an example. When there's only a couple of classes that deal with the File class, I tend to just suck it up and write a few integration tests that operate on actual files in a temp directory. If the file system stuff is a major element of the code base I'm working with, I'd be looking for an abstraction that reduces the number of places where my code base is exposed to the File API. That's not a trivial refactoring so I don't do it that often.
11 years ago
Hi Varun,

I'm afraid the answer would be no on both counts.

I've tried to focus on concepts that are applicable across test frameworks (and programming languages for the most part). Most examples use JUnit and there's a couple of appendices to introduce JUnit for those who are new to it. While I think they are a decent introduction to someone who's used another test framework before (perhaps with a different programming language), it certainly wasn't a primary goal to teach JUnit or compare it to alternative frameworks.

Regarding test data and databases, those topics have been largely cut out by the explicit focus on unit tests, isolated tests written for individual objects or small clusters of objects – tests that explicitly try to avoid hitting a database or any other external component that's not in the test's control.
11 years ago
First of all, I can't resist pointing out the history of the term Behavior-Driven Development. Here's what Dan North, the inventor of the term, says about its beginnings:

Dan North wrote:I started using the word “behaviour” in place of “test” in my dealings with TDD and found that not only did it seem to fit but also that a whole category of coaching questions magically dissolved. I now had answers to some of those TDD questions. What to call your test is easy – it’s a sentence describing the next behaviour in which you are interested. How much to test becomes moot – you can only describe so much behaviour in a single sentence. When a test fails, simply work through the process described above – either you introduced a bug, the behaviour moved, or the test is no longer relevant.

I found the shift from thinking in tests to thinking in behaviour so profound that I started to refer to TDD as BDD, or behaviour- driven development.


In short, the original definition of BDD was more or less "TDD with a different vocabulary". In the recent years, BDD has grown to mean all sorts of things beyond the original idea. For instance, some people use it as a synonym for acceptance test-driven development (ATDD).

With that said, I've only seen one actual (non-technical) customer create executable examples directly in a computer-understandable format. That was almost 10 years ago when we gave our client a spreadsheet with some examples and she would expand on those examples, adding corner cases etc. In every other organization where I've seen specification by example in practice, the tools have been so obviously limiting and cumbersome that the real collaboration has happened with good ol' pen and paper and the team has encoded the examples from those conversations into various digital formats afterwards.

Having those concrete examples is pure awesome! Whether they're encoded into an executable format and can be run with a single command is somewhat secondary to me. A very nice bonus, if you will, but certainly not the beef.
11 years ago
Sorry, no it doesn't. It does address dependency injection as a concept in Chapter 7, "Testable Design", but doesn't go into any specific technology or framework for dependency injection.
11 years ago
The best way out of a hairy situation is to avoid getting into the situation in the first place. You're quite probably right on the money about the real issue not being about selecting the right tools but the badly written code that makes you look for such tools.

Regarding review-design-first-then-write-tests vs. write-test-first-then-review-design, my preference is the combination where you review the design every step of the way as you write tests, one at a time. Doing test-driven development, I validate (review) the design I'm about to implement by first drafting test code that uses that design. Once I see that the design makes sense from the user's point of view, I proceed with making the test compile and pass the test. Another alternative might be to pair developers with each other and encouraging them to review each other's code as they're writing it rather than after the fact.
11 years ago
Ah, the neverending quest for requirements traceability

Technically, sure you can annotate the life out of your unit tests with requirement ID's and whatnot. Whether that makes much sense in terms of cost and benefit, I doubt it. For instance, I can't even imagine the heuristics for systematically deducing which of the hundreds of features of your CRM system (for example) relate to the EmailValidator class and its dozen tests. How about that component that you use for all the buttons on your UI? Surely the tests for that component should be tagged with any user-visible feature in the system that involves pushing a button.
11 years ago
What I would do depends so much on the actual code base and technologies involved that it's quite difficult to say much in that direction. With that said, and generalizing a bit, I would expect to see some kind of a "pyramid" shape in place where most of the volume would be in low level, isolated unit tests for individual objects or small clusters of objects and the closer to the system's boundaries your tests would get the fewer and fewer of such tests you would have.

For instance, I'd expect a JavaScript-heavy code base to have unit tests for individual "objects" or functions and I'd expect to have a handful of end-to-end tests with Selenium and the like for increasing the team's certainty about not having broken anything in the larger scheme of things. I would most certainly not want to run thousands of Selenium tests to cover all possible combinations of user input on a form checking that the client-side validations work correctly. Instead, I'd like to check that validations in general for that form are invoked and the UI reflects their result.

I don't know much at all about Vaadin (even though it's built by a bunch of Finns – we're not that small a country ) and I've only been exposed to GWT on one project shortly. It does seem, however, that most web frameworks aren't really all that test-friendly. They might go really far in making integration testing straightforward but at the same time they might make it really difficult to isolate individual objects for unit testing.

There's a guy in Norway called Johannes Brodwall who's been promoting raw Servlets the past couple of years. It may sound like going back to the stone age but he's got a point – web frameworks can very easily become like an octopus that spreads its tentacles throughout your code base. Anyway, I sense that this is going towards an unnecessary (and somewhat off-topic) rant so I'll just stop here...
11 years ago

David Sachdev wrote:Do you feel that Test First development lets you strategically architect out what you are trying to develop, or do you find it limiting?


I'll share my thoughts on this. First of all, I don't see TDD as a strategic way to architect a solution but more like a way to help me be systematic and focused. Working test-first definitely helps me produce working designs that are modular and fit for purpose. What it limits, for me, is the unwanted things like spending two hours to create a design that's so-and-so.

J.B. Rainsberger makes a nice analogy between TDD and the brakes in your car. He says you don't have brakes in your car so that you can stop. Instead, you have brakes in your car so that you can drive fast. The point is that TDD makes you think about what you're doing and while it may feel like you're going slow because you need to write all those tests, it's the very presence of those tests that allows you to keep writing code as fast as you are. Without the tests and the thinking that leads to those tests, you'd spend a lot of time reading the code over "one more time", "just to be sure" that you haven't broken anything and aren't about to break anything.

TDD is also definitely not the only way to get that outcome and I don't test-drive my code 100% of the time. For instance, writing a test upfront requires the ability to imagine a design that would work. If I'm integrating with an API I don't know, how could I imagine a valid, working design? In such situations, I tend to first hack around with the purpose of learning what I want and then either 1) backtracking a bit and test-driving the code (now that I know how the API works), or 2) adding tests around the hacked-together prototype. When I end up doing the latter, I almost always end up regretting that I didn't test-drive it from scratch. I still do it every now and then. How stupid of me...

By the way, when you say this:

David Sachdev wrote:I find that I prefer to test simultaneous with development as opposed to a test-first approach.


What do you mean by "simultaneously" testing and developing? To me, writing one test, making it pass, writing another, making that pass, etc. is already quite simultaneous and without clear checkpoints along the way I don't feel like I know where I am.
11 years ago

Yvette Schat wrote:now I'm now leading a team and I would like to know from you how, as an expert, you would to best explain convince the team members what unit testing is about and how it is best applied...



Of course the best way would be to buy a stack of books such as Effective Unit Testing

Seriously, there's a couple of different approaches to teaching programming skills in general. One can try to explain concepts and convey their importance using examples. That's essentially what books are all about. Another option is to put the goal of teaching aside and let other programmers observe how you work – not in a classroom or conference hall context but in the grease-on-hands, deep-in-the-actual-code-base context of the work you're getting paid to do. The paradox here is that you can't teach the other person anything. Not really. It's actually the learner who chooses to learn from you and chooses what to learn from you. Of course you can influence the outcome with your behavior and conscious choices – for instance by driving conversations to certain topics – but in the end we all choose for ourselves what we see and what we make of it.

Now, what I would recommend you to do is to do both. Get some books, print out some articles, organize a training class, invite a well-known speaker. These are all good ways of creating reminders, creating opportunities for people to choose to become interested. Once somebody has a spark, has the interest, their curiosity facilitates the kind of learning that can happen when you put two people to collaborate around a shared problem or task. If one of those two people is an experienced test writer, great. If neither has much experience with what they're trying to learn, that's great too – certainly much better than both individuals trying to struggle through alone.
11 years ago
Chapter 3 is dedicated to the different types of "test doubles", including mock objects but also lower fidelity utilities like plain stubs. What I've tried to do with Chapter 3 is to focus on highlighting the benefits and motivation for using test doubles and helping the reader identify what type of a test double they might need. It's not always a mock object that fits the bill best, although mock object libraries such as Mockito can be used in different styles. For example, a lot of people use a mock object library to create stubs.

As for specific libraries, we've used JMock and Mockito for the example code listings but we don't really teach either. Again, the goal for Chapter 3 wasn't to teach any specific library but to teach the fundamental concepts that may (or may not) justify using such a library.
11 years ago