Tuesday, March 9, 2010

10 tips to write shorter emails

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

There are some who think that the volume of email you send out directly reflects how much work you've done. So if you cc twice as many people, you've done twice as much work. For the rest of us, reading long emails is a time-consuming nuisance. To avoid being that person who irritates everyone with a daily novel-worth of emails, here's some tips to write shorter emails:
  1. The shortest email is the one you never even had to write- perhaps the issue can be resolved with a quick IM or water-cooler conversation.
  2. Refer to external resources with the URL instead of pasting large chunks into your email (like "see the wiki page at...". Although sometimes it may be more convenient for the recipients to just see the content of the URL that you're referring to (such as if they don't have access to the target URL).
  3. Make good use of "To" vs. "CC". Some people even filter their emails to redirect CC.
  4. If replying to a long email thread, consider deleting the older history that no longer matters.
  5. If your email is longer, consider splitting it into a clearly-marked "Summary" (2 lines), and "Details". Make it easy for a busy person to get the main point of the email in less than 30 seconds.
  6. "A picture is worth a thousand words", therefore a picture (like a diagram or graph) can often convey a concept much quicker than verbose text paragraphs. Consider also using outlines and tables for the same reason.
  7. Differentiate between informal and formal emails. Informal emails are usually quick questions or responses to friendly co-workers about a current issue for which there isn't a big consequence (example: "Should the confirmation page have a link back to the home page?"). You can make them shorter because you don't need to re-explain the whole problem or define every term. Formal emails usually have big consequences, are usually followed up with a live meeting or phone call to confirm, and have the details in an attachment. (Example: "Is a rate of $120 per contractor hour acceptable?") This usually requires them to be longer such that you catch all the influential and controversial ideas to ensure that everyone is on the same page.
  8. Consider tailoring your email to your target reader and their history of the topic at hand. For example, phrases like "Per our discussion yesterday..." can save you from re-describing a problem. Don't assume that because email can be forwarded to everyone, you need to write it to the "lowest common denominator".
  9. Consider batching multiple questions into one email. Yes, that individual email may be longer, but as a group, the emails will be shorter. It also saves you from having to re-explain the context in each email.
  10. Use good writing skills to condense your writing.

Sunday, March 7, 2010

Process as Infrastructure Enhancements

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

Most devs I meet hate process, almost like it's a stupidity-tax from some ivory-tower folk (who themselves don't actually need to use the process that they're imposing on others). These devs just want to get the app done, and they think that the process gets in their way with tedious constraints that add no value. I recall projects with "process" like forcing devs to go and update all the internal variable names to be compliant with some new coding standard, or not allowing devs to have admin rights to their own machines until three levels of paperwork is approved (good luck being a dev using a Windows OS if you're not an admin), or requiring that developers test the app by taking success screen shots of every single step - and then printing out that 600 page doc and getting it signed by QA.

That sort of stuff bothers me too, but I'm still a big fan of good process. What I realize is that I essentially view "process" as "developer infrastructure enhancements". I think of process as helpful things like automation, unit tests, code generation, proper tools, CI builds, checkout and install scripts, etc...  Devs just want to get the job done, and good process assists them in doing that, it doesn't burden them with ivory-tower taxes. If your process code-generates the data access layer, then the dev need not do all that manual ADO.Net plumbing code, and hence the dev gets the job done faster.

Sure, it's semantics - "process" vs. "infrastructure enhancements", but semantics are important because it affects how a thought is communicated to other people, and people are important.

Tuesday, March 2, 2010

Visual Studio 2008 hanging

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

There's a lot of reasons that Visual Studio hangs. It was hanging for me the other day when I tried to open, and I had a clean checkout. One solution that solved my current problem (thanks to a co-worker):

  • Close VS, delete the *.suo file, and try to re-open. I'm sure there's a reason why,

2 seconds later, VS was up and running.

Tuesday, February 23, 2010

Advice to a college graduate seeking an IT job

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

A lot of eager students will be graduating with CS degrees soon. Realistically, with almost 10% unemployment, out-sourcing, and a rough economy, it can be hard for a college-grad to find a tech job.

Here's a brain-dump:

  1. Condition your mind
    1. Until you are employed, your job is to find a job. Prepare to spend at least 4 (maybe 8!) hours a day actively pursuing job opportunities.
    2. Furthermore, you're not seeking to "get a job", you're looking to "add value" to a company by solving problems in a technical field that you're passionate about.
  2. Prepare
    1. Set up a linked-in account. This is an effective and professional way to keep track of people you meet.
    2. Make the equivalent of a business card that you can hand out as you meet people. Even a card saying something like "Joey Finklestein, my-email, 'Technology Specialist'" is good. The goal is to have your contact info easily available.
    3. Get your resume ready. make sure it downgrades to plain text in case you need to dump it into some online text area. I personally don't think resumes are the biggest deal. Yes, everything counts. But if you're blindly submitting your resume online, you're one among thousands, and it probably won't matter (sorry). If you meet someone in person, the impression you make will probably dwarf any wordsmith-ing on your resume. If you've actually got even a phone screen, the resume has already been sufficient.
  3. Network. Meet people.
    1. Especially if you live in a larger city (like Chicago), prepare to go to a user group meeting at least once a week. For example, Chicago has dozens of user groups (LCNUG, ALT.Net, CNUG, SQL groups, IT, SharePoint, TFS, Design, etc...) Just google it, there's probably a group. Even if the group isn't exactly on target, go to the closet-related thing. Try to meet at least 3 people. Talk to them, ask them what they do, get their business card, give them your business card. Often user groups have recruiters who are trying to fill positions - talk to these people. Even if their position isn't an exact match, they may know of another position, they may have a position that frees up later, or they may just offer you good advice. Plant seeds.
    2. Keep in touch with your graduating class. Maybe they have leads.
    3. Go to job fairs - most community colleges offer these on a regular basis.
  4. Start a corporate and professional online presence.
    1. Contribute to online discussion boards (like http://stackoverflow.com/)
    2. Contribute to an open-source project (check out CodePlex.com)
    3. Consider writing some articles (either start your own blog, or contribute on a free site like CodeProject. Even if you're just writing simple articles like "Joey's C# 101 tutorials", it's still beneficial. It tells employers that (1) you're motivated, (2) you can write (non-tech skills are a great asset), (3) you're pro-active enough to write. It will also make you more confident after you've explained things in an article. Try to write at least two short blogs, or one longer article, every week. Even if you're "not the writing type", employers want people who can write, and having a repository of your articles shows them, as opposed to summary statements at the top of a resume that say "has good communication skills". You can then also list your blog on your resume.
  5. Continual Education - industry is a different beast than academia. The CS degree is great, but that's the beginning, not the end.
    1. Prepare to spend at least an 1 hour a day reading blogs that are relevant to the job you seek. Find who the top bloggers are in your field of interest, and read them. Probably get an RssReader.
    2. Read the job postings on online sites like Monster, Dice, HotJobs, etc.... You want to make sure you know all the buzzwords, and see what employers are asking for.
    3. Do charity projects. Many charity groups could really use the free help. Offer to do a tech-related project (assist with their website, do a data migration, write a tool to help them do some task). It doesn't pay cash, but it does pay in experience and relationships.
  6. About applying...
    1. Ideally you want to meet someone in person (like at a user group). Next best thing is to meet someone in the company who can provide a referral.
    2. If you do apply online (with no personal reference), don't put all your eggs in one basket - apply to several companies. But don't spam Monster. Perhaps submit to a few companies each day, but not more than 10 companies at once. If you don't hear back from a company within 5 days, move on. Many companies send out an automated "we received your resume note", and then only personally follow-up if they're interested.

Tuesday, February 16, 2010

Where 100% Code Coverage is not sufficient

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

Sometimes I wish development were as easy as telling junior guys to "follow this one metric", and then they write perfect code. However, it's not. One example is how to know when you've written enough unit tests. Code Coverage is the obvious metric, and therefore "100% Code Coverage" sounds great. But there are plenty of cases where even 100% coverage doesn't do the job.

Case 1: Regular expressions

Take an email validator, something like so:

public static bool IsEmail(string s)
{
    return System.Text.RegularExpressions.Regex.IsMatch(s,
        @"\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b");
}

A single test would give 100% coverage, but obviously there's a lot of other paths to check. Ironically, because regular expressions are often used to validate input data, and it's an in-memory operation (no databases or external files to hit), it's a prime candidate for lots of unit tests to catch all the boundary conditions - as opposed to just the 1 test needed to reach 100% coverage.

Case 2: Single-line expressions

Similar to the previous case, merely calling this method with one set of inputs (say the "less-than" path, such as i1=5 and i2=10), will get 100% coverage. But that wouldn't test the "greater-than" and "equal to" conditions.

public static bool IsGreater(int i1, int i2)
{
    return (i1 > i2);
}

Case 3: Missing Asserts (bad logic)

Even with 100% coverage, it doesn't guarantee that the method logic is correct.

For example, say you've got a CSV-parsing method:

public static string[] ParseCsvString(string strLine)
{
    string[] astr = strLine.Split(',');
    return astr;
}
 

That is tested by:

[TestMethod]
public void ParseCsvString()
{
    string[] astr = Foo.ParseCsvString("a, b, c");
}

This will give 100% coverage. However, there are no asserts, so it's really just showing that the method didn't throw an exception. Even if a developer adds an assert, they need to make sure it's asserting the right thing. Say, adding an assert that the returned array is not null, or has a length of 3, misses the logic that trims the white space after each comma. For example, we want elements like "b" (no whitespace), not " b". In other words, we'd want the ParseCsvString method to loop through each item and Trim() it.

Case 4: Mocking giving a false sense of security

Mocking Frameworks, like TypeMock, are very powerful tools for increasing unit test coverage. These tools allow you to "mock out" a method call within code, such as that database or logging call that would be hard to run in a test method.

While this is great for testing legacy code, it can easily be abused. If every line is mocked out, there's nothing real that's left to test. So while it does get high coverage, if used incorrectly, it becomes meaningless.

 

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).