Sunday, September 15, 2013

Example for a responsive console application with async/await vs threads

There are mainly two reasons for using asynchronous programming:
  1. Utilize your CPU cores by parallelizing CPU intensive work.
  2. Keep your application responsive while long running activities are in progress. These activities may be CPU intensive work or are waiting for a response from the web, lan or database (IO bound work)   
Responsiveness is not only required for applications with an user interface but also for background services and applications. Background services should answer additional request even when they are currently busy with something else. On a user interface a user wants to at least be able to cancel a long running activity.

The following simple example demonstrate asynchronous programming with .NET 4.5 and async/await with an console application. The two long running activities (DoAction1() and DoAction2()) with CPU bound work are executed in parallel. The user can exit the application even before the computation and printing of the result has finished:
class Program
{
 static void Main()
 {
     var program = new Program();

     program.PrintResultAsync();

     Console.WriteLine("Press <return> to exit ...");
     Console.ReadLine();
 }

 public int DoAction1()
 {
     int result = 0;
     for (int i = 0; i < 5; i++)
     {
       Console.WriteLine("Action1 "+ result);
       Thread.Sleep(250);
       result++;
     }
     return result;
 }

 public int DoAction2()
 {
     int result = 0;
     for (int i = 0; i < 5; i++)
     {
       Console.WriteLine("Action2 " + result);
       Thread.Sleep(250);
       result--;
     }
     return result;
 }


 public async void PrintResultAsync()
 {
     Tuple<int, int> r = await ComputeResultAsync();
     Console.WriteLine("Result " + r.Item1 + " + " + r.Item2 + " = " + (r.Item1 + r.Item2));
 }

 private async Task<Tuple<int, int>> ComputeResultAsync()
 {
     var t1 = Task<int>.Factory.StartNew(this.DoAction1);
     var t2 = Task<int>.Factory.StartNew(this.DoAction2);
     return new Tuple<int, int>(await t1, await t2);
 }
}

The application has the output on the console below:
We can compare the previous async/await implementation with an equal implementation using plain threads. The thread based implementation is much longer and requires more overhead like additional member variables:
class Program
{
 static void Main()
 {
     var program = new Program();

     program.PrintResultWithThreads();

     Console.WriteLine("Press <return> to exit ...");
     Console.ReadLine();
 }

 public int DoAction1()
 {
     int result = 0;
     for (int i = 0; i < 5; i++)
     {
       Console.WriteLine("Action1 "+ result);
       Thread.Sleep(250);
       result++;
     }
     return result;
 }

 public int DoAction2()
 {
     int result = 0;
     for (int i = 0; i < 5; i++)
     {
       Console.WriteLine("Action2 " + result);
       Thread.Sleep(250);
       result--;
     }
     return result;
 }

 private int r1;
 private int r2;
 private ManualResetEvent e1 = new ManualResetEvent(false);
 private ManualResetEvent e2 = new ManualResetEvent(false);
 private WaitHandle[] manualEvents;

 public void PrintResultWithThreads()
 {
     var printThread = new Thread(
       () =>
       {
         e1 = new ManualResetEvent(false);
         e2 = new ManualResetEvent(false);
         manualEvents = new WaitHandle[] { e1, e2 };
         ComputeResultsWithThreads();
         WaitHandle.WaitAll(manualEvents);
         Console.WriteLine("Result: " + r1 + " + " + r2 + " = " + (r1 + r2));
       });
     printThread.IsBackground = true;
     printThread.Start();
 }

 private void ComputeResultsWithThreads()
 {
     var t1 = new Thread(
       () =>
       {
         this.r1 = this.DoAction1();
         this.e1.Set();
       });
     t1.IsBackground = true;
     t1.Start();
     var t2 = new Thread(
       () =>
       {
         this.r2 = this.DoAction2();
         this.e2.Set();
       });
     t2.IsBackground = true;
     t2.Start();
 }
}

Sunday, January 13, 2013

Introducing Continuous Integration: A Success Story

In his book “The Clean Coder” Robert C. Martin tells several anecdotes from his professional live as a software developer to explain the attitude of a professional developer. That reminds me of a story when I started my current job.
It was around 2009 when I started to work in an organization with seven software development teams each with the size of approximately ten people. The teams delivered every two month new software versions which are then manually integrated to a running system on a medical device hardware. The integration took around additional four to six weeks. I couldn't believe that software was created with this “stone age” process. In the worst case the developers got feedback for their features from the fully integrated system only after three month. Oh my good, why do I started to work there? I talked to my boss about my concerns and he admitted that we have to change something. So I was appointed as a project manager. The core project team had two members: Matt, a very experienced software consultant and me.
We called the project “DailyBuild”. So our goal was to speed up the integration cycle time from ninety days to one. Yes, there where a lot of obstacles on our way. For example the teams used different source code control systems, we perceived the number of used build scripting tools as nearly infinite and the total software build time was about eight hours. Many problems we had to solve were related to the organizational structure of the development department. And of course if you want to change the way of working of people, a lot of them say: “Why should we change, we have always worked like this”. The only good thing was that I knew all the time that the project could not fail. I knew that the benefits would be overwhelming. The agile movement was already around several years and thousands of software teams had already adopted Continuous Integration.

After 4 month we had the first successful automated build including a simple smoke test of the integrated system on a virtual machine. It took some more weeks to finish things. Today, no one in the development department can imagine to work any more without the “DailyBuild” process in place. Yes we made it!

Sunday, November 4, 2012

Lerning Perl with TDD and Unit Tests

As an absolute beginner to the language I needed to write my first Perl script. As a big fan of Test-Driven Development (TDD) I thought it would be a good idea to start with a test when doing the first Perl program. And it worked really nice. This post should be a simple step-by-step tutorial for Perl beginners who want to write simple Unit Tests for Perl. I will use my first Perl script as an example.

The Example: A ClearCase trigger

To customize the behaviour of ClearCase you have to write Perl scripts which can be associated with any ClearCase command as a so called ClearCase trigger (see IBM Rational ClearCase: The ten best triggers). For my example, I needed a trigger that updates a FitNesse Wiki page (the file name is always "content.txt") when it is checked-in to ClearCase. If the file contains a string like "$Revision: \main\MAINLINE_SQE\3 $" the Perl script should update the version information. That's it. 

Step-by-Step Tutorial


  1. Install Perl.
  2. Create a folder "PerlScripts" for the new Perl scripts. We will have two files in this folder: "CiVersionFitnesseTrigger.pl" is the Perl script for the trigger. "CiVersionFitnesseTriggerTests.pl" is the Perl script for the corresponding Unit Tests.  
  3. Download the Test::Simple Perl module. Unpack the gz archive. We will only need the file "Simple.pm" from the folder "lib/Test". Create a folder "Test" as sub folder of our "PerlScripts" folder. Copy the file "Simple.pm" to this "Test" folder.
We start writing our first test in "CiVersionFitnesseTriggerTests.pl":
use Test::Simple tests => 1;

# System under test
require 'CiVersionFitnesseTrigger.pl'; 

# Testing is_fitnesse_wiki_page() method
ok(FitTrigger::is_fitnesse_wiki_page('content.txt'), 'content.txt is page');

We start defining an empty sub routine and an empty main routine in "CiVersionFitnesseTrigger.pl":
package FitTrigger;

sub is_fitnesse_wiki_page {
 return  0;
}

#
# Main method
#
1;
We can now run the first unit test and see it failing:
Now we have the infrastructure to start implementation. We fix the first failing test:
package FitTrigger;

sub is_fitnesse_wiki_page {
 my ($file_name) = @_;
 return  $file_name =~ m/^(.*\\)?content\.txt$/
}

#
# Main method
#
1;
Now run the unit test again and it succeeds:
We continue the cycle of writing new unit tests and implementing the script step by step. In the end we have 12 unit tests and 1 integration test:
use Test::Simple tests => 13;

# System under test
require 'CiVersionFitnesseTrigger.pl'; 

# Testing is_fitnesse_wiki_page() method
ok(FitTrigger::is_fitnesse_wiki_page('content.txt'), 'content.txt is page');
ok(FitTrigger::is_fitnesse_wiki_page('c:\content.txt'), 'c:\content.txt is page');
ok(FitTrigger::is_fitnesse_wiki_page('..\content.txt') , '..\content.txt is page');
ok(FitTrigger::is_fitnesse_wiki_page('c:\temp\content.txt'), 'c:\temp\content.txt is page');
ok(!FitTrigger::is_fitnesse_wiki_page('content.txt.old') , 'content.txt.old is not a page');
ok(!FitTrigger::is_fitnesse_wiki_page('somecontent.txt') , 'somecontent.txt is not a page');
ok(!FitTrigger::is_fitnesse_wiki_page('content.txt\something.txt') , 'content.txt\something.txt is not a page');

# Testing getTempFolder() method
my $tmpFolder = FitTrigger::get_temp_folder();
ok(defined($tmpFolder) && $tmpFolder ne '' && length($tmpFolder) > 1 , 'temporary folder not empty');

# Testing getTempFile() method
my $tmpFile = FitTrigger::get_temp_file();
ok(defined($tmpFile) && $tmpFile ne '' && length($tmpFile) > 1 , 'temporary file not empty');

# Testing update_revision_in_target() method
my $testFile = "$tmpFolder\\test.txt";
my $targetFile = "$tmpFolder\\target.txt";
open("TESTFILE", ">$testFile") ||
    &error("Could not open test File $testFile for writing");
print TESTFILE "hallo1\nhallo2\n\$Revision: VERSION_ZZZ \$\n";
close TESTFILE;
my $newVersion = 'VERSION_111';
FitTrigger::update_revision_in_target($testFile,$targetFile,$newVersion);
open(F,"$targetFile");
my @list = ;
my $content=join('',@list);
close F;
my $expectedContent = "hallo1\nhallo2\n\$Revision: VERSION_111 \$\n";
ok($content eq $expectedContent, 'version was updated in target file');


# Testing overwrite_file() method
FitTrigger::overwrite_file($targetFile,$testFile);
open(F2,"$testFile");
@list=;
my $newContent =join('',@list);
close F2;
ok($newContent eq $expectedContent, 'file was overwritten with a modified file');
ok(! -e $targetFile, 'modified file is deleted');

# Testing main() method
$testFile = "$tmpFolder\\content.txt";
open("TESTFILE", ">$testFile") ||
    &error("Could not open test File $testFile for writing");
print TESTFILE "hallo1\nhallo2\n\$Revision: VERSION_ZZZ \$\n";
close TESTFILE;
$ENV{CLEARCASE_PN}=$testFile;
$ENV{CLEARCASE_ID_STR}='VERSION_888';
system ("perl CiVersionFitnesseTrigger.pl");
my $expectedContentMain = "hallo1\nhallo2\n\$Revision: VERSION_888 \$\n";
open(F3,"$testFile");
@list=;
my $newContentMain =join('',@list);
close F3;
ok($newContentMain eq $expectedContentMain, 'perl script has updated content.txt');

The complete implementation in "CiVersionFitnesseTrigger.pl" looks like:
package FitTrigger;

sub is_fitnesse_wiki_page {
 my ($file_name) = @_;
 return  $file_name =~ m/^(.*\\)?content\.txt$/
}

sub get_temp_folder {
 my $tmp_folder = $ENV{TMP};
 $tmp_folder = $ENV{TEMP} unless ($tmp_folder);
 $tmp_folder = "/tmp" unless ($tmp_folder);
 return $tmp_folder;
}

sub get_temp_file {
 my $tmp_folder = get_temp_folder();
 return "$tmpFolder\\ccTriggerTmp.$$";
}

sub update_revision_in_target {
 my $source = @_[0];
 my $target = @_[1];
 my $revision = @_[2];
 open("SOURCE", "$source") ||
  &error("Could not open source file $source for reading");
 open("TARGET", ">$target") ||
  &error("Could not open target file $target for reading");
 while ()
 {
  if (/\$Revision:?.*\$/) {
                    s/\$Revision:?.*\$/\$Revision: $revision \$/;
         }
  print TARGET;
 }
 close SOURCE;
 close TARGET;
}

sub overwrite_file {
 my $source = @_[0];
 my $target = @_[1];
 open (SOURCE, "$source") ||
  &error ("Could not open source file $source for reading");
 open (TARGET, ">$target") ||
  &error ("Could not open target file $target for writing");
 while() {
  print TARGET;
 }
 close(SOURCE);
 close(TARGET);
 unlink($source);
}

sub error {
    my ($message) = @_;
    die ($message."\nUnable to continue checkin ...\n");
}


#
# Main method
#
# Summary: 
# If the name of the checkin file is ‘content.txt’ then search in the content of the file for a string like
# „$Revision: \main\MAINLINE_22_WIPID\4 $“. This string will then be replaced 
# with e.g. „$Revision: \main\MAINLINE_22_WIPID\5 $“.  

my $check_in_file = $ENV{'CLEARCASE_PN'};
my $revision = $ENV{'CLEARCASE_ID_STR'};

if(is_fitnesse_wiki_page($check_in_file)) {
 my $targetFile = get_temp_file();
 update_revision_in_target($check_in_file,$targetFile,$revision);
 overwrite_file($targetFile,$check_in_file);
}
1;
Running the tests:

Sunday, April 22, 2012

Advantages of Fitnesse over traditional testing tools

Currently I'm part of a team that tries to introduce test automation to our organization. We are developing products for the healthcare sector with relatively long release cycles due to high regulatory requirements. These long release cycles are resulting mainly because of high manual test efforts and missing test automation. There were some discussions which tools to use for test automation. Two main possibilities are available:
  • Traditional commercial, heavyweight, GUI-based, record and replay tools like HP QuickTest Professional, IBM Rational Robot, QF-Test or Borland SilkTest.
  • Agile Acceptance test tools like Fit/Fitnesse.

In a pilot project we found some advantages of Fitnesse over traditional commercial testing tools:

No Licence costs for Fitnesse

Ok, in a big company it's not a big issues to spend some money for commercial tools, but even then you will not buy licences for every machine and every employee. Fitnesse we use on every developer machine, on every tester laptop, on every machine in the test lab, on laptops for presentations in meetings. You can use it on every machine you want without filling order forms and waiting weeks for completion of the order process. So the use of Fitnesse is not limited to the test specialist but instead we can use it cross-functional for application specialists, testers, developers and software architects.

Simple Installation of Fitnesse

Fitnesse can be brought to a machine simply by copying a folder with its subfolders. Or you can run it from an USB stick, which is quite practical for tests on systems wich are not connected to the corporate network.

Test-First approach with Fitnesse

It is a natural approach to write down the test specification before or during the development of the software, because developers need the input to provide test fixtures for connecting the Fitnesse tests with the production code.

Please refer to Elisabeth Hendrickson's blog for similar and more advantages: Agile-Friendly Test Automation Tools/Frameworks

Monday, February 27, 2012

Mocking Best Practices

When writing unit tests you have to use mocks or stubs for dependant objects. Very often it is convenient to use a mocking library (like RhinoMocks for .NET or jMock for Java). Just using a mocking library does not guarantee to get readable and maintainable unit tests. It make sense to have a set of rules which are guiding developers when writing unit tests with mock objects. I compiled a list of such best practices for mock objects ("mocking" rules). I use the term mock object for a objects verifying expectations about calls to themselves. Test stubs are only used for feeding inputs into the system under test.

Rule 1: Try to avoid using mock objects and prefer state verification over behaviour verification if it is possible.

If you can verify the outcome of an method by checking the return value or by checking the state of the system under test, this is the preferable method, because it is simpler and makes your test more independent from the implementation details. You may need test stubs to feed indirect inputs into the system under test.

Rule 2: Apply the Law of Demeter („no train wrecks”) to your code you want to unit test as much as possible.

Testing code like "employee.GetDepartment().GetManager().GetOffice().GetAddress().GetZip()" is much harder than "employee.GetManagersOfficeZipCode()".

Avoiding "train wrecks" reduces the number of mocks and stubs you need and therefore improves readability and maintainability for your tests.

Rule 3: Use a minimum number of mock objects per test, preferable is only one mock object.

Concentrate on one aspect per test. A reader can identify the most important part more easily. In one test you may check the call to one depended-on component (DOC) and in another test you will check another DOC. You may need additional test stubs to feed indirect inputs into the system under test.

Rule 4: Define a minimum number of expectations as possible.

It’s easier for the reader to see what is important. Tests are less brittle when code changes. Test what code does, not how.

Rule 5: Use Command-Query Separation (Side-Effect-Free Functions) for your code. Don't define expectations on mock objects for queries, only for commands.

Divide all object's methods of your code into two sharply separated categories:

  • Queries: Return a result and do not change the observable state of the system (are free of side effects).
  • Commands: Change the state of a system but do not return a value.
Queries deliver input for tests, commands are output. Only check the output (what)

Rule 6: At the borderline between your own code towards foreign code, it may be wise to not stub or mock the foreign code directly.

Very often it is better to create an own interface and implement a small layer of adapter code. Test this small layer with integration tests including the foreign code. It is much easier then to stub or mock your own adapter interface when you test your other own code. Examples for foreign code are database access code (like ADO.NET, JDBC in Java, Hibernate, NHibernate), active directory access, network access, and so on.

References:

Wednesday, December 21, 2011

Testing Java Console Applications

Currently I'm reading the great book "Growing Object-Oriented Software, Guided by Tests" by Steve Freeman and Nat Pryce. They encourage us to drive software development in the large with an outer loop of end-to-end acceptance tests and in the small with an inner loop of unit tests. While implementing just for fun the Nine Men's Morris board game with a simple console user interface, I tried to get a feeling for "test guided growing of software" as it is described in the book.

During that exercise I needed to find a solution to control the input towards and the output from the console. The following example source code shows one possible solution.

I started with an acceptance test. I choose to implement it with JUnit, but Fitnesse tool would have been an alternative.

public class NineMensMorrisAcceptanceTests {

  private ApplicationRunner application = new ApplicationRunner();
  
  @Test
  public void applicationAsksForUserMoveAndThenMakesOwnMove()
  {
    application.startGame();
    application.hasDisplayed("Nine Men's Morris");
    application.hasDisplayed("Please enter spot to place piece:");
    application.userEnters("1\r\n");
    application.hasDisplayed("Computer places piece on spot: 2");
  }
}
The ApplicationRunner class starts the console application in a new thread and acquires control over the input and output streams. Luckily Java has such a well designed IO system, which allows easy test set up. The game application writes to the console via System.out and reads from the console via System.in:
public class ApplicationRunner {

  private PipedOutputStream pipedOutputStream;
  private PipedInputStream pipedInputStream;
  private ByteArrayOutputStream outputStream;

  public ApplicationRunner(){
    pipedOutputStream = new PipedOutputStream();
    pipedInputStream = new PipedInputStream(pipedOutputStream);
    System.setIn(pipedInputStream);

    outputStream = new ByteArrayOutputStream();
    System.setOut(new PrintStream(outputStream));
  }
 
  public void startGame() {
    Thread thread = new Thread("Test Application"){
      @Override public void run(){Console.main(null);}
    };
    thread.setDaemon(true);
    thread.start();
  }

  public void hasDisplayed(String text) {
    boolean displayed = false; int tries = 20;
    while(tries>0 && !displayed){
      Thread.sleep(100);
      displayed = outputStream.toString().contains(text) ? true : false;
      tries--;
    }
    if (!displayed){
      throw new AssertionError("Missing text in output: " + text);
    }
  }

  public void userEnters(String userInput) {
    pipedOutputStream.write(userInput.getBytes());
  }
}
The Console.main() method set ups and starts the console application:
public static void main(String[] args) {
  ConsoleGameUI consoleGameUI = new ConsoleGameUI();
  GameController controller = new GameController(
    consoleGameUI, 
    new Engine(),
    new MoveGenerator());
  consoleGameUI.init(new InputParser(),controller);
  controller.start();
}
When we develop the ConsoleGameUI class, we will write some unit tests. There we can use also the hijacked streams to control inputs and outputs. Because this time the test runs synchronously we can use a ByteArrayInputStream instead of PipedInputStream to supply the user input to the system under test:
public class ConsoleGameUITests {
 
  // Class under test
  ConsoleGameUI consoleGameUI;

  private String userInput;
  private ByteArrayInputStream inputStream;
  private ByteArrayOutputStream outputStream;
  ...
 
  @Before public void setUp() {
    userInput = "some input from user";
    inputStream = new ByteArrayInputStream(userInput.getBytes());
    outputStream = new ByteArrayOutputStream();
    System.setIn(inputStream);
    System.setOut(new PrintStream(outputStream));
    ... 
    consoleGameUI = new ConsoleGameUI();
    consoleGameUI.init(inputParserMock, gameControllerMock);
  }
 
  @Test public void shouldPromptTheUserToEnterSpotToPlaceAPiece(){
    consoleGameUI.askUserForMove(Turn.PLACE_WHITE);
    assertTrue(outputStream.toString().contains("Please enter spot to place piece:"));
  }

  @Test public void shouldPromptTheUserToEnterSpotsToSlidePiece(){
    consoleGameUI.askUserForMove(Turn.SLIDE_WHITE);
    assertTrue(outputStream.toString().contains("Please enter spots to slide piece:"));
  }

  @Test public void shouldReadInputAndCallParser()
  {
    context.checking(new Expectations() {{
      oneOf(inputParserMock).Parse(userInput);
      ...  
    }});
    consoleGameUI.askUserForMove(Turn.PLACE_WHITE);
    context.assertIsSatisfied();
  }
  ...
}
In the ConsoleGameUI class we use System.out and System.in:
public class ConsoleGameUI implements GameUI {

  private final Scanner scanner;
  private IInputParser parser;
  private IGameController gameController;
 
  public ConsoleGameUI(){
    this.scanner = new Scanner(System.in);
  }
 
  public void init(IInputParser parser, IGameController gameController){...}
 
  @Override
  public MoveRequest askUserForMove(Turn turn) {
    switch(turn){
    case PLACE_WHITE:
      System.out.print("Please enter spot to place piece:"); 
      break;
    case SLIDE_WHITE:
      System.out.print("Please enter spots to slide piece:");
      break;
    ...  
    String line = scanner.nextLine();
    MoveRequest request = parser.Parse(line);
    return request;
  }
  ...
}

Friday, February 25, 2011

Rhino Mocks Arrange / Act / Assert (AAA) Syntax Quick Reference

Recently I held a training session about Test-Driven Development(TDD) for .NET developers. A important part in this training was about Mocking, which is essential when you apply TDD to the real world. I presented several examples with Rhino Mocks and used the brilliant AAA syntax of Rhino Mocks. As supporting material for the practical exercises of the participants I missed a quick reference or an API documentation for this syntax style. Based on Ayende's article Rhino Mocks 3.5 and the Rhino Mocks 3.3 Quick Reference I created a new document with code examples:

Rhino Mocks AAA Syntax Quick Reference on Google Docs Rhino Mocks AAA Syntax Quick Reference on Scribd