Saturday, November 26, 2011

The Cloud Experience

We are entering the age of ubiquitous computing, and it is not a computer on every desktop.  It is a myriad of devices.  And the most common is more likely to be in your pocket than on your desk.  And we expect these devices to serve us fluidly.

What emerges is The Cloud Experience.  It is the idea that I can work effectively regardless of time, place or device.

We often think of this experience with email, or social networking like GMail and Facebook.  But, we will come to expect this experience of all of our data and software.

I expect that as I write this blog post, I can close my laptop. Then, go to the park, pull out my phone, and pick up editing where I left off.  Then, go to a friend's house, log on with his computer and publish the post.

There are two basic requirements:

  • The state of my work is saved "in the cloud"
  • An appropriate user interface is available for the device I am using

Next generation software developers should embrace this experience.

Saturday, August 13, 2011

For Speed and Certainty TDD Wins


As software grows, Test Driven Development beats Legacy Development in terms of speed and certainty.

With Legacy Development (manual testing)

1. I get some new requirements. 
2. I modify the application code. 
3. I step through the code in my head.
4. I run the application in a few scenarios.
Repeat steps 2 - 3 or 4 until everything works as expected
Repeat steps 1 - 4 until all requirements are met

With Testing Legacy Code (write tests after application code)

1. I get some new requirements. 
2. I modify the application code. 
3. I modify the test code.
4. I run the tests.
Repeat steps 2 - 4 until all tests pass
Repeat steps 1 - 4 until all requirements met

With Test Driven Development (write test(s) before application code)

1. I get a new requirement.
2. I encode the requirement as a test.
3. I modify the application code.
4. I run the tests.
Repeat steps 2 - 4 until all tests pass
Repeat steps 1 - 4 until all requirements encoded

Compare the three approaches in terms of speed and certainty.

Speed

All three approaches get slower over time.  The software grows and verifying all requirements takes more time.  

Doing this manually is clearly slowest. (Computers run code faster than I do.) But writing tests takes time too.  The question is which takes more time? Writing tests? Or manual testing?

The answer is that the cost of writing tests stays roughly constant.  However, the cost of manual testing goes up with the amount of code.

The question becomes: when does the time taken to manually verify code exceed the time necessary to write unit tests which can automatically verify the code?  After a week?  A month?  After the second developer comes on?  For applications of significant size, TDD wins.  

Certainty

The most uncertainty is with manual testing and the least is with test driven development.  

In manual testing (legacy development), the programmer elects to run some test scenarios mentally, and some manually. It is based on judgment calls, and is nebulous.

With unit testing of existing code, the parity between tests and implementation is difficult to verify. It is mentally taxing to determine which tests to write after the implementation is done. Is all code covered?  Even with 100% code coverage, not all requirements may be covered.

With test driven development there is less ambiguity.  A requirement is encoded as a test. Then, just enough implementation code is written to meet the requirement.  Parity.  Balance.  Certainty.  

Saturday, July 23, 2011

AppHarbor vs. Heroku

I am a simple caveman web app developer.  Your scalable racks frighten and confuse me.  But, there is one thing I do know.  I have code.  I have data.  And I must put that code and data online as quickly as possible.

Both AppHarbor and Heroku provide deployment using Git.  This is elegant.  I expect to see more services offering both continuous integration and live deployment via source control.

AppHarbor is for ASP.NET code.  Heroku is for Ruby on Rails.

For now, Heroku and Rails lead the way.  But, AppHarbor and .NET are catching up quickly.

The code.
Round 1.
Fight!

AppHarbor provides some continuous integration features.  It runs your unit tests prior to deployment.  If a test fails, the software does not get deployed.  It also provides a list of recent builds, which you may click to deploy.  Heroku does not provide these features.

What about debugging your live code?  Heroku wins this one.  Heroku automatically logs exceptions.  It provides a couple different logging options.  AppHarbor provides a page for "Errors", but throw as I might, I've never seen it say anything but "No errors to display."  They currently recommend you roll your own error logging.

Heroku also recently rolled out a feature to help with managing Staging and Production environments.  This is a highly requested feature on AppHarbor, so I expect we will see it soon there.

Finally, what about writing code?  This goes to AppHarbor (well, actually to Microsoft).  Visual Studio simply provides more assistance to the developer.  With Ruby on Rails you will be installing more tools and spending more time at the console.  And Code Completion?  Visual Studio beats the Ruby development environments.  (Can a dynamically typed language can ever offer as much code completion as a statically typed language?)

AppHarbor wins (but not without taking a few licks).

The data.
Round 2.
Fight!

One of the corner stones of Rails is "Convention over Configuration", and this is most evident with its ActiveRecord based ORM.

Using .NET on the other hand...  Well...  There are many options for data access.  And they certainly use conventions.  But, none is without some configuration.  And AppHarbor offers no clear recommendation.  This is a brick wall to beginner adopters.

And schema migrations?  Rails wins again.  Heroku handles migrations the same way they are handled locally: by calling a rake command.  The code and schema stay naturally in sync as the migrations are stored in text files alongside the source.

AppHarbor is very different.  Databases are created manually via the web interface.  Databases cannot be added or dropped at runtime from the application.

Furthermore, Microsoft's Entity Framework is not there yet either.  Using the EF Code First approach (which seems to be the path of least resistance) the only "migration" supported is dropping the database, and creating an entirely new one.  Clearly this nuclear option won't work with AppHarbor's policy, or if you want to keep your data.  (There is a work-around that only drops the tables.  I ended up creating my tables manually with a sql script exported from my local database.)

Another database bootstrapping problem that new MVC3 projects will run into is the absence of Application Services tables.  These services can be removed from a new MVC project, or you can populate the remote database as described in this thread.

Heroku wins.  Flawless victory.

Round 3?
The conclusion is that Heroku is faster overall, particularly for database deployment.  But, AppHarbor, Microsoft, and open-source .NET developers are closing the gap.

Saturday, July 16, 2011

Git on Google Code vs GitHub

Google Code now supports Git as a repository option.  Here are my first impressions of pushing a git repository to Google Code compared to GitHub:

Cons

  • Project name has to be globally unique and all lowercase.
    On GitHub my projects are under my user directory.  So, I don't have to compete for a unique project name.  And I can used mixed-case, which is normal for most languages.
  • No automatic readme.  GitHub has a convention where a readme file is automatically shown on your project home page.  And it is prettified if it uses markdown syntax.
  • No instructions for pushing your existing repo.

    After you create your project you are not presented with instructions for pushing your code via git.  In fact, you aren't presented with many instructions at all.  If you navigate to the source page you will see instructions for cloning your new repo, but no instructions for a pre-existing repo..

    As a side note, you can push an existing repo to your Google Code project.  Follow similar steps as you would on GitHub:
    • Go to the source tab to find your source URL and a link to a generated password
    • cd <existing git repo>
    • git remote add origin <url>
    • Paste your password when prompted
    • git push -u origin master


Pros

  • Pick your license.  There doesn't seem to be a conventional way to specify your open source license on GitHub.
  • Even though Google Code doesn't have a convention for using your readme file, you can use wiki syntax to update your project description.  It does not track changes.
  • There is better integration between the project wiki and the project home page.
  • Integration with other Google services like Analytics and +1
  • You can pick a project logo...
For the time being, I'll be sticking with GitHub.  But, I'm glad to see some competition.

Wednesday, June 29, 2011

Announcing C# TDD Course in Houston

UPDATE: Rescheduled to August 19

I'm offering a one-day pilot course on Test Driven Development and Design in C# on Friday, July 29 Aug 19, 2011 in Houston, Texas.  The cost is $128 for the day (9 - 5).  The class will be limited to 15 students.  The location will be announced.  It is likely to be in the Westchase area.

The class focuses on unit testing and test first design.  We will discuss foundational principles and go through hands-on labs.  We will discuss your concerns about TDD and how to realize its benefits.

Introduction to TDD with C#
  • Benefits and Goals
  • Concerns and Fears
  • Principles and Practices
  • Accelerators (tailored to Microsoft Visual Studio)
About the Instructor
I've gone from unit testing skeptic to TDD evangelist.  I love coding.  I love sharing what makes coding more rewarding!  I've been developing using TDD with C# for three years.  I've been programming since before I could drive...

Get in Touch
If you have questions about the course feel free to post a comment below.  Or contact me on Twitter or LinkedIn.  Registration for the class is handled through PayPal by clicking the button below.


Recommendations
You will enjoy this class if you are a C# developer who wants to:
  • Regain the joy of programming
  • Feel relaxed and focused, even in the face of changing requirements
  • Avoid maintaining complex Rube Goldberg systems
  • Be more confident in your code
Students should bring their own machine with Visual Studio.  The classroom will have WiFi and power at each station.  Lunch will not be provided.

Why Hulu's Device Segmentation is Backwards

Open up Hulu on your iPhone and you don't watch video.  Instead, you see a message:
To watch videos on this iPhone, please subscribe to Hulu Plus.
They are segmenting their market by device.  But, they've got their market segmentation backwards.

What drives companies to try market segmentation is the idea that you can maximize profit by charging more to customers who are willing to pay more.  Joel Spolsky explained it well in his article "Camels and Rubber Duckies".

Hulu has it backwards because they are trying to maximize profit on small, wireless handheld devices, rather than on big-screen home theaters.  Phones are becoming the common way to view online content.  Phones are the horizontal.  Big screens are the vertical.

They also have it backwards because people will pay more when they can combine viewing with eating, drinking and socializing.  (Why do people still go to the movies if everyone complains about how expensive they are?)

Ever try to eat dinner while watching a video on your iPhone?  Ever try to share that show with the person sitting next to you?  Suddenly the 1950's experience of having dinner and enjoying a show with your family becomes a feature worth paying for (again).  I suspect the big networks (the ones behind Hulu) take this TV experience for granted.

Eventually Hulu will figure this out and try to flip it.  But, they won't be able to without losing customers.  People are sensitive to artificial segmentation.  People will realize that this segmentation is contrived and will entertain getting their entertainment elsewhere.

Sunday, June 26, 2011

Quick Example using TestDrivenDesign

using TestDrivenDesign;

[TestClass]
public class QuickExampleTest : TestBase<QuickExample>
{
    [TestMethod]
    public void ShouldSayHelloMultipleTimes()
    {
        // Arrange
        Subject.Count = 3;      
        // TestBase<T> provides us with a default constructed
        // QuickExample (think: "Test Subject")
        var path = TextPath();
        // Gives us a path in the test run directory like: 
        // QuickExampleTest.ShouldSayHelloMultipleTimes.txt

        // Act
        Subject.SayHello(path);

        // Assert
        TestContext.AddResultFile(path);
        // TestBase provides the TestContext property. 
        // AddResultFile adds a hyperlink to our file on the
        // test result page
        TextFileAssert.Contains(path, "hello hello hello");
        // TextFileAssert helps test writing text files.
        // Yes, there is a BinaryFileAssert too!
    }
}

Let's take a moment to review the code that you aren't writing:
  • No TestContext boilerplate
  • No initialization of your test subject. Every test method gets a newly constructed subject, which you are free to overwrite
  • No coming up with your own unique file name and combining it with the deployment directory
  • No reading of a text file into a string or collection before you can do an assert
This was also posted on the TestDrivenDesign wiki.  Get the code at https://github.com/jfoshee/TestDrivenDesign

Friday, June 24, 2011

I Picked the MIT License for TestDrivenDesign

Today I elected to release TestDrivenDesign under the MIT License.

Why the MIT License?

  • I want to make other developers smile
  • I believe in an Abundance Mentality

As a developer, when I use open source code, the MIT License always makes me smile. So, hopefully this will make other developers happy.

A scarcity mentality would have me keep my code hidden from the world, and retain as many rights as possible.  But, I believe in fostering an Abundance Mentality.  I believe that "my cup runneth over" is not just an observation; it is a mindset.

Wednesday, June 22, 2011

Using TestDrivenDesign

Announcing the TestDrivenDesign C# library on Github: http://github.com/jfoshee/TestDrivenDesign

Over the past few years I have become an advocate of Test Driven Development and Test Driven Design (TDD).

I've done most of my unit testing in C# using the Visual Studio unit testing framework.  So, I've started to factor out common patterns from my tests into this library.

The name of this library may seem a bit presumptuous.  But, I thought it was appropriate since I want to see more code:
using TestDrivenDesign;

Friday, June 3, 2011

Two-person Canoeing takes Teamwork

or "How Ears Trump Oars"

Last weekend I went canoeing with several friends.  Alejandra and I teamed up in one canoe.  We took it as an opportunity to work on our own teamwork.  I am proud to say that we did well, but it was a challenge!

When you put two people in one canoe with one destination, you have created an effective illustration of Interdependence.  (I am using the term as Covey does in The 7 Habits of Highly Effective People, which I reference often.)

The two people have to work as a team to reach their goal.  But, what does it mean to work as a team?

Each Independent
Often people think of teamwork as breaking a big task into several non-overlapping (independent) tasks.  This is the simplest functioning form of cooperation. It is what we learn to do on school projects.  "I'll write the report and you find the pictures and build the poster board."

In a canoe it is almost impossible to create non-overlapping roles.  As soon as you put an oar in the water you are affecting the direction of the boat.  That's a good thing.

Most professionals have achieved some basic independence.  And most professionals are comfortable dividing work this way: where there is as little coordination as possible.  Sometimes it goes to the point of silly imbalance... "I'll watch for sharks while you paddle."

This independence can render the team totally ineffective.  Try paddling upstream.  If you are taking turns paddling, for example, you are going to move slowly (if at all) and both be exhausted.

Finally, in the worst case, both people work against each other.  "I'm just going to paddle my hardest to get this thing moving regardless of what the other guy is doing."  Believe it or not, it takes some effort to flip a canoe.  But two inconsiderate teammates can certainly make it happen.

Compromise
With some basic instructions most people will divide the work this way: the person in back steers the boat, and the person in front makes it go forward.  This is an effective system for two people to navigate a canoe downstream.  But, it is not optimal.

Here's why: You can't paddle on one side of the boat without affecting it's direction.

So, if the person in front is only trying to provide power without concern for direction, the person in back is going to have to compensate.  With every stroke that the front person makes, the person in back is going to have to apply a counter-stroke to keep the boat on course.

The person in back is using their energy to undo part of what the person in front did.  Not optimal.

The boat zigs and zags...  The person in back is frustrated because someone else is making their job harder.  The person in front is frustrated seeing that they are paddling towards the shore and not downstream.  Energy is wasted and frustration builds.

Coordination and Synergy
When people become frustrated with each other the first thing to go is communication.  But communication is absolutely necessary to coordinate.  And coordination is necessary for synergy (and to paddle a canoe efficiently).

When the two shipmates are communicating, they can issue requests to each other.
"I need you to switch sides so we can make this turn."
"Shallow water 10 yards ahead!"
"Should we go to the left or right of this branch?"
"Give me two good strokes!  All your might!  We can get over this log!"
"Great job!  Let's take a break."

It's good to be comfortable to issue requests to each other.  But it is more important to be listening and responding to the requests.

Now both people can be paddling.  The rear person may be more responsible for steering and the front person more responsible for power, but they recognize the overlap.  They embrace the overlap.  They are working together.

Now they can make sharp turns.  Now they can go upstream.  And now they can overcome obstacles.

Advice
1. Use your oar
Remember that you have no one to blame but yourself.  As Dan pointed out, "You each have an oar."

2. Use your ears
When we started our trip, some of our friends were making their way downstream leaving us behind.  This gave us a sense of urgency!  "We better get moving.  They are getting far ahead."  But this sense of urgency is dangerous.  It gives the illusion that starting to paddle is more important than working out the skills that will be necessary for the trip.  Don't give in to imagined crises.

Before you start trying to make progress down river, take the time to discuss roles and goals.  Throughout the trip make special effort to listen to your teammate.

Wednesday, May 25, 2011

Hosting a simple website on Amazon S3

I assume you have already signed up for Amazon Web Services S3.  I also assume you have a domain registrar. For this example I'll be using GoDaddy, but there are other popular registrars.
  1. Register your domain
    1. Do this first if you haven't already to make sure you get the domain name you want.
    2. For these instructions I'll use example.com as the example domain.
  2. Create Bucket named for your domain
    1. Sign into AWS Management Console for S3
    2. Under Buckets, click Create Bucket
    3. Name the bucket: www.example.comThis should be the full host plus domain name
    4. Click Create
  3. Upload files (e.g. index.html)
    1. Select www.example.com from the list of buckets on the left
    2. Click Upload
    3. If prompted by your browser, enable Java for the uploader to work.  
    4. Click Enable Enhanced Uploader
      (I could not get the Add Files button to work in Chrome w/out the enhanced uploader)
    5. Click Add Items
    6. Browse and select files to upload for your website.  I will assume you at least have an index.html file.
      You can use Ctrl+Click to select multiple files.  Then click Open.
    7. Click Start Upload
  4. Make bucket a website
    1. Right click on www.example.com in the Buckets list
    2. Select Properties
    3. In the lower pane, select the Website tab
    4. Check Enabled
    5. Enter index.html for Index Document.
    6. Click Save
    7. Click the Endpoint link to verify it is online.
    8. Copy the endpoint link to your clipboard.  Typically something like: http://www.example.com.s3-website-us-east-1.amazonaws.com/
  5. Create a CName record for www.example.com
    1. Log into My Account on GoDaddy
    2. Go to the DNS Manager
    3. Click Edit Zones beneath example.com
    4. In the CNAME (Alias) table:
    5. Click the www row (usually the last row)
    6. In the second column (Points to) paste the endpoint link, removing the http:// and the trailing slash: www.example.com.s3-website-us-east-1.amazonaws.com
    7. Click outside the row to finish editing
    8. Click Save Zone File
    9. Click OK if prompted
    10. Periodically try opening www.example.com in a new web browser, or just wait for an email from GoDaddy letting you know your changes were effected.
    11. You may have to wait for these changes to take effect to move onto the next step.  
  6. Redirect root (example.com)
    1. Go to the Domain Manager
    2. Check the box by EXAMPLE.COM
    3. Click Forward, Forward Domain in the toolbar above the list
    4. Enter www.example.com in the box after http://
    5. Click OK
    6. Periodically try opening example.com in a new web browser, or just wait for an email from GoDaddy letting you know your changes were effected.
  7. Newly uploaded files need to be made public
    1. After you update or upload new files to S3:
    2. Right click on the file and select Make Public
    3. You can use Ctrl or Shift for multiple select

Monday, May 23, 2011

Games I Played in Week Zero

I spent a couple hours playing video games last week. (See the chart in my previous post.)

The pink wedge is GTA4: The Lost and Damned.  There aren't many games that I play all the way through, but GTA4 is one of them.  I particularly enjoy dialing up FLY-555-0100 on the in-game cell phone to spawn an attack helicopter...

The lime green wedge is Assassin's Creed II.  I've only started to play this, but it seems pretty fun.  It includes an easy-to-use free-running mechanic.  If you like free-running games, this one is worth a try.

It also occurred to me that there is better acting in these video games than in some movies...

Week Zero Report

My first week of self-employment is behind me.  I tracked 23 hours out of the last week using toggl.

From the data, my priorities were:
  1. Untracked (eating, sleeping, socializing, leisure, miscellaneous)
  2. My first web app (codenamed: Project Zero)
  3. Health (walking and physician visits)
  4. Miscellaneous
  5. Blog
  6. Playing video games


The largest share of tracked time, at 6.5 hours, went towards my first project.  I am not sure if that is good or bad for a first week on the job.  Either way it should improve.

The second largest share went to my health.  I'm happy about that.  One of my primary goals for being self-employed is living a more healthy life.

The third largest share of time went to...  miscellaneous.  That's right, I've only been in business one week, and the long tail of costs is already apparent.

Moving forward I'd like to improve the amount of time that I tracked, and correspondingly devote more time to production.

If you are curious what games I played read on in my next blog post...  

Wednesday, May 18, 2011

Why I'm Advertising

I am going to be placing advertisements on my blog as one possible revenue stream.

Why would I do this?

  • I believe what I have to say will be valuable to some people
  • I believe I can make a little income this way
  • This gives me some incentive to write many high quality articles
  • I want others to enjoy products that I've enjoyed
  • I want products that I've enjoyed to do well
  • I've never tried it before
  • If Oprah can have some favorite things, so can I
In my life, I have finished a season of reaping and enter a season of sowing.  That is, I have been enjoying good paying jobs since graduating from college.  And, I've spent some of that good money on things I've enjoyed.  I spent 8 years in college sowing, and 7 years afterwards harvesting.  

Now, as I start my own company, I begin a new season.  Now I will be focusing my time and money primarily on planting seeds for future harvesting.  Learning from this highly applicable analogy, I ask, "Does a farmer spend the whole season planting one perfect seed, or does a farmer diligently plant many seeds?"  Clearly, most successful farmers plant many seeds.  Thus, this blog is just one seed for me.  Perhaps it will bear no fruit at all.  But it will be one seed among many.

    Monday, May 16, 2011

    A New Company

    I started my new company today.

    I enjoyed some of the perks of working this way:

    • Took a morning walk to Starbucks
    • Read the morning news via Twitter
    • Edited a video of my morning walk while laying in my front yard
    • Fixed lunch on a gas range in my own kitchen
    • Used my own bathroom (I hate to even mention this perk, but it matters because corporate bathrooms suck.)
    • Worked standing up
    Bootstrap accomplishments today:
    • Set up new checking account for the company (Chase gave me a coupon for $125 for opening a checking account.  That's more then the $50 coupon I have from Wells Fargo.)  I seed funded the company with $125 myself.  So, that's $250 of capital.
    • Set up time tracking with toggl
    • I produced something (a video of my morning)
    • Set up this blog
    • Started documenting the principles/practices I would like to build this company upon
    Conspicuously missing from my day is any programming.  My goal is to be productive every day.  But, that won't always mean coding.  That said, I can't lay groundwork forever.  

    I'm still thinking of what will be a good first project.  Here are my criteria:
    • Adds value to my life (Being my own first customer is a perfect example of bootstrapping)
    • Is a web application (either client or server side)
    • Has extremely tight scope (can be finished in a few days)