I have been an iPhone owner since the iPhone 3G was released in the USA on July 11, 2008. Why do I remember the exact day? Because I was one of the nerds that stood in line outside Tuttle Mall, in Columbus, Ohio, way before the AT&T store opened! Anywho, I often get asked what my favorite iPhone app is. Having tried out a fair share of apps from the App Store, I have to say my all time favorite is Evernote.
If you are the type of person that tends to forget things, loose things, and hates to spend a long time organizing information, then this is app is for you! And you don't really need to have an iPhone to use it. It is available for all major smart phones. Plus you can use it directly through www.evernote.com, or via multiple Web Browser addons or use one of the many thick client versions they have for all major operating systems.
If I need to remember anything for later (a store receipt, notes from a lecture, a good deal I see in the paper, a shopping list, recipe from a friend, a note from my kids' school, the name of a good wine bottle,.. you name it) I simply snap a picture of what I want to remember and send it to my Evernote account via the Evernote iPhone App. If I feel up for it I might tag the note (e.g. Recipe) and add a descriptive title (e.g. "Chili Recipe from Bob"). But often I am to lazy to do that, and it typically doesn't matter. I just file it and forget it. What Evernote does when it files my note is to automatically perform OCR on the picture and store any text it extracts as metadata along with the note. So if Bob showed me a handwritten recipe that he had titled "Bob's kick ass Chili" then that piece of text (granted it is written in legible writing) would automatically be stored in the metadata index for the note. So if years later I searched my Evernote account for "Chili", or "Bob" AND "Chili" I would find the recipe.
To me, Evernote is the shoe box method for organizing, that actually works! Meaning, you can get away with throwing all your junk into one large shoe box and thanks to Evernote's powerful search capabilities have it at your fingertip anytime you need it. Feeling left out at a chili cooking party? Just whip out your cell phone and say "One second, I have a better recipe!" and voila you are the star of the party! ;-)
For more info on Evernote, check out one of their many introductory videos on www.evernote.com. Then sign up and get an account! The basic account is free and should be sufficient for most users.
Blog about software development, agile practices, software use, and the latest happenings in the wide world of technology
Sunday, December 19, 2010
Wednesday, November 17, 2010
Notes on Test Driven Development and Testing
This week I attended the Agilis 2010 conference, including a 2 day course on Test Driven Development by Nat Pryce. Below are a few notes from his class. Not necessarily the key teachings, but rather nuggets of information that I found interesting.
- One of the main arguments for using TDD is that it encourages you to improve the design of your code. Writing the test for a software component that you have designed, but have yet to implement gets you to think about and question the purpose and nature of your design. E.g., if when writing a unit test for a given class you discover that the test code gets way to complex or convoluted, then that is probably an indication that the class being tested has too broad responsibility and should be refactored into smaller, simpler units. I had always thought of TDD as more of a means to ensure you build a comprehensive test suite and as a result have fewer bugs in your software, but had not given much thought to the fact that it is in essence a way to get you to improve your software design; hence making your code easier to understand, use, and maintain.
- We did some exercises using the JMock framework, that Nat Pryce co-wrote. JMock is a neat tool to help you mock out interfaces that your code interacts with and to validate that your code is using the interfaces as expected. JMock allows you to command the mock object of the interface to behave a certain way (e.g. return specific results) and set up expectations for how you are planning to call the interface (e.g. methodA will be called once and only once with arguments "ABC" and 99). These expectations are integrated with JUnit and if not fulfilled by the end of your test run then JUnit will fail the test.
- The following JMock Cheet Sheet page provides an overview of he JMock syntax.
- During the Q&A session with Nat he admitted that JMock was probably best suited for green-field projects (new systems) while frameworks like Mockito where better suited for brown-field projects (preexisting systems that you are trying to create tests for).
- We spent some time discussing Monitoring Events, which is the concept of having your system broadcast notifications (events) about your code execution. E.g. when an order is placed or when a user logs into your system a notification of the event is sent to a JMS Topic that interested parties can subscribe to.
- This is great for logging. A logger component can subscribe to the topic and log all events in the system. It can then allow you to filter out certain events or do things like group events by requestid and provide a holistic overview of a single user transaction (as opposed to having to grep through numerous log files on multiple servers to try piece together what happened when a given user transaction ran through the system, which may have spawned multiple threads in multiple JVMs).
- Monitoring Events are great for testing too. Imagine trying to assert that a call to a checkout service (to complete the purchase of a product) will result in a proper inventory reduction in asynchronous inventory system. If your test runs straight through and checks the inventory status as soon as it has completed the purchase, then the test will likely fail, since the inventory system hasn't had time to process its update inventory request. One might try to fix such a test by adding a sleep statement of say 10 seconds after the checkout call but before the inventory is checked (which still might fail if the system is running slow). Or (which is a little better) one might implement a loop that every 1 second pulls the inventory system to see if the update has been received (succeed fast). In both cases we are polluting our tests with sleep statements and lengthening the time to feedback, when we run a suite of tests. A better way would be to have the test subscribe to the Monitoring Event (topic) and complete (succeed) as soon as it has received an inventory update notification.
- You can also use Monitoring Events to build a support tool for your system. E.g. the tool could send an email or SMS text message to a support person when a certain event is received (OutOfMemoryError, External service not responding, etc) or a when certain number of events have been received over a given time frame.
- Miscellaneous tips on testing and coding
- If you are ever testing code that depends on the system clock (e.g. at noon every day the system is supposed to execute some function) then a neat trick to make that code more testable is to refactor out the dependency on the system clock. E.g. instead of your class making a direct call to say System.currentTimeInMillis(), have your constructor take in a generic Clock object (or define a class variable and use dependency injection to inject a Clock implementation). Then you can have a SystemClock implementation that simply uses the current system clock, where as during your test run, the class under test is initialized with a FakeClock implementation that hardcodes the time to 12 PM)
- In your system tests, which load up and work with data in a database, have your JUnit setUp method clear out the database, rather than the tearDown method. This way you have actual data to look at if a test fails (rather than a clean swiped database).
- Use Simplicators to simplify communication with 3rd party APIs. That is, a facade that maps the 3rd party interface and artifacts over to your domain model or something that makes sense in your system. This way you can more easily test your own code (by using mock Simplicators that don't have a dependency on a 3rd party system) and likewise your code is more easily maintained (e.g. a type change or renaming of a field in some 3rd party XML response may require you to update your Simplicator implementation, but might have no impact on your business code if the response has already been mapped over to your domain model.
- Have separate tests that test your production setup. Basically tests that you can run in production to verify a deployment. Don't deploy your unit/system tests into production. Avoid the painful lesson that GitHub recently experienced where a test run in production cleared out their entire production database!
- When programming, don't have your methods return null! Null checks pollute you code and make it harder to debug. Return empty objects instead.
Sunday, March 21, 2010
Agile netið Founded
This week I took part in founding the Agile Network (Agile netið), a consortium of agile minded Icelandic companies, one of which is Hugsmiðjan, my current employer. The purpose of the non-profit organization is to advocate Agile and Lean development practices and sponsor agile lectures and conferences in Iceland. The founding partners are 10 companies that have been doing agile for awhile and are interested in sharing their experiences and learning from each other. At the founding meeting we elected a 3 person board for the organization, of which I got elected secretary :-) Hopefully it wont be too much work :) I am very excited to be part of this process and hope to learn a lot from my fellow members. The website for the organization is www.agilenetid.is. No English version yet, but we are working on it. Then there is a Facebook group for those interested in keeping up with what were are doing. Fans wanted :)
Subscribe to:
Posts (Atom)