Selenium Assertions and waitFors in FlexMonkium

Posted in Stu Stern on February 28th, 2010 by admin
In our previous video, we saw recording and playback of Flex interactions interleaved with browser interactions within a single Selenium script. Today's video shows how we can execute FlexMonkey Verify commands as assertions or waitFor predicates within a Selenium script.

The video shows a simply script being played back at slow speed. When we then try to play the same script back at fast speed, it fails because the script navigates to the page containing a Flex app, but then attempts to interact with it before the app has finished loading.

What we would like to do is have a way to tell Selenium to wait for some condition that signals the app has finished loading. One way to do this is to have Selenium wait for the appearance of a component within the application's window. We interactively create a FlexMonkey Verify command that tests whether the name field has a blank value. Notice that when we create this command, it is also "recorded" by the Selenium IDE as an assertion, assertFlexVerify.

This assertion will fail if it is executed before the swf has finished loading. However, we can ask Selenium to wait for the condition to become true by changing the assertFlexVerify command to be a waitForFlexVerify instead. Now, when we run the script, it waits for the swf to load before continuing, and then successfullly plays the rest of the script at high speed. We can of course use a similar technique to have a Selenium script wait for other Flex application events, such as data being returned from a query to be displayed in a table.



As you can see, we have all the major mechanisms necessary to very clean integration of FlexMonkey and Selenium. There is some trivial syntactic sugar we will likely sprinkle on what the video shows here, and we've still got some code clean up to do before we'll be ready to release, but we believe all the hard problems have been solved so it won't be much longer before FlexMonkium, the FlexMonkey Plug-In for Selenium, is publicly available!

FlexMonkium: The Movie

Posted in Stu Stern on February 27th, 2010 by admin
Once again, we bring you a video smuggled at great risk from Gorilla Logic Labs, deep beneath the surface of the Earth.

Last week, on this very blog, the world first learned of FlexMonkium, the FlexMonkey plug-in for Selenium. Now, we are pleased to present this exclusive video of FlexMonkium in action, allowing Selenium IDE to record both browser and Flex application interactions within a single Selenium script.

Although the recorded scenario is seemingly simple, it is actually quite wonderful. Selenium IDE begins recording on a plain html page, and continues recording as we navigate to a page containing a Flex application, and Flex application interactions are recorded to the script. Recording continues as we hit an html link ("Back") outside the Flex application in the browser page. For good measure, we continue recording as we navigate again to the page with the Flex app for further interaction, and then navigate back to the plain html page. All Flex and browser interactions have been recorded to a single Selenium script!

And of course, playback works as well.



Just a few more weeks and we'll be ready to release FlexMonkum! If you're interested in early access, please let us know.

Whole House Audio/Video Distribution

Posted in Eric Daugherty on February 24th, 2010 by admin
I have my house wired so that every television can access a shared set of sources (mostly).  I wanted this solution because everything I watch is recorded.  Therefore, I wanted to access each of my three DVRs on every television in the house.  Here is how I accomplished it.

First, I located all of the DVRs in the basement.  They are each run to every television in the house using different transmission mechanisms.  Here is a general overview of my system layout:

Most of the components are in the basement, with the exception of the disc based components (DVD Players and game consoles). 

The Basement and Family Room are in close proximity, allowing direct wiring of all the devices.  The DVRs are wired directly to the TV using Component and S-Video connections.  The sound is sent back to the basement from the DVD and game consoles using digital audio connections.  The speakers are wired directly from the AV Receiver in the basement.

The rest of the rooms require some alternative transmission mechanism.  For the Standard Definition (SD) televisions, I use a Channel Vision E4200 RF converter.  This devices takes up to 4 standard definition sources (audio and video) and modulates them onto broadcast channels.  I then combine the Antenna feed with the Channel Vision output and run it on the RG-6 that runs to each television in the house.  Now ever TV can tune to a channel, say 63,  and display the output from the SD DirecTV DVR.  I also have a Cat-5 run to each television with an IR Sensor.  This allows signals from that room to be transmitted back to the basement and be 'seen' by the components there.

For the second HD TV, I use a system from Audio Authority (Model 9871 + Wall Plates) to transmit a High Def (HD) component video signal, digital audio signal, and IR signal to the second room.  This system requires a converter box at the source and destination, but allows all of the signals to travel over a pair of Cat-5 cables. 

Here is an overview of the wiring:
The RF Modulator is a great solution for sending audio and video to SD televisions.  I even have an SD feed from the HD DVR so you can watch down-converted versions of the HD shows on any TV as well.

The Audio Authority system is great for transmitting HD video, as long as it is component and not HDMI.  See my rant against HDMI for more information.

I use a Niles IR system to capture/repeat the IR signals.  It has worked well, although there does appear to be a quality difference in the IR sensors.  Spend the money to get a good one.

For music I use my laptop to stream music to one of two Airport Express devices, attached to each AV Receiver in the house.  It isn't a Sonos, but it works.

I have a Harmony remote in each room setup to control the local TV and the DVRs.

Overall, I've been very happy with this setup.  It has been in place for over three years now and just works.  There are certainly other solutions to this problem, but I've been pleased with this for my needs.

We’ve released FoneMonkey, our record/play functional tester for iPhone

Posted in Stu Stern on February 23rd, 2010 by admin
We officially launched the FoneMonkey open source project today at http://www.gorillalogic.com/fonemonkey.

If you've been following my recent posts, you know that FoneMonkey is the world's first record/playback functional testing tool for the iPhone. FoneMonkey records user interactions with the iPhone, and replays them while verifying that actual results match expected ones.

Key FoneMonkey features:
  • High fidelity recording and playback of most iPhone gestures including touches, drags, and shakes.
  • Integrated script editor and test runner.
  • Recording and playback on both the simulator and actual iPhone device.
  • Extensible framework can be customized to provide specialized command recording and playback for custom components.
  • Simple Objective-API can be used to run FoneMonkey scripts using OCUnit.
With complete source, downloads, documentation, video tutorials, and a user forum available now at FoneMonkey Home, we are fully ready to monkey!

Five Pervasive Myths About Older Software Developers

Posted in Dave Rodenbaugh on February 23rd, 2010 by admin

I recently celebrated my 40th birthday.  A friend joked to me, “Hey, guess that means you’re too old to program anymore!”  I laughed on the outside, but it gave me pause.  Age discrimination is nothing to laugh about in our field.  COBOL guys faced this problem years ago as Java guys like me were ascending the ranks, and we laughed heartily about legacy code and their inflexibility with new technology.

Now the joke’s on me.  Maybe you too.  And if it’s not now, it will be soon enough.  Still laughing now?  Yeah, I thought so.

Computer Science Degree Trends 1996-2008

Source: CRE Taulbee Survey, 2007-2008, pub 5/09

Computer Science Enrollment Trends, 1995-2008

Source: CRE Taulbee Report

Our field is ripe for age discrimination in so many ways.  We value hot, new technologies, the ability to absorb them at unheard of rates, working insane hours to push products out the door–all things attributed to the younger workers of our field.  And did I mention that younger workers are cheaper?  A lot cheaper.  But the trends of computer science degrees do not bode well for having a plethora of young, cheap workers at a manager’s disposal indefinitely.  In fact, all data point to one conclusion:  CS degrees enrollments have been declining or flat for almost a decade.  And if anything, the candidate pool for hiring is getting worse, at least according to Jeff Atwood.  You’re going to have to hire someone to write your next project, and with the backlash against outsourcing, who you gonna call, Egon?

If you’re thinking you’re going to avoid the “grey matter” of software development, think again.  There are a number of myths about older software developers that continue to be perpetuated in IT and software development that somehow put older, experienced workers at a disadvantage in our field.  But they’re largely crap and considering the degree trends, ignoring everyone 40 and over because we’re too old seems plain foolish.  Let’s debunk these myths one-by-one.

MYTH: Older software developers are more expensive than younger ones, making younger developers more desirable.

REALITY: The real reason experienced developers are labeled as expensive is because staff salaries are the #1 expense of any software organization.  The fact is, younger means cheaper.  But, while inexperienced, younger developers may save you budget, but they will cost you in the long run if that’s all you have on your team.  Younger developers haven’t taken the lessons of failure to heart.  They haven’t had enough time to learn those lessons yet. And guess whose money they’re going to be learning on?  Yours.  Think that won’t cost you money in missed deadlines and incomplete projects?  Think again.

Yes, older software developers have higher salaries than younger ones.  But what exactly are you paying for here?  With an experienced software developer, you’re paying for all the experience that comes with past project successes and failures.  Those are expensive lessons if you want to pay for them directly during your tenure as a manager.  But if you buy into an experienced worker, that’s like getting insurance against some of those classic mistakes in project management and software development that you don’t have to repeat.  Meaning you look better on your annual review because you hired smart people that know how to get the job done.

MYTH: Older software developers are less flexible and less capable of learning new technologies because of their legacy knowledge.

REALITY: It’s actually because of their past experience, that more experienced software developers can migrate to new technologies, frameworks, and systems more quickly and in greater depth.  For example, if you learn a GUI framework in C/C++, you have a mental model about message passing, event handling, MVC patterns used to design the system and separate presentation from back-end logic.  The very first time you learn a GUI framework, in addition to the syntax, the examples, and the quirks of the library, you also need to learn all the conceptual stuff.  And after two, three or more GUI frameworks, you notice that they all have very deep similarities outside of the syntax.  You might even notice newer frameworks have overcome substantial limitations that you used to have to work around with complicated hacks.  Those insights are lost on someone new to the framework.  And those insights can really boost productivity in ways you’re not able to directly measure.

MYTH: Older software developers are less able to perform the arduous tasks of software development (read:  work long, painful hours) because of family commitments and other attachments that younger workers don’t have.

REALITY: I think it would be fair to state that experienced software developers are less willing to work those long, painful hours because they’ve learned the hard way that there are productive limits to pushing yourself 80 hours a week for months on end.  It’s called burnout, and I’m willing to bet that anyone who has already experienced it in the past simply isn’t as eager to go there again.  But with that said, the supposed reason of “family commitments” is bogus.  High-quality, experienced software engineers are ruthless time managers, and those with families are even more motivated to get things done in allotted times.  They may have dance recitals and soccer games to attend to, but they also make up that time in off hours and highly focused work during the 40 hours they’re given in a week.  Good software engineers with families must become highly efficient with personal time management or they quickly get buried with the deluge of work coming their way.

MYTH: Older software developers are less mentally agile than younger ones.

REALITY: Aging does affect the brain and it is measurable to show that older workers think more somewhat slowly than younger ones.  But mental agility is only part of the equation.  Thinking faster isn’t always better.  What about judgment?  There’s an old expression:

Good judgment comes from experience, experience from bad judgment.

Lost mental agility is a poor excuse to not hire an older software engineer in light of the fact they’ve seen, done, and lived many more successes and failures than a younger developer.  Experienced developers have tons of past projects to draw from and assist in avoiding bad decisions today.  Younger developers have new ideas which are important, but often untested and unproven.  Having both perspectives on your team is of great value.

MYTH: Older software developers are more jaded and cynical and therefore, less desirable in the workplace than younger ones.  Younger developers are more enthusiastic than older ones.

REALITY: Anyone who believes this is probably someone who doesn’t like their ideas criticized by those who’ve been around long enough to see really stupid decisions put into practice again and again.  Experienced software developers smell crap a mile away.  They don’t buy your stories about how the product isn’t well received in the marketplace because they’ve been interacting with the customers for years and know you’re trying to cover up a future layoff in the company.  They won’t put up with managers asking them to work 80 hours a week because the customer wants the software next month and they already told you it will take 3 more months to complete with the features agreed upon.

Younger developers haven’t been in those situations as frequently and therefore, have less resistance to bad management practices.  The only desirable trait management wants here is naivete.  If you want a great team and great products coming out of it, having people that can call you out on bad decisions will save your bacon again and again.  But only if you have the courage to admit you don’t know everything.

And as far as enthusiasm goes, you can’t tell me age dampens enthusiasm.  If that was the case, Donald Knuth, Ward Cunningham, Bill Joy, Bill Gates and hundreds of others who’ve crossed the magic 40 barrier would be less interested in our field just because of age.  But they’re not.  Passion is passion. If you have it when you’re 40, chances are you really love that field.  That kind of love isn’t going to die overnight.  Younger developers still finding their footing in the world may have short-term passion, but that can be swayed in the face of obstacles and challenges in the field along the way.

In conclusion, let me be absolutely clear about a few things:  Young is not necessarily bad. Old is not necessarily good. And most importantly, anyone who can’t program their way out of a wet paper bag shouldn’t be hired, no matter how old or young they are. Keep your teams a vibrant mix of age and experience–where diversity exists, learning can take place.  But if you’re the person looking to hire someone, don’t write off the dude with the gray hair sitting across from you.  Let go of your age prejudice and see if they can impress you.

Someday that dude (or dudette) may be you.

Related posts:

  1. Older Developers: Bad Habits Are Killing Your Career

Siri – The Next Generation of Appliance Computing?

Posted in Eric Daugherty on February 23rd, 2010 by admin
In my previous post, I discussed the trend toward computing appliances (ie DVRs, Kindles, etc.) instead of general purpose computers.  On the recommendation of Merlin Mann on MacBreak Weekly, I downloaded the Siri iPhone application and gave it a try.  Wow.

The Siri application attempts to be the ubiquitous Star Trek computer.  Just ask it a question and it will give you the answer.  It provides both voice and text interaction modes, and an easy user interface that exposes common feature easily.

It won't do everything you want, and I'm not sure this specific application will be something I use regularly, but at a minimum it provides an interesting example of where the world is going.  Imagine using this with what I imagine will become ubiquitous Bluetooth headsets.  Just ask a question and have the answer spoken to you.  We are not there yet, but we're starting to get really close.

This is an example of what I consider the appliance trend, applied to software.  The application provides easy access to a common (if limited) set of features that are intuitive to use.

Parsing Twitter with RegExp

Posted in Justin Shacklette on February 23rd, 2010 by admin

I needed a very simple Twitter cache for a project I’m working on. And I was very happy to trade off some realtime accuracy for reliability. In addition to caching the tweets, I also needed to pre-process them into css-able html with clickable links, usernames, and hashtags. The web had a few nice examples of how to use regular expressions to parse the raw tweet text, but I decided to take what I liked and do the rest myself.

Links

Here’s the PHP code for parsing links out of the raw tweet text:

$text = preg_replace(
    '@(https?://([-\w\.]+)+(/([\w/_\.]*(\?\S+)?(#\S+)?)?)?)@',
     '<a href="$1">$1</a>',
    $text);

I only wanted http and https links, with an optional query part (\?\S+)? and an option anchor part (#\S+)?. The conversion of a text link into an html link is done using back references, which in PHP is $1, $2, etc. In the expression above, I use $1 twice to put the matched link into both the href attribute and the link text.

Users

Here’s the PHP code for parsing Twitter usernames:

$text = preg_replace(
    '/@(\w+)/',
    '<a href="http://twitter.com/$1">@$1</a>',
    $text);

Nothing special, just take the @ and all following word characters (letters, digits, and underscores), and turn it into a user link.

Hashtags

Here’s the PHP code for parsing Twitter hashtags:

$text = preg_replace(
    '/\s+#(\w+)/',
    ' <a href="http://search.twitter.com/search?q=%23$1">#$1</a>',
    $text);

Getting the hashtags right was the most tricky of the three. I decided to only grab hashtags that were proceeded by one or more spaces. The real magic is the %23 in the query string, which forces a search on the complete hashtag, including the # part. For example, compare a search for #flex to a search for flex.

The Cache

The cache is just a simple cron job that periodically queries Twitter and retrieves the latest tweets. Most importantly, the cache fails gracefully if Twitter is inaccessible, which it does by doing exactly nothing if Twitter is down. This guarantees that my app always has valid data (when my server is up, the cache is up too), but with the possibility that the data is a little old.

Here’s the notable function in the cache:

function getTweets($user, $num = 3) {
    //first, get the user's timeline
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://twitter.com/statuses/user_timeline/$user.json?count=$num");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $json = curl_exec($ch);
    curl_close($ch);
 
    if ($json === false) { return false; } //abort on error
 
    //second, convert the resulting json into PHP
    $result = json_decode($json);
 
    //third, build up the html output
    $s = '';
    foreach ($result as $item) {
        //handle any special characters
        $text = htmlentities($item->text, ENT_QUOTES, 'utf-8');
 
        //build the metadata part
        $meta = date('g:ia M jS', strtotime($item->created_at)) . ' from ' . $item->source;
 
        //parse the tweet text into html
        $text = preg_replace('@(https?://([-\w\.]+)+(/([\w/_\.]*(\?\S+)?(#\S+)?)?)?)@', '<a href="$1">$1</a>', $text);
        $text = preg_replace('/@(\w+)/', '<a href="http://twitter.com/$1">@$1</a>', $text);
        $text = preg_replace('/\s#(\w+)/', ' <a href="http://search.twitter.com/search?q=%23$1">#$1</a>', $text);
 
        //assemble everything
        $s .= '<p class="tweet">' . $text . "<br />\n" . '<span class="tweet-meta">' . $meta . "</span></p>\n";
    }
 
    return $s;
}

First, we query the user’s JSON timeline using cURL. Second, we use PHP’s awesome json_decode function to convert the JSON into objects. And lastly, we iterate over the tweets and parse everything into our desired HTML output.

Here some sample output from my twitter feed:

<p class="tweet">Been reading Programming Goggle App Engine. Actually feeling dumber now than before I started. Too much to learn.<br /> 
<span class="tweet-meta">2:58pm Feb 14th from <a href="http://www.tweetdeck.com/" rel="nofollow">TweetDeck</a></span></p>
 
<p class="tweet">Blog Post :: Async Testing with FlexUnit 4 :: <a href="http://bit.ly/cGLnaI">http://bit.ly/cGLnaI</a><br /> 
<span class="tweet-meta">3:33pm Feb 11th from <a href="http://www.tweetdeck.com/" rel="nofollow">TweetDeck</a></span></p>
 
<p class="tweet">Blog Post :: A Better HTML Template for Flex 4 :: <a href="http://bit.ly/70DLsj">http://bit.ly/70DLsj</a><br /> 
<span class="tweet-meta">12:55pm Jan 25th from <a href="http://www.tweetdeck.com/" rel="nofollow">TweetDeck</a></span></p>

Once I have the output, I can do whatever I want with it: save to disk, stick it in the database, keep it in memory, cache it in memcache, etc. In my case, I wanted the simplest possible option, so I chose to write it out as a static html file.

The end. The rest of the app’s not ready yet…

FlexMonkium: FlexMonkey/Selenium Bridge

Posted in Stu Stern on February 22nd, 2010 by admin
Hey, all you Selenium people out there, get ready to monkey!

We've been getting a lot of requests about integrating FlexMonkey with Selenium to provide testing of "hybrid" test scenarios involving both Flex and non-Flex web apps. It is of course common to embed Flex applications within web pages that also contain non-Flex, HTML components, and the combined Flex and non-Flex pieces together produce a single user experience and workflow. Ideally, such hybrid user interface scenarios could be automated within a single test case. In fact, many times the functional dependencies between Flex and non-Flex components make it impossible to test one without the other.

While we've been hearing about many efforts to combine FlexMonkey with Selenium to provide for such hybrid testing, we're not aware of anything having yet been made publicly available, and having just completed development of FoneMonkey (which we're officially announcing tomorrow), and FlexMonkey 1.0GA (which we're releasing in about a week), we've had some time to take a look ourselves at how we might go about integrating Selenium with The Monkey.

After exploring various permutations, we hit upon a very robust approach through which we "slave" FlexMonkey recording and playback beneath Selenium. We have created a bridge, which we are provisionally calling FlexMonkium, that forwards FlexMonkey commands to Selenium during recording, and forwards FlexMonkey commands from Selenium to FlexMonkey during playback. Such FlexMonkey recording and playback is seamlessly interleaved with native Selenium recording and playback to easily produce hybrid testing scenarios. For example, in a single recording session you can click on HTML components and Flex components, even across multiple browser pages, with the resulting FlexMonkey and Selenium commands being recorded into a single Selenium script which (with the aid of the FlexMonkium bridge) can then be played back with any Selenium runner.

We are fairly confident we'll have something ready for early access in a matter of weeks! If you'd like to get your hands on FlexMonkium as soon as possible, contact us here.

Why the iPad will succeed, and the Rise of the Computing Appliance

Posted in Eric Daugherty on February 22nd, 2010 by admin
The iPad is an appliance, and it will be successful.  But before we get to that, we need to start at the beginning.

When I was a kid I ran a dial-up BBS service (The Outhouse) on a computer cobbled together from old donated computers and a few new parts I'd purchased.  I would take apart old computers (donated by my friends parents after their companies discarded them) and test the various parts for something I could scavenge.  I spent hours pouring over the massive Computer Shopper magazine to find the best deal on a new hard drive or modem.  This was the very definition of an (economy) do-it-yourself general purpose computer.

In my first two decades of computing I never purchased a pre-built computer.  I always assembled new computers from parts, or upgrade my existing computer (often replacing everything but the case and CD-ROM drive).  Pricewatch.com was my favorite site for a long time.

But along came a new device that started a big change, TiVo.  I bought my first TiVo around the year 2000.  It was something I could have built myself, but I realized that the convenience of having a dedicated appliance was worth the cost.  I just wanted it to work, and it did. Very well.

In the years since, I've been transitioning away from general purpose computers to appliances.  The Linux and Windows desktop/servers I used to run (24/7) have been replaced by a Linux based wireless router (Linksys WRT 54 GL) and a NAS (ReadyNAS NV+).  They provide nearly all the services the old general purpose computers provided with a few exceptions, and each of those exceptions have been moved to the cloud.  I've moved my website hosting and email hosting to the cloud using GoDaddy (< $5 month for web hosting) and Google Apps (Free).  They provide a better quality of service, at a minimal cost.  Along the way I migrated from writing and hosting my own email server (Java Email Server), to hosting email at GoDaddy, to free hosting at Google.  That is quite a shift in effort and cost.

The same progression is true with my other devices.  I now exclusively use laptops, and have not assembled a desktop more than 4 years.  I've also embraced Apple devices, which have more of an appliance feel than do other devices.  I use iTunes to manage my music, a couple of iTunes Airport Express units to listen to music on my stereos, and an iPhone as my mobile music device, and phone.  While one could argue that these are not really a change to appliances, I think they match the general trend.  Appliances provide a pre-defined (somewhat inflexible) experience that 'just works' as long as you stay in the provided feature set.  This is exactly what Apple excels at doing.

Finally, I've adopted a Kindle.  While I could read on a laptop, or an iPhone, this single purpose device excels at linear reading (ie Books).  I use it every day.

There are several reasons for this trend.  One is simple economics.  As the years go buy, I have more discretionary income, and more demands on my time (namely two young children).  The convenience of buying appliances versus tinkering has certainly changed for me.

I think there is more to the story though.  As the computing and home electronic fields mature, it becomes easier and more cost effective to create appliances that fit into our worlds.  Which brings us to the iPad.

The iPad is not the first device to attempt to move the general purpose computing environment to an appliance.  One could argue that it is really a descendant of the WebTV concept.  Take the primary activities people use general purpose computers for and put them into an appliance.  This brings up a brief and interesting digression...

Apple does not create markets.  Apple waits until a market is ready, and then delivers a product with impressive polish and ease of use.  MacBooks don't do anything a similarly priced PC can't do, they are just prettier and easier to use (or have been traditionally).  The iPod was not the first portable MP3 player, it was just better (including the iTunes ecosystem).  The iPhone didn't break new ground on smart phone functionality, it was just better (again, including the iTunes and AppStore ecosystem).  Finally, the iPad isn't new either.  Microsoft has had a TabletPC version of their Operating System since 2001.  The previously mentioned WebTV provided email and web browsing as an appliance experience.

Apple is attempting to build on these ideas, with Apple's traditional polish, iTunes ecosystem, and of course, Reality Distortion Field.  I don't know that version 1 of the iPad will be a success, but I am convinced that appliance computing will become a significant mainstream success.

Final Note to Developers: As Software Developers, we will always use a general purpose computer.  Just as a carpenter utilizes a set of tools to build a house, we will utilize a set of tools (ie general purpose computers) to build appliances.  Our goal should always be building applications in the appliance mindset.  My youngest child (2 years old) can turn on my iPhone and open her favorite puzzle game.  All of our computing experience should be this easy.

java.util.DuctTape

Posted in Jerry Andrews on February 21st, 2010 by admin
Overview

The proposed class, java.util.DuctTape, is designed as a general purpose fix for a variety of commonly-observed situations in production code. It serves as a temporary patch until a permanent solution is developed and deployed.

Features

DuctTape has the following features:
  1. Transform any internal data representation into any external representation without creating dependencies on either side.
  2. Transform any component interface into the interface required by any caller, again without creating dependencies.
  3. Perform branches into any point in existing code, and returns from any point in existing code, allowing for maximal reuse without recoding where logic already exists to perform some function.
  4. Intercept attempted calls to any unimplemented method and send an email request to support to perform the operation manually
Discussion

The utility of a properly-executed DuctTape implementation seems obvious. Once code is in production, users inevitably find edge and corner cases (and sometimes whole use cases) not anticipated by the requirements, design, implementation, or QA teams. The lead time required to implement these cases is often not available; a quick-and-dirty DuctTape-based solution is required to keep things running smoothly. A standard DuctTape implementation is far preferable to the hacks commonly used to hold things together until the next point release.

We urge immediate action on this by the developer community.

Acknowledgement

Thanks to Bob Hedlund for the original DuctTape class concept. Thanks to the TCAS team for suggestions on the feature list.