More recruiter telemarketer pre-screen questions

Here are the technical questions from the outsource recruiter:

1.  Given
uinsigned int x;
what does x & (x-1) do?

I haven’t programmed in C hardly at all since college, so I had to look up the order of operations on the internet, which is what any decent programmer would do with questions like these anyway.  Turns out, as I thought, that parentheses trumps everything, even bitwise AND (whose precedence is lower than I thought and bitwise operations aren’t performed left to right, which was a surprise to me, but I digress.)

Like most human beings, I’m not good at bitwise calculations, and if there’s a trick to this one that sophomores memorize, I don’t know it. 

Here are a few sample calculations:

x	= 1	→ 000001
x-1	= 0	→ 000000 &
result	= 0	→ 000000

x = 2 → 000010 x-1 = 1 → 000001 & result = 0 → 000000
x = 3 → 000011 x-1 = 2 → 000010 & result = 2 → 000010
x = 4 → 000100 x-1 = 3 → 000011 & result = 0 → 000000
x = 5 → 000101 x-1 = 4 → 000100 & result = 4 → 000100
x = 16 → 001111 x-1 = 15 → 001110 & result = 15 → 001110
100101 100100 & 100100
110110 110101 & 110100

I don’t see any pattern from this limited set.

2.       On your platform, what are sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(float), sizeof(double)?

You don’t know what my platform is, so you can’t know if I’m right or wrong,  but I ran this quick program on my x86_64 Windows and x86_32 Linux computers and got the same results:

C:\aaron\projects\c>cat sizeof.c

#include "stdio.h"

int main()
{

        printf("sizeof(char) %d\n", sizeof(char));
        printf("sizeof(short) %d\n", sizeof(short));
        printf("sizeof(int) %d\n", sizeof(int));
        printf("sizeof(long) %d\n", sizeof(long));
        printf("sizeof(float) %d\n", sizeof(float));
        printf("sizeof(double) %d\n", sizeof(double));
}

C:\aaron\projects\c>gcc sizeof.c -o sizeof

C:\aaron\projects\c>sizeof.exe
sizeof(char) 1
sizeof(short) 2
sizeof(int) 4
sizeof(long) 4
sizeof(float) 4
sizeof(double) 8

Results are in bytes.

3.  Given a structure
struct X {
chat c;
int i;
};

What is sizeof(X)?

Well, a couple of points first:

  1. I don’t know how big a “chat” is – I’m assuming a typo and that it should be “char”
  2. You would need to measure sizeof(struct X) or create an instance of it to get sizeof()
  3. [aaron@qa-site ~]$ cat sizeofstruct.c
    #include "stdio.h"
    
    struct X {
            char c;
            int i;
    } X;
    
    int main()
    {
            printf("sizeof(X) %d\n", sizeof(X));
            printf("sizeof(struct X) %d\n", sizeof(struct X));
    }
    [aaron@qa-site ~]$ gcc sizeofstruct.c -o sizeofstruct
    [aaron@qa-site ~]$ ./sizeofstruct
    sizeof(X) 8
    sizeof(struct X) 8
    

    My guess would have been 5, for sizeof(int) + sizeof(char), but gcc (at least) pads the struct for efficiency.


    4.  Enumerate sort algorithms that you know, and specify their runtime in o notation.

    The sort algorithms that I know of off the top of my head are the bubble sort and the quick sort.  There are plenty more, and an infinite variety of special cases which depend for efficiency on the goal of memory or processing efficiency based on the expected data.

    I don’t even know what “specify their runtime in o notation” means, but a bubble sort (of integers) looks something like this (in pseudocode):

    list = e.g. { 2, 5, 1, 8 , -3}
    
    sort(list):
    	while (increment(iteration) < length_of_list )
    		while (increment(count) < list[count + 1])
    			if (list[count] > list[count + 1])
    				swap (list[count], list[count +1])
    

    Essentially, it loops through the whole list the number of times there are elements in the list.  For each element, it compares it with the next (it could also be done by comparing with the previous) element and swapping the two if they are out of order.  The reason it has to repeat is that it only shifts one place on each pass, and doesn’t compare with elements before it.  It is straightforward, but very inefficient.

    A quick sort starts by finding a “middle” and then splitting the list and comparing against both sides and shuffing each element that way.  A more memory intensive modification that would be quicker is to copy elements into a new list, adding them above or below as they fit.

    I suppose I could have looked up more sorting algorithms on the internet (or from a book), but that’s probably not the point of this exercise.

    If you’re looking for an experienced C programmer, that’s not me.  If you’re looking for someone who memorizes bitwise operations and sorting algorithms, I’m afraid I don’t think I’d be interested in working somewhere [where|that] that is an important criteria.

I love outsource telemarketer recruiters

I’ve gotten quite a few calls today from recruiter telemarketing call centers in India.  One was for a local company that handles most of the contracts at a very large local software company (which also sells keyboards and mice.)

Anyway, I’m a little more desperate for work now, so I thought I’d humor this one and fill out their forms.  I started off okay, but got a little tongue in cheek towards the end for a position I’d probably consider “beneath me”, which I’m probably not qualified for, at a company I’d prefer not to work.  Of course, if they like my answers, I think I’d change my mind about wanting to work there.

Here are my answers:

Screening Test

1. What is ad hoc testing?

Ad hoc means that it does not follow a detailed plan. It can either be done through normal usage or exploratory testing. It is a good idea to plan for some amount of “ad hoc” testing, as it may reveal unanticipated defects, or help identify areas that could be targeted for future, more methodical testing.

2. What goes into the body of a good bug report?

First of all, a bug report summary should be contain a concise description of the problem that makes it easier to search for, and identify the problem specifically. The body of the report should contain a more detailed description, as well as steps to reproduce the problem, expected results (as well as the actual, unexpected result), and any necessary setup or data needed. Attachments with further information might include an excerpt of the log file or screenshot identifying the problem.

3. What is the difference between priority and severity?

The severity of an issue reflects how great of a problem it is believed to be. Indications of severity might include the number of users or amount of the system affected by the issue. Priority, on the other hand, represents a decision as to how important it is that the issue be fixed. Priority is, by definition, a relative measurement, while severity is qualitative. Two issues may be identical in severity, but have different priorities. While severity and priority are often correlated (a high severity issue is likely to be high priority), it is not necessarily so.

4. What is regression testing?

Regression testing is done to ensure that the quality of code does not “regress” or decrease. Regression is also sometimes used to mean the “recurrence of defects”, though that usage is not as intuitive. The purpose of regression testing is to verify that the system continues to perform as expected after changes have been made. The practical method of ensuring this is to re-execute tests that have been known to pass previously. A major challenge with regression testing is that as the system grows over many iterations, the amount of regression testing increases to the point where it is not practical to execute all tests. Automation of regression tests helps, but is not a complete solution for this problem. It can thus become necessary to target a subset of all tests for regression.


5. What are the different test categories that test cases are commonly grouped by?

There are several categories of tests. Common usage includes:

  • unit tests – designed to test individual code components in isolation
  • integration tests – designed to test several units of code working together
  • functional tests – designed to test the features or requirements according to the design. These are sometimes also called “acceptance tests”, though “user acceptance tests” are also sometimes considered a separate category, since they are performed by, or in behalf of the end user.
  • system tests – designed to test the system as a whole. “System integration tests” tests multiple systems interacting the way lower level “integration tests” test individual components interacting.

Other types of testing include performance testing, load testing, penetration testing, security testing, usability testing, etc.

6. How would you test a light bulb?

If it was in the socket, I’d turn on the switch and see if it lights up. If not, I’d shake it and listen for a rattle that would indicate that the filament is broken. Seriously, I know this isn’t what you’re looking for, but I thought I’d take the opportunity to make a point about requirements rather than play the interview question game anymore.


7. When is a product ready to ship?

It’s always ready to ship. Don’t you practice Agile, use continuous integration, and shoot other silver bullets? Truth is, that’s a management decision, not a measurable quantity of quality.

what java generics gets wrong about hashes

If you’re actually using a hash, this is what you really want to do:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@SuppressWarnings({ "unchecked", "serial" })
public class DrSuess {

   public static void main(String[] args)
   {
      Map foo = new HashMap()
      {
         {
            put(1, "fish");
            put(2, "fish");
            put("red", "fish");
            put("blue", "fish");
         }
      };

      Iterator i = foo.keySet().iterator();
      while(i.hasNext())
      {
         Object key = i.next();
         System.out.println(key + " " + foo.get(key));
      }
   }
}

but generics frowns on it.  A Dictionary could be  <String, String> or an AssociativeArray could be <String, Object>  but a Hash wants to be able to put anything in it.  Give me useful subclasses, not the useless crap that is Java generics.

challenges in test environments

So you’ve got your basic testing framework,  100% unit test coverage, a pile of functional tests, automated builds, and and a decent deployment script.  In short, you’ve acheived the 1 click holy grail of test automation.  Your functional tests run automatically every hour, after every checkin, or whenever you feel like it — against a clean system with the newest code.

Why haven’t you attained testing nirvana yet?

Well, there are still a few more challenges you might be facing.  Here are some that I’ve run into:

Email & Other Services

Many applications need to send (or worse, receive) email.  How do you handle that?  At the unit level, you can use a simple mock, and at a higher level you can use dummy server like MailTrap or Dumbster.  But what if you really need to test that emails are being sent?  You could also use a simple SMTP server like James, but sometimes you need to be able to test with a production-like mail server, which can require special expertise.

If you’re sending actual emails, that opens up a whole slew of new issues.

What about network policies, spam filters, etc? Besides the technical challenges, there can be bureaucratic issues to deal with.

How do you check reply-to addresses in the test environment if the server names are different?

How do you test external mail systems?  If you’re sending email, where do you send it? You could set up test hotmail or yahoo accounts or use a temporary service like Mailinator.

How do you verify email results?  It can be challenging, especially stepping outside your app.  Webmail apps (like Gmail/Hotmail/Yahoo) resist automation efforts, and rich clients aren’t automatable using web automation tools like Selenium.

What if you need to test how it looks in multiple mail clients, or formats?  One time, I wrote a test to verify text vs. html formatting and had it send mail to my personal email address where I could check it with mutt.  Someone “borrowed” my code, and I ended up with over 100 test emails every night when the billing regression scripts ran.

That’s just email.  It’s the most complex, but you might have other services and systems that are needed.  FTP, Cron, VPN, SNMP, etc.

External Systems

Besides the services such as Email that are often considered a part of the underlying operating system, there are other applications that may interact with the system under test.  There are a variety of reasons that it may not be feasible or practical to use them including licensing issues, complex installation, and often an insurmountable hurdle — you don’t own the system.

Web services can fall into this category, as well as SAAS systems.  Examples include Payment Processing, Address Verification, etc.

While test systems might exist (if you’re lucky), they are often not as robust or performant, and may have restrictions on the number of requests, and the complexity of the response.   There are also potentially firewall and security issues.

You may have to build mocks, which don’t cover the range of potential circumstances, or even simulated services, which could have their own bugs (or not expose actual bugs in the production system.)

External systems are a significant challenge to integration tests, and sometimes isolating your system from them is not desirable or even possible.

Firewalls, Networks, Load Balancers, Latency

I’ve touched twice already on network and firewall issues,  but besides the corporate LAN firewall, there is the issue of testing against a realisting production network, which can include firewalls, a DMZ, load balancer, clustered servers, and traffic shaping.

How can you test a complex deployment environment?  I can tell from first hand experience that some of the trickiest bugs can surface when you start using multiple application servers, or when your load balancer mangles your session information, or when the database isn’t on the same server as the web front end.  How can you be sure that your intrusion detection system won’t proactively block a webservice (or prevent a real DOS attack.)

A complex network also means that result times aren’t going to be the same.  Not only do clients not connect over 100 MBit ethernet, but a production network topology will have it’s own latency issues.

Performance

Besides network latency, there are other performance issues that are challenging to tackle.

How do know if performance in your test environment is adequate for production?  (I actually had an incident once where the test server was significantly newer than production, so while it performed adequately in test, it was unacceptable in production.)

You may not have budget for the same hardware in test that you have in production.  You might not be able to load balance across multiple application servers because you don’t have licenses for it.  Your database won’t have the same volume of data.  All these and more can be challenges to your test environment.

Production Data

I mentioned production data in relation to performance, but besides the volume of data, there are other issues in attaining production-like data.

One of my favorite bugs is one that was dependent on production data.  I don’t remember what it was, but some data in production had invalid characters (unicode or 2 bit asian)  that was causing our system to blow up, but we couldn’t reproduce it test, no matter how hard we tried.  Turns out that recent versions of the content management system disallowed or escaped them, so they weren’t an issue in test, even if we cut and pasted the offending text.  It was literally impossible to reach that state.  But it was happing in production.  The only way I was able to find the issue was by installing TCPDump on the production server to capture the stream.  Thank goodness for a cooperative sysadmin.

I guess the issue of that story has more to do with production-like systems than data, but it was caused by real production data.

I remember another issue with production credit cards failing.  Of course we couldn’t tell what the cards were, because we didn’t store the card numbers, just a hash.  That one was because our code didn’t expect card numbers greater than 16 characters, and they were being truncated.

The point of these stories being that production data sometimes does stuff that you don’t expect.  And sometimes there’s no substitute for production data.

In the case of credit card data or other sensitive info, how can you pull from production? You might need to scrub data to avoid identification.  And knowing just what you need to pull from production can be challenging.  You don’t need that 20 million row transaction log, or do you?

Time Dependent Results

Credit card processing reminds me of another issue:  Time Dependency.  You might run credit cards as a batch every night at 12:30, but can your simulator or test system handle that?  Do you have to wait until midnight to check your credit card failure test cases?

What about billing, which may only run once a month?   Or email newsletters?

What about daylight savings?  Everyone testing time sensitive applications a couple years ago remembers the daylight savings switch.  (I’m expecting it to switch back real soon now — and billions more in lost productivity, but it’d be worth it for more realistic times.)

How can you check cron (and other scheduled) events?  Changing the system time may work for some, but not for others.

What about timezone issues?  Are your test servers and production servers running on UTC or local time? Are they all in the same time zone?  What about external systems?

Manual Intervention.

With many of these issues, I’ve found there are some things that can’t be fully automated, or automation isn’t worth the effort.  You might have to separate some of your tests out that require manual intervention.  How do you flag a test that is 99% automated, but requires one step that can’t be automated or can’t be easily automated.

Test Organization and Maintenance

Apart from all the technical hurdles, there are the challenges of test organization and maintenance.  When you have hundreds (or thousands) of functional tests, how do you keep track of them all?  They are not simple and isolated like unit tests.  They are environment and system dependent.  They may require manual steps.  They may dependent on data setup, or other tests passing.

A test may pass but no longer be testing anything of value.  Or it may fail do to some UI change or process modification.  They are brittle.  They are complex.  You can follow good practices to combat these problems, but you can’t avoid them.

And then there’s the matter of how long it takes.  Eventually, your functional tests are going to start taking longer to run.  How do you break them down?  You can have a core/full regression.  You can separate acceptance tests and regressions.  You can have smoke tests.  It’d be nice to be able to tell which tests are affected by which system changes, but sometimes you can’t be sure.  Or you can be sure and wrong.

One incident I remember involved changes to the admin interface, a completely separate application.  So the customer application didn’t need regression tested, right?  Except that a base class that both applications inherited from was accidentally modified by an ambitious IDE refactoring.

This long rambling post describes some of the challenges that may arise once you have successful test automation in place.  I could say that the moral of the story is that there’s no silver bullet, but that would be glib.  Being aware of the issues and potential workarounds can only help.

Have you encountered similar (or other) challenges with test environments?  What have you don’t to surmount them?  I’d love to know.

link_to considered harmful

Why do all websites built with Rails suck?  Or rather, why does the UI for all websites  built with Rails suck?  And why do 99% of them have the exact same UI — you know it, a solid  (usually reddish)  stripe across the stop, a menu separated by pipe (|) characters,  square tabs, large fonts, grey boxes & sidebar  , etc.  Make’s you long for rounded corners.

railspages

Of course it is probably based on the original simplistic design of the Agile Web Development with Rails demo app.  Several other books and tutorials have followed the pattern, which is all fine.  Programmers learning to program don’t need to focus on design.  But why do so many real production sites copy this (lack of) design?

It’s because the programmers are designing the sites.

Hi, my name is Aaron, I’m a programmer and I design my own websites.

Or rather, they’re not designing them.  They’re borrowing a design from a tutorial, and letting Rails take care of the rest.  Now, I’m not saying it’s impossible to design a pretty website that uses Rails.  I’m saying it’s *very difficult* to design a website that uses Rails unless you, the designer, are a Rails programmer.  Not just a casual programmer, but familiar with the internals of Rails.

Because Rails wants to design your UI for you.  And Rails wants to prevent you from creating your own UI.  Rails wants to generate your HTML.  Let me repeat that, because it’s the core of my argument, and I’m in a condescending mood:

Rails wants to generate your HTML

Don’t let it.  We should ban link_to as well as form_for and other functions like it. Let’s summon Dijkstra’s ghost, remake him as a graphic designer, and get rid of link_to and it’s ilk.

The problem is, designers can’t get into your controllers and views and edit the page presentation, because you’re using link_to.  They can’t even see what a link looks like, much less a table (“THE HORROR!” chants the CSS zombie brigade) full of content that might include links.

You could use ERB to get rid of them:

<a href="<%= site.page.link.url %><%= site.page.link.text %></a>

But there is a better way, and it’s been around for ages.  Use attributes for real HTML tags to identify dynamic elements.

<a id="my_dynamic_link" class="please_parse_this_for_me">Link Text</a>

You can use components to build complex HTML elements like Menus, Tables, and other complex components:

<ul id="my_dynamic_menu"><li> example row to be replaced by dynamic content</li></ul>
<table id="my_dynamic_table">
  <th>
    <td> number </td>
    <td> title </td>
    <td> summary </td>
  </th>
  <% site.page.table.each do |row| %>
  <tr>
    <td> <span id="row.number">default number <span> </td>
    <td> <a id="row.title.link" href="default link">default title</a> </td>
    <td> <span id="row.summary">default summary</span> </td>
  </tr>
</table>
<div id="mytree" class="fancy.dynamic.nested.tree.component"/>

Ruby is silly

Ruby is a silly programming language.  I’m not trying to start a flame war, and this isn’t really a rant.  There is a lot I like about Ruby, and it gets more right than most any other language.  But it has it’s idiosyncracies, and here are some of them:

Syntax

I’ll start with the simplest thing to pick on, syntax.  While everyone has their own preferences and in part it depends on what you’re accustomed to, there are some objective judgments that can be made.

My personal pet peeve is the function definition keyword def, which is short for ‘define’.  Define what, though?  A function, of course.  While ‘def’ might be preferable to ‘fun’, it is less descriptive.  Why not use ‘def’ to define a class, if everything is an object?  This is a relic from earlier languages when functions were the only abstraction, thus the only thing you could define. That was so long ago that there was only enough memory for three letter commands.

Then there is the iterator syntax.  In the name of making code easier to read, you get idioms like 5.times do … and fishes.each do Interesting, but nothing at all like English.  You might suspect that since Matz is Japanese, that it might match the sentence structure of that language — but it doesn’t.  The words are English anyway.  If the phrasing is pidgin, then it’s even more silly.

Which brings me to do…end.  Why take away the braces?  It used to be the accepted way to group blocks of code (and is still allowed for unnamed blocks) but there was also the option of using ‘do…end’.  Braces were then discouraged, then banned.  All in the name of readability but, as pointed out already, that’s not readable in English.  Not only does it take more keystrokes (and storage space, and screen real estate), it is also distracting and makes parsing the code more difficult, both for the interpreter and more so for your eyes.  Also, ‘do’ is almost always superfluous.

Function names

There are a lot of silly function names in Ruby.  You can bash PHP for function names like ‘strnicmp’ but that is actually following a convention that has a 30+ year pedigree.  But in Ruby, for example, sub is used for ‘substitute’ and gsub for substitute all.  But those are the venerable (thankfully retired) words first used to define and invoke functions (subroutines).  Which reminds me that ‘end’ is also a keyword with a past that has a more accurate meaning.   Using puts as a synonym ‘print line’ is another example.  ‘Puts’ means ‘put to the screen’, but Ruby uses ‘puts’ for standard IO.  And while it uses getc to get a character, puts and gets read lines, not strings.   ‘put’ and ‘get’ would be better, and also more in line with traditional usage.

Blocks

Blocks are nothing more than unnamed functions.  While many Ruby fans think they are the greatest thing since sliced bread, there are several disadvantages to blocks.  The first is the potential for inefficiency.  It is easy to get in the habit of passing around blocks, and algorithms in blocks.  Because blocks are first class objects, it is not the same thing as passing around function pointers, although they are passed by reference.  Which means they have identifiers on the heap/stack/whatever, anyway.

Unnamed blocks are great, occasionally, for 1 liners.  But do you then really need a block?  By which I mean, do you need to pass a block for execution?

Another problem is that because blocks are not named, if they have much practical use, you start cutting and pasting blocks.  That flies in the face of “Don’t Repeat Yourself”, and can lead to maintainability nightmares.

Because blocks are unnamed, they are undocumentable.  The first and most important part of documenting a subroutine (which is what a block is) is giving it a name.  A descriptive name is good, though I realize that names that describe what many blocks do would end up being longer than the code block itself, which is a succinct description of what it does already.  And because they are not isolated, they cannot be described in their definition as objects, even though that’s what they are.

Iterators

Blocks wouldn’t be much use without iterators.  In Ruby, iterators have a different syntax than other languages.  Objects have built in iterators, which is sometimes nice, but with the cost being that it makes objects much heavier.  Even simple integers carry this weight around with them.

A significant performance (and memory usage) improvement could be achieved in Ruby just by separating iterators from base objects.  Because of their baggage however, almost no operations that require any degree of efficiency can be written in Ruby.

For most objects, you end up implementing your own iterators anyway, and since you might need multiple ways to iterate, a single solution often isn’t useful.

If you want to have collections that are iterable, by all means have them, but don’t pretend that arrays are iterable.  That’s a job for lists.

Give me the choice of having expensive functionality (of which iterators are just one example) or not, so I can write more efficient code if I want.  And give me transformations (methods or casts) so I can get at the base array, hash, or collection beneath the iterable, sortable behemoth.

[Side note: I don’t know of any languages where casts are first class objects, but that could be an interesting idea]

Closures

Closures are sometimes neat, but you’re just passing around blocks and iterating lists.  The same thing can be done almost as easily iterating over regular lists and calling functions.

Symbols

Symbols are a really clever way to avoid the deadweight in Strings.  Symbols are useful in their own right, but it’s really a workaround for the overweight object that Strings have become in Ruby.

Everything is an Object

There really are basic constructions below the level of an Object.  They exist in Ruby but the language, by design, makes it difficult to access them.  While it’s useful to think of everything (like numbers, blocks, and class definitions) as objects, it doesn’t make sense to have them all descend from the same base Object.

Mixins

Mixins are just global (package/namespace scoped) functions.  It is sometimes a handy abstraction, and since functions are first class objects, there is no OOP religious reason to not allow them.  Weak “duck” typing makes it possible to pass unknown types, but also makes it brittle, except with simple types that are easily cast such as String, Integer, Float, and Character.

Other

A few miscellaneous points:

Why single line comments only?

Variable scope sigils: @, @@, $ and none. I can’t think of a single reason for the variety except to avoid implementing scope tracking in the interpreter.  Making scope self documenting by enforcing it with syntax is debatably beneficial, but it is a strange arbitrary selection.  I’d vote for consistency first.

Conventions which are almost compiler rules:  CONSTANT,  boolean?, change!, assign=

Capitalized True and False.

Implicit return values.  Not all subroutines return values, or always return values.  By implicity returning the last lvalue, you could potentially return the wrong thing.

definitely need better time management

Some days I’m filtering through all my email, tweets, and open tabs (the last list almost never gets shorter).    Some days I sink hours into getting the littlest thing to work.   In short, I need to manage my time better.  I’d say 90% of my real productivity is accomplished in 10% of my time.  Maybe less.

It’s not a new subject, and it’s certainly not unique to me.   I’m always vowing to do better, and sometimes I do, for a while.  This latest bout was sparked by an article (probably from a link on twitter)

http://www.swaroopch.com/blog/why-i-do-time-tracking/

There’s nothing new there.   The gist is:

  • Track your time to find out where it’s going
  • Avoid interruptions & timesinks

I could add

  • Prioritize

There are 10 points the author realized, a couple of which I found useful:

stop reading tech news websites during work hours and stop twittering.

switch off internet during the first two hours of work everyday

restrict time in front of the computer on weekends and outside work hours

work better when there are big chunks of work as opposed to many small things

more productive if I wake up early

count exercise time also as productive time

I think a big part of the problem is the context switching.  don’t read an article while you’re waiting for tests to run.  The tests will be done in 5 minutes, but you’ll spend 10 minutes reading the article (and 10 minutes reading the comments, and 10 minutes on a good link and…)  While that is useful time, it’s not productive time.  Budget time for browsing and researching, but don’t let it cut into productive time.

I thought to break tasks into several categories.  First there is productive time (coding, writing,  and learning) then their is non-productive but necessary time (administrative, setup, & maintenance.) This could also include meals, sleep, and exercise. Then there is communication time (email, phone, meetings).  This doesn’t include twitter, IM, and reading blogs.  That can fall into the next category, speculative time (networking, researching.)  Then there is leisure time.  Be honest, most of your “research” falls into this.  If you find something specific you need to research, create a speculative task for that specific subject, and timebox it.   Then there is wasted time.  If you’re wasting time, stop.  At the very least, pick a leisure activity and do it so that you can get enjoyment out of it.

In my last bout of time management mania, I decided I would get up early and spend two hours on one task – coding or writing.  That’s a good idea.  If I close shop the previous day with setup for that morning, I can jump right in.  No setting up the server, looking for pen & paper, cleaning out email (nothing important needs a response before 8am or after 5pm), or installing the right tools.  That means you can do research in administration work in the late afternoon when you don’t feel like being productive.

Don’t let that stifle creativity.  If you wake up with a good idea, pursue it, for 1 hour.  Then stop.  Prioritise, and move on.  Chances are, you killed your morning productivity, but at least you don’t have the idea scratching to get out.

If you don’t feel like doing what’s important, do something you can’t justify doing that you’d really like to do–  timesinks like redesigning your website, checking out a new framework, tinkering on that side project, etc.  You’re still being productive, you’re just breaking priorities.  Just don’t get too wrapped up in it without taking another look at your priorities.

After your morning productivity, it’s time for communication and business administration.  8-10 is communication time (or 9-11.)  The important thing is to get your communication done before lunch, so you can hopefully get another creative period in.  Stop reading after lunch is over, knowing you can go back to it soon.  Just a couple more hours productivity until that blood settles in your stomach (be sure not to have too big of a lunch).  Get up and take a walk to get your juices flowing.

If you find yourself drifting or getting frustrated in the afternoon, take a break.  Read some blogs.  Or write something useful in your own blog.  Or network (IM a friend).  But then as the day gets later, take a look at those small tasks.  Things that can take 5 minutes to 1 hour to complete.  Try to knock a few off.  It’ll make you feel worthwhile, and might get you back in the mood for work.

If you get going again (for a potentially 3rd creative period), be sure to stop short.  Take care of a few administrative tasks, including prioritization, to be able to be ready for your early morning work.  That’s your most productive time, and even if you’re on a roll now, it’s better to put a cap on it and let the juices ferment and the well refill for the morning.

windmill testing framework

I thought I’d take a look at a new browser-driving testing tool called Windmill.

Windmill is similar to Selenium, in that it drives the browser via a proxy.  It has a test recorder, similar to Selenium IDE, but includes a DOM explorer and firebug-lite.  It also has an interactive shell, so if you like running Watir via irb, you can do that.  Friendlier than the Selenium interactive interface.

Windmill is written in Python and can be installed with easy_install.  However, it doesn’t seem to work with Python 2.4 (it requires ctypes, which I believe was added in Python 2.5).  I tried it with Python 2.6.2.  It also requires pywin32.

It seems to have a cleaner architecture than Selenium, since you run it through the Windmill controller, though this is roughly analogous to instantiating a browser object in Selenium.  However, I had some trouble getting it to work on windows.

Oddly enough, it seems to work with IE, but not with Firefox.  When I try the example:

C:\Python\26\Scripts>windmill.exe firefox http://www.google.com

Traceback (most recent call last):
  File "C:\Python\26\Scripts\windmill-script.py", line 8, in <module>  load_entry_point('windmill==1.2', 'console_scripts', 'windmill')()
  File "C:\Python\26\lib\site-packages\windmill-1.2-py2.6.egg\windmill\bin\windmill_bin.py", line 33, in main admin_lib.command_line_startup()
  File "C:\Python\26\lib\site-packages\windmill-1.2-py2.6.egg\windmill\bin\admin_lib.py", line 357, in command_line_startup shell_objects = setup()
  File "C:\Python\26\lib\site-packages\windmill-1.2-py2.6.egg\windmill\bin\admin_lib.py", line 179, in setup shell_objects_dict['browser'] = getattr(shell_objects, browser[0].lower())()
  File "C:\Python\26\lib\site-packages\windmill-1.2-py2.6.egg\windmill\bin\shell_objects.py", line 45, in start_firefox controller.start()
  File "build\bdist.win32\egg\mozrunner\runner.py", line 138, in start 
  File "build\bdist.win32\egg\mozrunner\runner.py", line 62, in run_command
  File "C:\Python\26\lib\subprocess.py", line 595, in __init__errread, errwrite)
  File "build\bdist.win32\egg\mozrunner\killableprocess.py", line 158, in _execute_child pywintypes.error: (1, 'QueryInformationJobObject', 'Incorrect function.')

The browser spawns, but sometimes gives this message:

Proxy Server Refused Connection

The rest of the time, the windmill window also opens, but stalls with:

Reverting to JavaScript includes..
So, I’m going to give windmill a pass for now.  It looks interesting, but Selenium works now.  Maybe that’s just an argument for Java over Python (at least on Windows).

Ask a good question poorly

and you still might get an answer.

I’ve been looking (not very effectively) for freelance test consulting work for the past 6 months.  Mostly that’s meant keeping heads down working on QA Site and Taskboard, writing the occasional blog post, networking through Twitter, and  telling every recruiter that calls me that I’m looking for independent work.

It didn’t work.  I knew I should have networked better (though I am getting better), and I should have tried marketing myself somehow (how, though, sales cold calls?)  I was clueless, as well as bit shy, and perhaps a bit too interested in refining my own vision of a product instead if doing any real customer validation.

Well, now I’m almost out of money and looking for  full time (or contract) work.

About a week ago, out of curious  rather than bitter desperation, I posted a comment on  an article on Seattle 2.0 about bootstrapping your startup through consulting.  Turns out someone saw my comment and respondent with their own blog post.  It looks like I’ve had the tab open for a few days, but never got around to reading it, and was actually completely unaware that it was “about” me or my previous comment.

Surprising, and somewhat flattering.   I actually looked through the bullet points: Networking, job boards, freelance sites, social networking sites, blogging/articles, marketing yourself, and my favorite — a sandwich board.

board11

I thought, “great, this doesn’t help me.”  But after reading more carefully, I realized that while there is some takeway from it (and I might try the sandwich board when the weather cools a bit),  the details acknowledge the limitations and difficulties of each method.   There was a list of  some interesting suggestions at the end about how my situation (and that of others like me) could be improved:

What could make it so much easier to find an independent consulting role?

I particularly liked the following suggestions:

2. A stronger referral network than exists today amongst the independent consulting community?

3. A tailored recruitment service specializing only in freelancers ?

In retrospect, I should really have done more writing:  tutorials, product reviews, etc.  I did write a presentation, but that was mostly to test out google apps and LinkedIn:

http://docs.google.com/present/view?id=dqpnt2f_8cx73f3f3

It could use some more fleshing out.

Besides writing, I do think that getting more involved in the “community” is a good idea.  I’ve missed a couple of QASIG meetings, and attended a couple of others of it’s type, but they seem more geared towards the “industry” (translation: employers & employees.)

Perhaps the community I need to target is more the developer community, in particular, the startup community where I’d hoped to find my most likely “early adopter” potential clients.  It seems that much of the startup community I’ve seen (including Seattle 2.0) is more of a “business” than a community however, no offense.  From pay-to-participate gatherings, to office space and web designer promotion, I haven’t seen much value to me, personally, though I could be missing something.

I should spend some more time giving back.  And that means more than just tutorials on my blog, participating in forums as someone with helpful answers, not just questions.  I’ve tended to avoid stuff like that not out of selfishness, but out of the fear of it eating up too much of my time.

It seems that every successful freelancer I’ve talked to (or heard much about) has given back, whether in the form of writing a book (with useful information) or maintaining a mailing list (or plugin repository.)

I could also have worked better at networking, though like I said, I’ve improved.  I’ve found twitter particularly helpful, since if I find an insightful blog post, tool, or author I like, by tweetering at them I sometimes get a response.

I hope to spend more time talking with successful freelancers and entreprenuers and gaining more information from them.  And perhaps their commentary (like Matt Doar’s) will make my blog a bit more readable.

If someone happens to read this and has some insight to share with me, I’d love the feedback.

I’d also like to thank Ben Curtis (of the Rails Plugin Directory) for his advice over lunch the other week.  He’s graciously promised to give me feedback if I ever get him a QA Site with some test results up.

I’d like to post more interviews, and get more people willing to give me feedback as well.  There may even be a lunch in it.