Showing posts with label development. Show all posts
Showing posts with label development. Show all posts

Sunday, April 17, 2016

Scrum is abstract

Over the last decade or so I found that more and more sotware developers struggle with scrum.

Especially since so many people treat agile the way it is described in the half-arsed agile software development manifesto or the dark agile manifesto.

So if I change Scrum (my process) - is it still Scrum (the approach)?

One thing that puzzles a lot of people is the fact that Scrum has to be amended past the 16 pages of it's official definition. The definition itself says so.
Yet on the other hand the battle cry of a huge body of people who call themselves agile professionals is "You are doing Scrum-But."
So where does that leave the teams? Torn between "Inspect and Adapt" "Responding to Change" and "Don't do Scrum-But."

Is it Scrum-But, Scrum-And or something completely different?

Of course it is possible to philosophize about this question a lot, but for the experienced software developer it should be easy to grasp. If you have a background in "clean-code" (as Uncle Bob calls it) or are familiar with the SOLID principles for other reasons the following picture says "it all": (metaphorically speaking)

Scrum as an abstract class

If you look at it as a programming construct Scrum is an abstract class – it defines behavior, data, interactions etc. but some parts are just defined via template methods and stuff has to specified for the concrete implementation.

And for the concrete implementation it makes sense to apply the same rules that make sense when designing object oriented software.

So your subclass should only interact at the designated points without meddling with the innards of the superclass (OCP Open Close Principle). And your implementation should be usable wherever the super-type is usable (LSP Liskov Substitution Principle)

I'm not sure about the other aspects of SOLID, but transferring this thinking for the LSP and the OCP to Scrum implementation – together with the idea that Scrum is an AbstractSuperClass – helps to answer the question whether we're facing a scrum-but or not.

TTFN Michael

Sunday, July 13, 2014

Testing: How to get the data into the system

Even though the correct term for a lot of the “testing” going on would be verification let‘s just stick with “testing” in the titles for the time being...

General verification workflow

The general way to verify that a piece of software does what it is meant to do seems quite simple:

  • Formulate the desired outcome for a defined series of actions
  • Put the system in a known state (or the sub-system or the “unit” – depending on your testing goal)
  • Execute the aforementioned defined actions
  • Verify that that the desired outcome is actually achieved
  • [Optional] Clean up the systems [1]

While this process sounds simple enough, there are enough pitfalls hidden in these few steps to have spawned a whole industry and produce dozens of books.

In this post I want to tackle a very specific aspect – the part where the system is put into a “known state”.

Putting the system into a known state might involve several – more or less complex – actions. Nowadays, where it's possible to automate and orchestrate the whole creation and setup of machines with tools like vagrant and puppet it is even possible to set up the whole environment programmatically.

You might not want to that for each unit test, which brings us to the question of when to setup what wich I will try to address in some future post.

The problem with the data

However big or small the test-setup is, one thing that is very hard to avoid is providing data.

The state of the system (including data) if often called a fixture and having those fixtures – known states of the system with reliable, known data – is a fundamental prerequisite for any kind of serious testing - may it be manually or automated.

For any system of significant size if there are no fixtures, there is no way to tell if the system behaves as desired.

Getting the data into the system: Some options

In general there are three ways to get the data into the system

  • Save a known state of the data and import it into the system before the tests are run.
    In this scenario the important question is “which part of the data do I load at which time“ because the tests might of course interfere with each other and probably mess up the data – especially if they fail. Consider using this approach only in conjunction with proper setups before each test, amended by assertions and backed up by “on the fly” data-generation where necessary.
  • Create the data on the fly via the means of the system.
    Typically for acceptance tests this means UI-interaction – probably not the way you want to go if you have to run hundreds of tests. Consider implementing an interface, that can be accessed programmatically from outside the system, that uses the same internal mechanisms for data creation as the rest of the software.
  • Create the data on the fly directly (via the datastore layer).
    This approach has the tempting property that it can be extremely fast and can be implementing without designing the system under test specifically for testability. The huge problem with this approach is that it duplicates knowledge (or assumptions) about the systems internal structures and concepts – a thing that we usually try to avoid. Consider just not using this approach!

So, do you actually have fixtures? And how do you get to your data?

’til next time
  Michael Mahlberg


[1]

(One can either put the effort in after the test or in the setup of the test - or split the effort between the two places, but the effort to make sure that the system is in the correct state always has to go into the setup. Cleaning up after the test can help a lot in terms of performance and ramp-up time, but it can not serve a substitute for a thorough setup.

Thursday, May 26, 2011

Pre-flight checks are possible on planes but not on Enterprise Applications - why?

Pre-flight check
Unit testing is all pretty well but what about delivering these tests into production?
Is it a good idea? Or is it "nice for toy applications, but you can't do that with Enterprise Applications, because there is to much money/security/personal data at stake"?
And what kind of tests are we talking about anyway?

Basically this post is meant to debunk some believes that I encountered during a couple of Enterprise Application projects. Lets look at them:
  1. We write throw-away code for unit tests that that we wouldn't need if we didn't write unit tests

  2. [The] tests are only usefull during development - they /must/ be removed from production code

  3. We don't need to simulate the connected systems once we get the real systems connected

  4. Throw-away code is effort that's useless and could/should be avoided


While these claims seem very convincing at first sight and might be very appealing to managers who try to get a development team to be "more productive" their physical world counterparts tell that story quite differently. And my own - albeit to some extent seemingly counterintuitive - observation is that these believes seem to be quite wrong.

Now - if you're still with me (or against me - as long as you care about the matter) - let's debunk them one at a time

(Unit-) Tests require otherwise useless code - I don't think so!


Of course you need to write some things to automate the tests that would not be necessary if you did something else instead. Like testing the application manually. But that doesn't mean that you win anything by not writing "those things" in the first place. You'd just replace a checkable, repeatable way to test your program by one that’s dependent on the alertness of the tester (in fact: your alertness!), her or his mood, interruptions etc.

And let’s look at "those things" that you have to write. For me, three things come to mind - the tests themselves, some kind of test harness and some special diagnostic extension point where it is possible for the tests to get access (read and write) to otherwise unexposed information. I'll come back to the exposition of otherwise unaccessible information in the next section but the other two can be dealt with right away.

The tests themselves? Well, of course I could just test the System manually. But even if I was willing to re-test all possibly affected portions of my system each time I change my code - which I am not - it soon would become economically unsound. Apart from the sheer amount of time spent doing that, for any system that has reached a substantial size I would have to keep records of the test so that I can repeat them easily and know which parts have been retested since the last change and which still need some love. Just writing the tests is way less effort than the combined effort of writing specs, keeping track of the test I just did manually and the manual testing itself.

The test harness? I think this is addressed by the same consideration that hold true for the tests themselves. Plus the fact, that there often is no way to test without a test harness since the system under development relies heavily on surrounding components.

Test should be run only outside live systems - I don't think so!


So let's come back to those extra accessors we wrote for our test that are "only there for the tests". Well sometime they /are/ only there for the tests. Unfortunately. They could be so much more. Let's look at the real - sorry, physical - world for some comparison:

Airplanes and automobiles.
Have you ever wondered what all those dials on a typical airplane dashboard of the last century indicate? Well a lot of them show things that /should not be necessary to measure/ for example the exhaust gas temperature (egt). This also is a function of the manifold pressure and the fuel intake - both of which are displayed by other gauges. But measuring each of the components separately - which really is redundant if everything works as designed - gives the pilot the option to manually lean or enrich the fuel for optimal performance. And it serves as an indicator of possible related problems.

I still have to see an Enterprise Application where there is e.g. a counter for request, a counter for inserts and a counter for updates, that get monitored in production. Such counters usually are there - for the tests. And they are used - in the tests.
So why not take them to the production system?

Or take another element of pre flight checks (not applicable to jets), the mag-check. Usually airborne engines use a magneto based system for spark generation and two separate circuits with separate magnetos and two spark plugs per cylinder. The "normal operation" is to have both spark plugs running. But - and this is where Enterprise Applications differ hugely - the pilot can control this. Even in mid-flight. And it's part of the pre-flight check to test those unwanted conditions.

Like "Both" - Revs should be 1400, "Left" - Revs should drop (only one plug), "Both" - Revs should rise again, "Right" - … you get the picture.

But I've never seen something like that done to an Enterprise Application:
"Cache Available" => All pages should show in less than n milliseconds
"Cache not Available" => Pages x,y and z should show much slower
"Database available" => Data should be written to the database
"Database not available" => Data should be written to files

But wait - that's not possible.
Because we removed all the rods and knobs that enable direct access to those internals from the production code.

And more often than not it's not even possible to take the delivered application an debug it because the debug information - and even the symbol tables where applicable - have been removed. So it's necessary rebuild the production version including debug information from the source control and try to recreate the failing scenario.

If automobile engines where build like that you would have neither the yellow "general engine failure" light on the dashboard nor the option to go to the garage and have them plug in the diagnostics computer and tell you exactly that there are air bubbles in the fuel pipe every time the engine revs over 5521. (that's an example of course…)

Instead the garage would have to rebuild an engine exactly like the one you've got in your car and analyze the error from that one. Or at least completely disassemble your engine, insert probes, reassemble it and run it in an environment simulating your car.

Although there are numerous implementations where you can probe a running system - especially on Apples OS X - they are mostly aimed at system level functions or the core frameworks. Actually I think it's very sad that it is so uncommon for programs and especiall Enterprise Applications to reveal relevant information about their internals.

It's preferable to use The Real (connected) System for development - I don't think so!


Do you really think that, in the car supply industry, they fit each wiper motor in bodies of all targeted cars before they ship them? Last time I checked they used test rigs that have nothing in common with cars except for the interface to the wiper motor - but they might have some additional features like an instrument that measures the torque of the motor and another one that measures the current drain. And by mounting the wiper motor in that rig and measuring those values they can verify that it actually confirms to the contract to which both the car manufacturer and the supplier designed their part. (Which opens the road to Design by Contract - but that would be another story)

If you write code that get's deleted later than it's waste - I don't think so!


Gimme A HandThere are lots of examples from the ream world that tell a different story. The simple one of course is the paper cup you get with your coffee to go. It does get 'deleted' later on, when you throw it away, but I don't think it's feasible to do completely without it. At least I would either burn my fingers or at least ruin my shirt if I tried to take "only the coffee and nothing but the coffee" from my local takeaway. (Replacing the throw-away cup with a mug for multiple usage might be a good idea from an environmental point of view, but replacing it is not the same as "just don't do it”)

The Casting Process * Craft & Design / Product DesignThe Casting Process * Craft & Design / Product Design
The Casting Process * Craft & Design / Product DesignThe Final Casting * The Casting Process * Craft & Design / Product Design
Another examples - that is perhaps more suitable from production point of view - is almost anything that has to do with casting metal. A wide range of casting techniques requires a cast that gets destroyed in the process. Those are made up of a multitude of materials and usually require serious work before the casting process can begin. And after the casting and cooling and hardening it often gets destroyed by brutal force - with hammers and pickaxes if needed. I really don't think you could build those metal things without the cast. So if I write code that for example simulates a calculation that will be build much later and gets thrown away once the more complex "real" function is implemented that - for me - is the mold that allows me to form the rest of my code around it.

References:
Theres a ton of related material out there, but "PPP" by Uncle Bob and the original edition of "Extreme Programming explained" by Kent Beck do a pretty good job of conveying the fundamental concepts. And throwing in some TDD by Kent Beck, BDD by Dan North plus Refactoring by Martin Fowler et. al. for good measure wouldn't do much harm either - but that's on my 2¢ and of course YMMV.

PPP = Agile Software Development, Principles, Patterns, and Practices by
Robert C. Martin
TDD = Test Driven Development: By Example by kent Beck
BDD = http://dannorth.net/introducing-bdd/
Refactoring = Refactoring: Improving the Design of Existing Code by Martin
Fowler, Kent Beck, John Brant and William Opdyke

Saturday, January 22, 2011

Context does matter in UX und UI design

In a recent tweet a friend of mine (Selena Delesie) stated that she is "Surprised to discover there are programmers who still don't put limits, data type restrictions, and error handling on form fields."

As much as I like twitter I soon came to realize that I couldn't put my answer in 140 characters - not even with unicode tricks.
But I'm not surprised at all - and I don't even think it's a bad thing that there are unchecked fields on forms.

As I said in my reply:
"depends on context & is a tradeoff between effort & possible harm.
user ∈ inhouse dev ⇢ lax checks"
user ∈ public ⇢ strict checks [didn't fit in the 140characters limit]

The scenario for user ∈   inhouse dev ⇢ lax checks

This would probably also be a 'C' or a very small 'D' on the cockburn scale, wich is explained in more detail at Alistair's own site.
If I build a 3-hour effort tool for me and my fellow developers to manipulate database metadata and that is intended to run only on our development machines I probably
  • won't put too much effort into checks against SQL-Injection - we can do all the harm we want anyway [and it doesn't matter much if we accidentally write "drop database;" in the database's command window or in an unchecked entry field]

  • won't put to much effort into checks against the wrong type - I'm pretty sure all of the intended users (e.g. me and three co-workers) can handle an error message like "invalid type at line 8745 in <name_of__3rd_party_sql_library>"

  • won't care if it's possible to enter 4gb of data through one of the entry field - the possible harm is well within acceptable limits for the stakeholders (me and my colleagues) and the harm could be achieved in much simpler ways

The scenario for user ∈   public ⇢ strict checks

On the other end of the spectrum would be a piece of software used by a large number of people who might or might not have have malicious intentions and where incorrect values might cause harm to serious money or even life (that would be a bigger 'D' an 'E' or an 'L' on the cockburn scale IMO.
The classic 'E' example for me is the ATM where I probably
  • would make sure that only numbers are entered by using a hardware keyboard that only consists of numbers [and check the input values to be a little bit safer with respect to physical attacks]

  • would replace drop-down boxes by large hardware buttons at the edge of the screen

  • and so forth

The 'L' examples that come to my mind are mostly related to heavy machinery or medical equipment - in both cases the aforementioned principle - limit the choices and represent data entry through manipulation of physical objects - are heavily applied.
Most application fall somewhere in between and nowadays more and more applications that deal with essential money (e.g. online banking) are realized without the hardware representation. In these cases, especially for applications running on the internet, I would
  • Put limits on the length of input data - on the client if possible and on the server just to make sure

  • Make sure the data that get's typed in represents the correct types * as early as sensible [that might be on the client - I'd add a server side check for good measure in all cases and might drop the client side check if it becomes to intrusive for the user.

  • Implement an error handling scheme that gives helpful information to the use with as much detail as he requests and informs the developers and maintainers of the system of the possible quirks in the system at the same time so that the UX can be optimized to have less occurrences of that specific error in future releases.

The problem with the two scenarios "user ∈   inhouse dev ⇢ lax checks" and "user ∈ public ⇢ strict checks"

is that most applications are somewhere between them. And sometimes application evolve from a little developer-on-the-team-only helper application to something that is used by more and more people so the last responsible moment ** to rework my three our project to a product becomes hard to determine. But if I as a developer kept my options open (e.g. because clean coding has become a second nature) it should be possible to productize the tool.
But - it has to be a conscious decision!
In my opinion it neither makes sense to make a cheap tool cat-proof nor is it responsible craftsmanship to offer a product to the public that doesn't employ proper checks.

* but that is a topic for another article - the only type that a user with a keyboard can key in is "array of characters" - what it represents is 100% context: e.g. "feed" might be a word in one case - it's the hexadecimal representation of 65261 in others.

** See e.g. Mary and Tom Popendiek on the topic of the last responsible moment and the keeping of options. Due to a fancy website design on their side I can't provide a link though - but as of 2011-01-22 the statements can be found after clicking on "focus on learning" in the principles box on the left hand side of their website.

BTW: I really wonder how this page with the "is element of" and the arrows will display on other browsers and systems...