Sunday, January 31, 2010

BOOK: Winning with People

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/book_winning_with_people.htm]

I am not a people person. However, I do love software engineering, and I recognize that no software engineering project will succeed without people. 95% of every project failure I've ever seen (or heard of) has ultimately been due to people reasons, not technical reasons - two coworkers can't get along, the manager leads the team in the wrong direction, the tech folks can't get the requirements from the business folks, the QA and dev teams bicker about what's "really an issue", etc... Hence, the cruel irony that just like I work on technical skills, I must also actively work on people skills. Sometimes that means not talking about work during the occasional co-worker lunch. Other times it means reading people-oriented books. This latter activity makes me consciously focus on people interactions.

One such book I read was John Maxwells' Winning with People. It was a Christmas present. John has written dozens of books about people, leadership, relationships, and all that. He's got a lot of wisdom. The book is a series of short chapters on various principles like "Never let the situation mean more than the relationship", and "the journey with others is slower than the journey alone." I found it practical, avoiding the common sense clich├ęs like "be nice, work hard, etc..."

I saw a few big take-aways:

  • "The journey with others is slower than the journey alone" (pg. 198)
  • Quoting Andrew Carnegie, "No man becomes rich unless he enriches others." (pg. 230)
  • "If individuals don't possess people skills, they very quickly hit a ceiling in their effectiveness." (pg. 242)
  • "Most of us admire and respect people who sustain solid, long-term relationships." (pg. 259)

The book is also filled with good quotes, like:

  • Quoted T.S. Eliot as saying "Half the harm that is done in this world is due to people who want to feel important." (pg. 11)
  • Quoted someone "the difference between who you are today and who you will be in fie years will be the people you spend time with and the books that you read." (pg. 13)
  • "Actions are remembered long after words are forgotten" (pg. 42)
  • "People who add value to others almost always do so intentionally."
  • "We often expect maturity to come with age, but the truth is, sometimes age comes alone." (pg. 63) - There are young devs who are great, and "experienced" devs who are not.
  • "Ultimately the things that bring fulfillment involve others." -  I would find it more fulfilling to use an old technology with friends, where we actually ship the product, then a new "cool" technology by myself.
  • "The best way to keep from stepping on other people's toes is to put yourself in their shows." (pg. 73) [I see this continually in the classic software rivalries: managers who want to deliver vs. techies who want to do "cool" stuff; application developers vs. QA, application developers vs. IT infrastructure, etc...]
  • "I made a mistake of trying to impress everybody" (pg. 95) - Software engineering is too big, so you can't possibly know it all, so inevitably you'll meet people who know more than you. One of the dumbest thoughts that ever crossed my mind as a younger consultant was "everybody asks me for help, but I don't need to ask anyone else - I must be doing great". Ah, the cluelessness of being young.
  • "If you don't like people or don't believe in them, you won't be able to fake it" (pg. 104). Tim's translation: "People can tell when you think they're a moron."
  • "Caring for people should precede confronting people" (pg. 107)
  • "Quitting is a permanent solution to a temporary problem." (pg 111)
  • "Most of the time when you confront people, they will have an emotional reaction." (pg. 114)
  • "Most people hate confrontation, but they love resolution." (pg. 115)
  • "If you are not honest with yourself, you will not be capable of honest with others." (pg. 126) - Example: If you deceive yourself into thinking the big task will be done in only 4 days, you're going to struggle giving accurate status reports to management.
  • "It is more rewarding to resolve a situation than to dissolve a relationship." (pg. 132)
  • Quoting someone else: "If you make every game a life-and-death proposition... you'll be dead a lot." (pg. 138)
  • Quoting someone else: "A successful man in one who can lay a firm foundation with the bricks others have thrown at him" (pg. 222)
  • "People are an appreciating asset only if we are willing to invest in them." (pg. 233)

See also:

BOOK: Making Things Happen, BOOK: Bringing Out the Best in People

Thursday, January 28, 2010

Four tool approaches to automated web UI tests

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/four_tool_approaches_to_automated_web_ui_tests.htm]

 We all know that in the ideal world, our web apps would have "sufficient" automated tests. But how? I'm not an expert here, but I've come across four general strategies:
DescriptionExamplePROCON
Send web requests, and then parse the corresponding response.MSTest WebTests
  • Handles simple postbacks very well
  • Independent of server technology (you don't care if it's ASPX, JSP, or PHP providing the responses back)
  • Lots of Visual Studio support
  • Dies on Ajax because it can't parse JavaScript
  • Requires a ton of parsing logic. Granted, there are free Html parsers to help with this.
  • Requires the expensive version of Visual Studio for Testers, so not everyone can run on their machines unless management pays $$$ for the licenses.
Directly tap into the ASPX pipeline (I'm no expert here, but to my limited knowledge, it seemed different than merely the request-response model).NUnitAsp (but this was officially ended)
  • Minimizes the parsing
  • Free
  • Still trouble with JavaScript (if memory serves me right).
Recording and playing back the mouse and keyboard movementsDon't know offhand, but I've heard of them with COM+
  • Tests actual UI layout (is the textbox 10 pixels below the button).
  • Very brittle with browsers, especially because browsers can resize
Run the browser in an automated script.WatiN
  • Because it runs the browser itself, it can handle whatever the browser handles, like JavaScript. This is huge in today's Ajax world.
  • Free! This is great when you want the entire team to run it on their local machines.
  • Active community supporting it
  • (I believe, but may be wrong) that because it runs the browser, it's limited to just IE.

 

Personally, I've seen the best luck with WatiN. Especially in the Ajax age, automated tests need to run JavaScript. I also find that to get a team to adopt a new tool, it's invaluable to let them run it themselves (i.e. anyone can download the open-source tool and run it with management paying $$$ for a license), and to provide tutorials (i.e. WatiN has an active community).

 

Sunday, January 24, 2010

Is this code broken?

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/is_this_code_broken.htm]

What constitutes broken code? Everyone agrees that code that crashes in production and threatens to have developers fired is indeed broken. But where's the line? Is the following code broken:

  • The code logs incorrect data in an error log file?
  • The code displays incorrect values in a label (like a mis-formatted date)?
  • If a certain rare case occurs (like a button is pressed at exactly 12:00AM, or an uploaded file size is exactly 1.00 MB), then the code crashes?
  • The code has mis-leading names for variables and methods. For example, it has a method "IsNumber" that checks only for integers, or "IsLetter" that allows for special characters? Say the current program calls the method with correct data so that the app never crashes?

In all these cases, say the application essentially "works" and handles the main use cases.

The problem is maintenance. Maintaining and extending code is an expensive part of the total cost of ownership. You could spend hours tracking down a single erroneous line of code. Code that is low quality (tons of copy & paste, misnamed methods, misleading logic, etc...) is going to be a fortune to maintain. On the other hand, certain functional errors that have zero impact on the business can perhaps be documented as "known-issues" (i.e. the month is formatted in a label with a preceding zero like "03" instead of just "3".

I'd say it comes down to the business, and the code is broken if it costs the business more than it should - whether it be via maintenance costs or functional errors that hinder the end users. Perhaps the question isn't as much "is this code broken", but "how can we maximize the business-value of this code?"

Wednesday, January 20, 2010

Five Ironies of Unit Testing

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/five_ironies_of_unit_testing.htm]

I am a huge advocate of unit testing. After years of writing tests, and encouraging other devs to write tests, I find five common ironies:

  1. The devs who would most benefit from unit tests are the devs who are least likely to write them - and vice versa. The star devs, who would write the code correctly to begin with, are also the ones most open to unit testing. Likewise, the low-quality-code-developers who shun testing are the one's whose code could benefit the most from it.
  2. Writing unit tests actually saves time - not just in integration testing but also in development - because it stubs out the context, allowing you to immediately jump to the area that needs testing instead of spending 5 minutes setting up the scenario.
  3. Developers often punt on unit testing because "my manager doesn't support it", but unit testing is really an encapsulated development detail that doesn't need managerial support (although of course their support is appreciated).
  4. Many devs generate the unit tests after they write the code ("those ivory-tower architects said we needed tests"), but tests are most beneficial before you write the code because they force you to think what the code does, and they make it faster to write the code.
  5. The same teams who don't want to write unit tests are relieved to have such tests on the code they need to maintain.

 

Monday, January 18, 2010

Blogging as a Legacy

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/blogging_as_a_legacy.htm]

I was casually chatting with a dev manager who had worked in the trenches for 25 years. He emphasized how a lot of developers spend their career without leaving a legacy. You work on a dozen systems, for different companies, and a decade later don't have anything external to show for it. Sure, you've got skills, 10-linear feet of obsolete tech books you've read, and the memories. But it's not as tangible as shipping actual products (like the devs who can say "I helped ship AoE2 - that was me!").

This hit home with me as I reach the 5-year mark for my blog. After 5 years of consistent blogging, I've written 430 posts and received hundreds of comments (many of them educating to me). There are a lot of obvious benefits to blogging, but after writing for years, what really sticks out to me is the legacy of blogging. I started blogging at CSC, blogged all through Paylocity, and continue blogging now at CareerEd. Ironically, my blog topics have evolved from hard-core development, to tech lead, to architecture, to more managerial-related tasks.

I can't show people any of the systems I've done (except for the occasional screenshot from a dusty tech doc), but as appropriate, I can share with them the archive of hundreds of blog posts. It helps motivate me to want to write for another 5 years.

Thursday, January 14, 2010

Three basic communication tips

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/three_basic_communication_tips.htm]

I am certainly no communication or "people" expert, which is probably why wiser people in my life have explicitly offered me three good rules for communicating with others. I think these rules apply in the corporate world as well, so it makes a good blog post (because I can't just blog about normal life-issues unless I can somehow apply it to software engineering).

Connect the dots - In software programming, we must explicitly spell every step. Sure you can refactor and abstract things out, or use third-party software to spare you from writing it - but somehow, every step must be flushed out in detail. This is great for a robust program, but it will drive real people insane (i.e. managers, business analysts, customers, and executives who write your paycheck). They'll just think you're being clueless, are inexperienced, or a smart aleck. When dealing with actual people, we need to be able to use our background knowledge of the situation to connect the dots.

Don't wait to be asked - It takes effort to ask for something, and people don't like exerting effort, so anytime you can "just know" and do the right thing (perhaps because you know the bigger picture of what they're trying to do), people are going to appreciate it.

  • For example, say you see a simple bug in the code. It's a safe change and the release isn't for a while. The savvy developer doesn't need to ask their manager "can I fix this bug" - they just do it (and maybe submit a ticket if their company's process requires that). Often just making the fix can be quicker than asking. (Of course common sense applies, don't go "fixing" mission-critical production code that's out of your scope).
  • It seems like only junior resources ask "What can I do to help?"- the senior ones already know.

Of course, it's reasonable to pro-actively notify a manager "I see A, B, and C. I know you're busy, so I'll assume I should start working on 'B' first because of reasons XYZ. Just let me know if you'd like to switch tasks". This lets your manager reply with a 1 word email like "great", and managers like being able to delegate entire tasks with 1-word emails.

"Connecting the dots" and "Don't wait to be asked" are related. Think of this as not needing to be micromanaged.

Translate what people say. There is a world of difference between someone's words and what they actually mean. Whether they've made a simple typo, using poor word choice, or they're struggling to articulate something - it's a big personal win if you can "see the forest through the trees" and know what they mean. You can do this by leveraging context, know where they're trying to go, and having familiarity with what it takes to get there.

  • Example: Missing words - A non-technical manager may say "we need to store this dropdown control in the database". They probably mean "..store the value of this dropdown control..."
  • Example: Wrong words - A non-technical manager says "We need a bigger machine". They probably mean "we need a better-performing machine"

Summary

You might say "but this isn't fair - I was doing my job to the 'T', I was technically correct" Ah, but life is not fair. You can be right, or you can be happy. And (as I find out the hard way) if you want to be happy with other people, you're eventually need to master many things, including these three.

 

Sunday, January 10, 2010

BOOK: Complete MBA for Dummies

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/book_complete_mba_for_dummies.htm]

I'm always been intrigued by the non-coding aspects of a project that are necessary for that project to succeed. Much of this includes people and business skills. I keep hearing of co-workers who take business classes, and it sounds fun, but it takes more time than I have right now (building snow-dinosaurs, sandboxes, and Christmas lights for the kids takes a lot of time). So I settled for the next best thing: reading the Complete MBA for Dummies. I was impressed.

The book is a casual 400-page read, and certainly lives up the the "for dummies" genre. It offers an overview of starting a small business, from the basics of management to HR to accounting to marketing and economics. I liked the practical tone.

While a book like this doesn't fundamentally change one's view of business, it is useful to get one to casually think about business-concepts during the normal work day. For each project, it prompts me to ask questions like:

  • "where does the revenue come from?"
  • "who is paying for this project?"
  • "how will this project help the business?"
  • "can this thing I built actually be marketed?"
  • "who are the customers for this product?"

Continually keeping these types of questions in mind also helps a developer relate to business-sponsors, who are the people that ultimately write the developer's paycheck.

 

Thursday, January 7, 2010

Coding is just the tip of the iceberg

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/coding_is_just_the_tip_of_the_iceberg.htm]

I love coding. The more I do software engineering, the more I realize that coding is just the tip of the iceberg. Consider tasks besides coding that are required for a successful project:

  • Identifying a business problem such that business sponsors are willing to pay for the product
  • Recruit the team to build the project
  • Provide the team the tools to develop the app (hardware & software)
  • Collecting business requirements
  • Coordinating with business partners, such as those providing data that the product will use
  • Designing a functional spec
  • Creating the architectural and technical designs
  • Decide on build vs. acquire (buy, open-source)
  • Outsource part of the project
  • Managing the project
  • Procuring the physical infrastructure that the app is deployed on
  • QA testing the app (functional, integration, user-acceptance, performance, etc...)
  • Deploying the app
  • Write training manuals for the app
  • Training support staff and users
  • Marketing the app such that people actually use it
  • Supporting the app

From start to finish, actually coding for a project may only be 5% - 10% of the total effort. That means that there's a huge portion of the project that is non-coding, and that huge portion can often overcome difficult coding tasks.

For example, say there is a component that is just difficult to program (it's complex, it's big, it occurs outside your expertise, etc...) You could possibly get around coding it yourself by maybe:

  • Buying or open-sourcing it (example: use an open-source tool or class library from CodePlex instead of writing it yourself)
  • Training the internal end users around using that feature ("we know the website has a bug, but just don't click the browser back button")
  • Using project management to get it punted, or out of scope
  • Convincing the business sponsor that the feature is not needed ("we don't need to invest all that time making a dancing paper clip assistant")
  • Better hardware (example, upgrading hardware for better performance)

The stars who keep delivering successful projects are familiar with this, and they are constantly mitigating challenges in one task by giving up something that doesn't matter from another task.

Sometimes you can solve hard coding problems by just sheer skill and coding right through it. But it's good to be aware of other techniques to work around the problem altogether.