Thursday, August 29, 2013

Testing is Fun

When I started programming, testing was the thing you did after you finished your first draft of a program.  If you've built a website, you may test that it displays the page as you designed it.  If you've built a calculator, you test that adding positive numbers, negative numbers and fractions all work right.  After testing, you'd find some bugs, fix them and say "Oh well, I guess it's time to ship".

Better late than never, I finally hopped aboard the test driven development band wagon.  Armed with Google Test, I'm beginning to make testing part of the early stages of my development process.  There are probably lists that detail all the benefits to test driven development, and you can and should search for them on your own.  But some benefits that I've personally experienced and felt are:

  1. Thinking about testing makes me write better code.  If you want to write unit tests, you need to separate your program into distinct modular components, so you can test one part at a time.  Of course, writing small byte-size units of code is generally a good programming practice anyway - so that's one win-win. 
  2. Testing gives you confidence.  All programs have some bugs, but testing helps you out in a few ways. 
    1. Before you check in code, testing might help you catch a bug.  So, buggy code doesn't enter your repository.  Nobody but you knows that you're a sloppy programmer!
    2. After your code has rolled out to the world, your test might find a bug before any user's notice it.  Although not ideal, maybe you can roll back changes or submit a fix before any clients begin complaining.  Only your coworkers know you made a mistake!
    3. One of your clients spots a bug and you get called up to fix it.  Testing will help you isolate the problem.  You know what tests have been written and what edge cases haven't thoroughly been tested.  Hopefully your tests help you fix the problem faster.  So, your clients know that you had bugs, but they marvel at your customer service.  
Now that I've experienced some of the benefits of testing, I can't imagine writing code without them.   

Tuesday, August 27, 2013

Pocket > Google Reader

A few months ago Google Reader was retired.  I quickly passed through the 5 stages of grief, and I knew I'd find something that would fill the void.

I started with Feedly.  This app looks much nicer than the old Google Reader app.  However, I found it hard to use.  It was just a bit too slick, with too many animations, and too many views.  It's not a knock on Feedly.  I suppose there's someone that likes all of the eye candy, but it wasn't for me.  I eventually found and settled on this dirt simple Rss reader - Sparse Rss.  

Sparse Rss has been serving me well, but in the midst of transitioning away from Google Reader, I started reading more articles that were brought to my attention via Twitter, Google Plus and even email.  I realized that I needed a place to store these articles that came at me from multiple sources.  The answer is Pocket (aka Read It Later).  I mainly use the Android App, but I've also used the Chrome App.  

Pocket looks great, yet is super simple to use.  It automagically decides on the best view for articles so that they are very easy to read.  It's hard to explain.  Somehow, the articles look great in Pocket.  It is as if they optimized the UI to make it best for someone who wants to read.  Perfect.

Even better, I found out that they have a developer API.  There are already a number of existing applications that use RSS to add articles to Pocket.  I will try them out and see if any of them improve my Pocket experience.  But even if I can't find an app that I like, I can't complain because the option is always there to write one myself.  Thus, the onus is on me, which is great.

Update: I usually use pocket on my phone, but today I decided to read some articles over a web browser.  They have this feature, where if you press "/", a quick screen guide for keyboard shortcuts is shown.  The guide itself looks great, and it is incredibly useful.  I already started using keyboard shortcuts (mostly j and k to navigate through a list).  This application always impresses me.

Monday, August 26, 2013

Testing sql queries

I was working on an Android application, and one of my queries wasn't returning what I expected it to.  

To test my query, I decided to just run sqlite on my computer, which is pretty simple.  Here are the steps:
  1. Download sqlite from http://www.sqlite.org/ .
  2. Unzip the file into some folder and then you can start a database called test1 with a command like this:
    ~/bin/sqlite3 test1.db
  3. Create a table and insert some data.
    create table phrase_table (words char(50));
    insert into phrase_table (words) values ('hello');
  4. Run queries like:
    select * from phrase_table;

While that was pretty simple, another tool to quickly test queries is http://sqlfiddle.com/ .  This is a web tool where you can set up a database table and then test queries.  For simple cases where you'd like to share your queries, this is a fantastic tool.

Monday, August 12, 2013

Simple C++ program with Google test

I have little to no experience with unit testing.  I want to change that.

In principle, unit testing sounds simple.  Unit tests are used to isolate and validate small parts of a program are working.  In practice, I don't really know how it's done.

As a first attempt, I tried to build a simple program with tests using google test, https://code.google.com/p/googletest/.  After downloading and unzipping the library, I moved it into a folder -- SomeDirectory/libs/gtest-1.6.0.  I then copied these files into a separate directory.
  • Makefile -- this is used by make to build both the test program and my program.
  • sample1.h, sample1.cc -- These define some functions that are linked into the test program and into my program.
  • sample_unittest.cc -- This defines test macros that are run in the test program.
If you put these files into a directory, you are almost ready to run the test.  You will have to update the paths in the Makefile.
  • GTEST_DIR = SomeDirectory/libs/gtest-1.6.0
  • USER_DIR = ./ 
You can run then run "make" followed by "sample1_unittest" and you should see some successful test output.

I wanted to add a real program with this test suite, so I wrote this:
To build the program I updated the Makefile to build "my_program" like this:
TESTS = sample1_unittest my_program
and then I added this to the end of the Makefile:
my_program : sample1.o main.o 
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

After running make, I had two programs.  "sample1_unittest" was the original test program and "my_program" was the 'real' program that I was testing.

Sunday, August 11, 2013

Gist - a great way to share and view code

I often want to embed code snippets into my blog posts. I am testing a method with this post that uses gist.github.com. The idea is that you put your code into some repository and then create a reference to it from wherever you want to use that code.  The code in the post will auto-magically have nice syntax highlighting, be easy to copy, and modifications can be made independent of the blog post.

It took me about a minute to create this gist: https://gist.github.com/dhan12/6206272.
The gist page gave me this one liner to add to my blog post:
  <script src="https://gist.github.com/dhan12/6206272.js"></script>
The output is shown here: It worked on the first try. I think this will be the way of the future for me.

When code reviews become painful

Code reviews are good, see for example http://www.codinghorror.com/blog/2006/01/code-reviews-just-do-it.html.  This is not new.  In fact, I have experienced all of the benefits that come with code reviews.  They've helped me identify bugs, learn new ways to do things, learn what my coworkers are working on and all ... Overall, code reviews make the world a better place.

This past week, I found myself saying, "I hate code reviews".  I said it under by breath to myself so no one could hear it, but I said it nonetheless.  Here are two gripes I had with code reviews and some thoughts on improving the process.

Code reviews can lead to flame wars.  
My co-workers are great, and I have learnt a lot from them - yet, we all differ in the way we code.  The most frustrating code reviews are the ones where everyone agrees that the code works, but changes are needed for other reasons.  Maybe the reviewer thinks that the code goes against some best practices guidelines, the code will have some future maintenance issue or that the code is just unclear at first glance.   What do you do if the reviewer says, "Yes, your code works, but I would have done it this way."  Here are some things I thought of:

  1. Make your reviewer do some work.  If your reviewer critiques a piece of code, I think it is fair to ask for a suggestion on what they think should be done.  After a concrete suggestion is made, you can either implement the change or say why you don't think the suggested method is better.  If it isn't too clunky, a comment can be added with the alternative coding route.  
  2. Limit the number of time a change of code is discussed.  Unless there is a miscommunication, it should be possible to present all arguments for and against a change in two rounds of reviews.  After that point, I think the reviewer should accept the change or pass the code to someone else for review.  
  3. Don't get code reviews from your direct manager.  They have too much authority.  Their suggestions aren't suggestions, they become orders.  

Code reviews break my workflow. 
Waiting for my code to be reviewed takes time and breaks my workflow.  This is in contrast to great modern tools like automatic/continuous building and testing.  Immediate feedback increases productivity and delayed feedback is frustrating.

  1. When giving estimates for delivering an update, set aside another 2-3 days (calendar time) for each code change.  This will give you buffer time and will reduce stress and frustration.
  2. Make sure that you have a very realistic development and or alpha environment for testing where you can release code to before a code review is complete.  If you have an alpha environment, you can continue with the deployment process and ensure that if your change is accepted, you won't discover bugs later on when you are rolling the code out.  If the code review has a delay, you might find and fix bugs before the code review has even occurred.

Monday, August 5, 2013

Searching for a needle in a hay stack

I have a lot of faith in modern search engines.  If I want something to eat, need directions, or want to learn something, Googling for the answer will amazingly give me the answer.

But today I had some trouble finding some information.  I wanted to know how to construct a query for a google appengine app that would search over a group of values.  In SQL, the query would look something like:
select * from mytable
where field IN ('someDataToMatch', 'anotherGoodValue', 'and so on');


I figured that the syntax would be similar, but googling for something like
"Google appengine datastore query IN"

sent me in the general direction of where my answer was, but it didn't give me the answer.  The problem of course is that "IN" is a very common word and it doesn't really give the search engine much to work with.  As an aside and for future self reference, the answer I was looking for is here: https://developers.google.com/appengine/docs/python/ndb/queries#neq_and_in.

I imagine that Google and others are working on improving searching and probably have lots of great things that they are building and testing, but here a couple quick thoughts on improving search:
  1. Allow users to opt-in to a program where Google or any other search engine can essentially spy on you.  If a search engine knew that I was a software developer, who has been working on a google appengine project for the past few days, has spent some time going through a few tutorials, and reading stackoverflow questions about google's datastore, I would hope that they would have a better chance at helping me find the page that I want.  
  2. I need a browser extension that monitors all of the pages I look through after I start searching for something.  If I find the answer I am looking for, I can hit a button that says "I'm done".  I think this will be the only way to map search terms to pages that are good hits for me. 
I guess I think that improving internet search will be similar to the future of medicine - personalized just for me.

Sunday, August 4, 2013

Weekend coding

This weekend was a typical one for me (at least for the last few years).  I spent the majority of the time with my family, hung out with some friends on one night, and did some household chores.

During the weekend, I managed to spend about 1.5 hours working on my latest project (this google app engine).  Given it was only a small amount of time, I made some decent progress. 

In my day job, my objective is to build reliable, maintainable, error-free performant code.   
At home, my objective is to build things that are interesting and fun, while learning something along the way.  Given the difference in weekend coding from real-job coding, here are some pointers on how to make progress on a hobby project successful.
  • Keep a list of work items that you may want to work on next. This list should be varied like, "updating the database schema to hold a user's dataset" or "update the UI to align all the buttons on the page".  I never know what mood I will be in when I return to a project. If I feel like making UI updates, working on back end tests or whatever, there should always be something ready to work on.
  • Make quantum updates.  This means take small steps that a make a difference.  If you try to accomplish a big task within a small amount of time, you may not finish anything tangible, which is disheartening.  
  • Code first, fix errors later.  This is probably the one that is the biggest departure from my normal habits.  For weekend coding, it's most important to get something working, so that you can give yourself a job-well-done pat on the back.  If you spend too much time harping on every edge case, you again might run out of time.