Alexander Tarnowski

Alexander Tarnowski

Professional Software Development

About the Developer Profession #1: How Many Decisions Do You Make in Real Time?

In this series of articles, I’ll be discussing the developer profession from different angles. The common denominator is that all articles will, in one way or another, be about professionalism. This first article is about the different factors and decisions behind every single line of code.

Notes snd Equations

A while ago I spoke to a friend who is pretty much a professional singer. He explained singing to me in a very passionate way, saying that singing is like solving multiple parallel equations in real time. He told me that it’s quite obvious that every singer has to follow notes. What’s less obvious is that the singer also takes a multitude of micro decisions during every second of his/hers singing. He told me about tempo, intensity, interpretation of the composer, matching the expectations of the audience, synchronization with other singers, following the Kapellmeister, and a bunch of other factors. I was quite impressed.

A second later it struck me that this goes for programming as well, and I started to list all the equations a developer must solve while writing a single line of code. Here it is!

read more »

Testbarhet för utvecklare för SweNug

Idag fick jag gästa SweNug och prata om testbarhet för utvecklare. Presentationen finns på Slideshare.

read more »

Det går nu att anmäla sig till TDD-eventet!

Tidigare kollade jag om det fanns intresse att hälsa på hos oss på Crisp och utbyta erfarenheter kring TDD. Efter att ett flertal hade visat intresse har vi nu schemalagt eventet till den 6:e maj.

Anmälan är öppen! Ni som visade intresse genom att kommentera det första blogginlägget ombedes att anmäla er via eventets sida.

12 år med TDD

12år

Om det känns lockande att fördjupa sig inom olika varianter och vinklingar av TDD, säg till, så ordnar vi ett TDD-kvällsevent här på Crisp.

read more »

Slides från SAST Stockholm Q4: Tema agilt

Igår hade jag äran att få gästa SAST Stockholm Q4, där jag fick hålla en presentation om utvecklartestning. Med handen på hjärtat, så blev det lite mycket information på få tidsenheter ibland. Dock brinner jag verkligen för ämnet och vill säga så mycket jag kan.

Efter att ha checkat runt lite, gläds jag åt att många verkade ha fått med sig följande budskap hem:

Utvecklare och testare tänker och talar annorlunda om test. Det är därför viktigt att utbilda varandra.


Continuous delivery – The simplest possible build pipeline for an integration scenario

Sometimes a continuous integration/delivery scenario is more complex than just building a system in a multi-stage pipeline. The system may consist of several subsystems, or just complex components, each of which requires a build pipeline of their own. Once all systems pass through their respective build pipelines they are integrated together and subjected to a joint deployment and further testing. When facing such a scenario, I decided to build the simplest possible thing that would work and get the job done.

Two converging build pipelines

read more »

The Future of Software Development

Whar are YPU doning in the future?

What will software development be like in the future? “Agile” as we know it, will not be around, nor will test-driven development, continuous delivery, or BDD-like methodologies. I’ve been pondering this for a while, and based on some observations and a dose of wishful thinking, I’ve arrived at the conclusion above. Do you agree?

read more »

Code archeology 101: Custom Exception Hierarchies

After having worked with various legacy codebases one discovers certain recurring traits and patterns. The topic of today is the Custom Exception Hierarchy encountered in Java legacy code. This phenomenon is rather Java-specific because of that language’s checked exceptions.

So what is a Custom Exception Hierarchy? It’s an exception hierarchy, with some strangely named exception at its root, present throughout the entire codebase and used everywhere. The author(s) of such hierarchy obviously felt that exceptions like IllegalStateException or IllegalArgumentException, or the like weren’t sufficient for the sophisticated needs of their application, so they came up with a better suited hierarchy of checked exceptions.

read more »

Country Ambassador for Agile Testing Days 2012

A while ago I was asked to become one of the Swedish country ambassadors for the Agile Testing Days 2012 conference. I said yes, because I think it’s a great conference. As country ambassador, I help in promoting the conference. I chose to do it, because I think it’s a good conference and I already recommend it to my friends.
read more »

Min första kurs

Jag har precis lagt upp min första kurs här på Crisp – Testning av webbapplikationer med Selenium WebDriver. I detta blogginlägg tänkte jag förklara lite mer ingående vad kursen är tänkt att lära ut. Mina kolleger har också kommit med värdefull feedback och frågor som säkert kan dyka upp igen.
read more »

Slides from the Selenium Conference

I gave a presentation called ”Being good at waiting – Using Selenium to test Ajax-intensive pages” in an unconf session at the Selenium Conference in London.

The audience was great! Thanks everybody! I certainly didn’t know everything there’s to know about the subject, and that resulted in an interactive session where people from the audience would share their experience and answer some questions. That was so cool :)
read more »

Is your system a black box?

Surprisingly often an organization exposes itself to a multitude of risks by not knowing enough about its systems, infrastructure, and applications. This doesn’t manifest itself as a lack of “enterprise architecture” documents (while some could help). The implications are far more down-to-earth. Does any of this sound familiar?

  • Upgrading both hardware and software is unproportionally difficult and the outcome isn’t predictable
  • There exist tasks that must be performed by a specific person
  • There exist artifacts that everybody thinks need to be there, but no one dares to touch, delete, or upgrade
  • Introduction of new employees is difficult

read more »

Properties of a good daily stand-up

I had a conversation with some of my colleagues about what makes a good daily stand-up, here are some properties:

  • Time-boxed (15 minutes)
  • Everyone is engaged
  • Synchronization is taking place
  • Attention to problems
  • People ask for help
  • The conversation is about stuff that matters to most people, individual issues are postponed
  • Anyone can lead the meeting, not just the Scrum Master / Team Coach
  • The meeting is the starting point for the day, afterwards everyone feels energized and can start working right away
  • Ends with a punch that marks the end of the meeting and the start of the day*

* The team has dumbells by the scrum board. The rule is that if you feel the current speaker is monopolizing the meeting, you can hand the speaker a dumbell. Now the speaker can keep talking only as long as they can hold up the dumbbell with an outstretched arm.

Learning, understanding, and horizontal development

As developers feel the daily pressure to deliver, they tend to skip a crucial step in the process: learning and understanding the system. There’s a huge difference between just adding more lines of code to the codebase and making changes that maintain the conceptual integrity of the system.

Horizontal development is the result of not spending enough time learning and understanding the system you’re working on. By starting to churn out code too soon, you’ll inevitably be adding silos of functionality in parallel to existing functionality.

The outcome is legacy code. It doesn’t matter how well factored it is, and what test coverage it has!

read more »

The link between testability and object-orientation

If you do TDD or write unit tests you soon start to feel reluctant about parameters and scalar data types. Why?
Consider the function below. Is it easy to test? Would it be created if TDD were used?


bool result = f(int p1, long p2, Object p3);

Pretend that the function above lives in a business layer and determines whether a customer can get a discount a particular month given a set of conditions embodied in the object otherConditions. Thus the above could be rewritten as:

bool eligibleForDiscount = canCustomerGetDiscount(int month, long customerNumber, Object otherConditions);

Without thinking about it, we would most likely refactor it by introducing types for month and customer number. This would save us from cluttering the first lines of the function with code related to checking the validity of those parameters. Some people would call this object-oriented programming, others would stretch as far as calling it domain-driven design. Irrespectively of the term chosen, the function above would most likely be refactored into something like:


bool eligibleForDiscount = canCustomerGetDiscount(Month month, CustomerNumber customerNumber, Object otherConditions);

While at it, we would probably discover that this code needs to live in a context, and we would place it in a class that handles business rules related to discounts. That class, whatever its name and function, would assume the responsibility of handling discounts, which would make the otherConditions parameter unnecessary. Of course this parameter was never actually an Object, rather another class in the business domain. However, I didn’t want to complicate the example.


bool eligibleForDiscount
= discountManager.canCustomerGetDiscount(Month month, CustomerNumber customerNumber);

At this point we could feel quite happy about the function.

  1. It has a good name
  2. Its invocation honors the Single Responsibility Principle (SRP), as the DiscountManager’s only responsibility seems to be handling discounts, while validation and domain-compliance are handled in Month and CustomerNumber.
  3. It doesn’t take too many parameters
  4. It feels quite testable (based on its signature, at least)

But what did we actually do to make this happen? Is there a way to formalize these refactorings?

It turns out there is, although we have to borrow a definition from the testing domain.
I came across an article that mentions quite an interesting metric: The Domain-to-Range Ratio. It’s defined as the cardinality of the domain of the specification over the cardinality of the range:

DRR = |D| / |R|

Without being too formal about it, we can say that the lower the DRR, the better. For example:
|D| = cardinality of a 32-bit integer type, |R| cardinality of a 1-bit boolean type, which would produce a function like f(int32) → bool

Is that testable? How many unit tests do you need to make sure that the function behaves correctly? One, ten, or 232?

Returning to the discount function, we see that its DRR would be a scalar product of cardinalities in the magnitude of 232, 264, and the combined DRR of all members of otherConditions that are queried by the function.

While it’s not apparent how complex the condition object actually is (it could be as simple as a boolean flag), we see that introducing a Month class reduces the cardinality of the first parameter from 232 to 12, and that introducing a CustomerNumber class at least halves the cardinality of the second, as customer numbers are most likely not negative.

In this light, we see that refactorings like:
Scalar → enum, Scalar → object, Remove parameter, start making sense in a formal sort of way.

It also happens that such refactorings make the code object-oriented…