Friday, July 31, 2015

Great article on 12 reasons for writing unit tests



Top 12 Reasons to Write Unit Tests
Most programmers do not write tests. We all know that we should write them, but for whatever reason, most of us don't. This is unfortunate, because testing is the most powerful tool we know of to improve software quality. Tests reduce bugs, provide accurate documentation, and improve design.
In our consulting work we hear every excuse imaginable for not writing tests. For example:
  • "I don't know how to write tests."
  • "Writing tests is too hard."
  • "I don't have enough time to write tests."
  • "Testing is not my job."
  • "My code is too simple for tests."
  • Blah, Blah, Blah ...
We hope that by writing this article we can dispell these myths and encourage programmers to do the right thing and write tests!
Tests Reduce Bugs in New Features
We advocate writing tests as you write new code. Tests do not eliminate bugs, but they dramatically reduce the number of bugs as you add new features.
Tests Reduce Bugs in Existing Features
With well-tested code, introducing new features rarely breaks existing functionality. If a new feature breaks existing functionality, existing tests fail immediately, allowing you to pinpoint the problem and fix it. Without the tests, you may introduce a bug that is not found for days or weeks.
Tests Are Good Documentation
A concise code example is better than many paragraphs of documentation. We see this time after time in our consulting work. Far too often, teams produce boilerplate documents that are of little practical value. When programmers need to learn an API, they search for code examples. Tests are among the best code examples because they are concise snippets of code that exercise public APIs.
Tests Reduce the Cost of Change
Tests make it easier to change software because you have confidence that changes do not break existing functionality. When you have good test coverage, you have confidence to explore new design ideas without fear of introducing new bugs.
Poorly-tested software becomes increasingly expensive to change as time goes on. Risk increases dramatically as the system becomes more complex because it becomes more and more likely that changes inadvertently break things that used to work.
Tests Improve Design
Writing tests forces you to make your code testable. Specifically, you tend to rely less on dubious patterns like singletons and global variables, instead making your classes loosely-coupled and easier to use. Code that is tightly-coupled or requires complex initialization is hard to test.
Tests Allow Refactoring
With tests, you are more able to change code throughout the lifetime of an application. Tests provide a safety net, allowing you to refactor at any time without fear of breaking existing code, so you can constantly improve the design of your program.
Tests Constrain Features
Far too often, programmers build fancy frameworks rather than deliver features customers want. When you adopt a test-first approach, you start by writing tests for the current feature. You then implement the feature. When the tests pass, you know you can stop and move to the next feature. Well-tested applications are more easily extended; therefore, you don't have to anticipate what the customer will eventually request.
Tests Defend Against Other Programmers
Textbook code is simple, but real-world problems are hard. We find that in real applications, you often encounter very subtle bugs due to Java bugs, quirky business rules, operating system differences, etc. These bugs may only manifest themselves under very peculiar scenarios.
Let's suppose you find that a payroll calculation routine removes a zero from everyone's salary, but only if the routine runs at 11:59 PM on New Year's Eve. Now, suppose that the bug fix involves a single-line code change.
Without a test, another programmer may come in and change that code. Unless they run the application at 11:59 PM on New Year's Eve, they won't know that they just re-introduced the bug and will cause countless bounced checks next year. With a test, however, you can ensure that when the programmer changes the code, the test breaks and informs the programmer of the problem.
Testing Is Fun
If you thrive on challenges, then testing is a lot of fun. Coming up with automated tests is difficult, requiring creative solutions for complex problems. Just like coding is an art, testing is an art.
In many organizations, testing is relegated to the least-experienced programmers. We often encounter the misconception that testing consists of people completing written checklists as they manually execute the application. This approach is completely unscalable, because it takes longer and longer for humans (monkeys?) to test every feature as the application grows.
Modern OO languages like Java are complex, particularly when it comes to dependencies between classes. One change can easily introduce bugs in seemingly unrelated classes. Gone are the days when each character-based screen is a standalone program. OO apps are far more complex and demand automated tests.
Writing automated tests is harder than writing the code itself, in many cases. The most expert programmers are the best testers. When faced with seemingly mundane coding tasks, coming up with creative tests provides an intellectual challenge that expert programmers thrive on.
Beginners typically need expert assistance when writing tests. This is where pair-programming helps, because experts work side-by-side with beginners as they learn the art of testing.
Testing Forces You to Slow Down and Think
When adding a new feature or refactoring an existing solution, testing forces you to think about what the code is supposed to accomplish. By writing tests first, you think about how to use the public API and what the ultimate outcome should be. Thus you end up with a clean and simple design that does exactly what you expect it to do.
Testing Makes Development Faster
On a class-by-class basis, testing slows you down. It takes time to think about and produce good tests. But as time goes on, your overall velocity increases because you are not constantly worrying about breaking existing code as you add new features.
We have also found that with good tests, we can ignore internal implementation details during the first iteration. Provided that we get the public API right, we can improve internal design and algorithms later, again without fear of breaking something. We have used this specifically for things like sorting algorithms. In the first iteration, we do something quick and dirty, like a bubble sort. We can always come back later and replace it with a better algorithm, if necessary.
Tests Reduce Fear
One of the biggest fears that programmers encounter is making a change to a piece of code and not knowing what is going to break. Having a complete test suite allows programmers to remove the fear of making changes or adding new features. We have found that we do not hesitate to change and improve well-tested code, whereas we fear changing untested code.
Eric M. Burke is an O'Reilly author and a principal software engineer with Object Computing, Inc. in St. Louis, MO.
Brian M. Coyner is coauthor of the Java Extreme Programming Cookbook and a Senior Software Engineer with Object Computing, Inc. in St. Louis, Missouri.

Friday, July 10, 2015

Postman 3.0 released with some pretty cool new features

Postman is a powerful Rest testing tool built as a Google Chrome app.  The new 3.0 version has some pretty Awesome features.

Some notable features in version 3 are:
  1. New user interface with a new design language.
  2. Collection Browser that lets you view documentation within Postman.
  3. Tabs to let you browse multiple requests.
  4. Code generator
  5. Better search features
  6. Postman Sync available for free for everyone.
  7. INTERCEPTOR - Capture requests from Chrome and build APIs quickly. View and send cookies and restricted headers from within Postman.
  8. NEWMAN - Postman's command-line companion. With Newman, you can integrate Postman collections with your build system. Or you can run automated tests for your API through a cron job.

Tuesday, June 23, 2015

Q&A on Test Driven Development and Code Smells with James Grenning

The whole Q&A is good but here is my favorite question and answer from the interview.
InfoQ: In your opinion what are the causes why are people not doing technical practices like TDD or refactoring sufficiently or well enough?
Grenning: Even though the technical practice of TDD and Refactoring have been around visibly since 1999 (with the publication of Extreme Programming Explained), most people in software development have no idea what they are.  I recall being a young engineer, having large demands on my time from my employer and family.  There was not a lot of time to devote to learning what the best ideas and techniques are. There are many ideas out there on how to build software.  Not all of them so helpful. So its hard to know where to put your energy.  As a young engineer in a new field, I thought I knew everything too.
With experience came the humbling realization that I did not know everything.  There is a lot to know in this broad and deep field.  We each learned how to program in a very unique way.  For me, a professor showed some examples of C programming constructs and then gave us an assignment to write an operating system.  Go figure it out! And we each did figure out how to program in our own unique way.  It seems that no one was taught how to program. If you think you are already a master of your craft, what motivation if there to learn more?
I give a survey to people that are about to attend my training.  You can see the questions and answers here: Training preparations replies.  You can see the techniques for writing and testing software are all over the map.  Most report using the techniques we used at the university in the 70s, and in industry in the 80s and 90s: print statements, break pointing and single stepping the debugger. Congratulations, it is 2015 and you are using state of the art debugging techniques from the 1970s!  How about trying 1999 state of the art defect prevention with TDD!?
After seeing TDD, engineers tell me they do not have time to write tests.  They do not have time to proactively prevent defects but they do have time to react to those defects.  Engineers also tell me that their boss won’t let them write unit tests.  It should be equivalent to me not not following my doctor's prescription because I’m in a hurry.
The long feedback loops that most developers live with are part of the problem.  Let’s say I provide an estimate of three months to my boss.  After two and a half, I go and deliver the bad news that I need another month.  This repeats.  Finally a subset of the promised functionality is delivered after six months.  It only looked like the engineer was really working when the deadlines were close.  What does this do to the engineer’s credibility?  Not much.
Working in iterations, with slim vertical slices of functionality, delivered every couple weeks, does a lot for a programmers credibility and confidence.  Having the test safety net catches unwanted changes in behavior.  The programmer gets all that for free once they master TDD as it takes about the same amount of time to get the code working in the first place with TDD as it does the 1970s way, Debug Later Programming (see the physics of test driven development).

Tuesday, June 16, 2015

Alfresco SDK 2.1

Just watched this tech talk on the latest version of the Alfresco SDK.



This sums up how you should setup a development environment and develop on top of Alfresco.

Here is a link to the current documentation.




Friday, June 12, 2015

Agile Software Development Videos from Bob Martin

Here are some really good videos about agile development.   Bob Martin is a great presenter. 

These are all pretty long but they are all worth watching.   The first 3 in the list below are my favorites.

Professional Software Development

Craftsmanship and Ethics

Demanding Professionalism


Clean Architecture and Design

The Single Responsibility Principle


The SOLID Principles of OO and Agile Design

Saturday, May 31, 2014

Moving from traditional filesystem storage to ATMOS for Alfresco

I recently had the opportunity to configure Alfresco with ATMOS using the Alfresco S3 connector.

The company I work for has an ATMOS cloud setup across multiple data centers.  

ATMOS is an object-based cloud storage platform to store, archive and access unstructured content at scale.  

We had an existing instance of Alfresco leveraging NetApp storage that I had to migrate to ATMOS.

In order to do this I needed to download and install 2 tools.

The steps to make the move to ATMOS are fairly simple…

    1.  Stop your Alfresco and Solr servers

    2.  Create your S3 bucket with ATMOS FOX. 
    3.  After you create the bucket you must add a non listable meta tag (bucket-mapping-type=one_to_one) to the bucket folder. 

     4.  Copy your files in your contentstore and contentstore.deleted to Atmos using AtmosSync.jar. 

     5.  Update your alfresco-global.properties with your S3 configuration.
          ### S3 Config ###
          s3.accessKey=xxxxxxxxxxxx/xxxx
          s3.secretKey=xxxxxxxxs3.bucketName=bucketNAME

             #s3.bucketLocation=US
             s3.flatRoot=falses3service.https-only=false
             s3service.s3-endpoint=ATMOSHOST
             s3service.s3-endpoint-http-port=8080#
             s3service.disable-dns-buckets=false
             dir.contentstore=contentstore
             dir.contentstore.deleted=contentstore.deleted
          #Maximum disk usage for the cache in MB 

             system.content.caching.maxUsageMB=51200
             #Maximum size of files which can be stored in the cache in MB (zero implies no limit)              
             system.content.caching.maxFileSizeMB=0 

      6.  Back up your DB if you haven’t already

      7.  Update all records in the ALF_CONTENT_URL table (store:// to s3://)
               UPDATE alf_content_url SET content_url = replace(content_url, 'store:', 's3:’)

 
     8.   Startup Alfresco and Solr servers and you should be good to go.   


Once you have verified that Alfresco is functioning properly you can repurpose the filesystem storage.

Wednesday, January 8, 2014

Duplicate entries put into HashSet Java issue

I have recently run into an issue using HashSet.addAll(Object) where duplicates are added to my Set.

I even made sure that the Object I was using Overrode hashCode().

Apparently the addAll() implementation for HashSet doesn't check for duplicates.  This is bad because a reason for using a Set over a List is to avoid duplicate values.

If you loop through all of the values in the collection you are adding to the Set it works as expected not adding the duplicates.  This is the approach I took to get around this issue.

for (item in myCollection){
    set.add(item)
}

vs what I was trying to do which didn't work:

set.addAll(myCollection)

Another approach could be extend the HashSet and override the addAll() with the logic I used.