Welcome to MSDN Blogs Sign in | Join | Help

Ivo Manolov's Blog

.NET, WPF and Win32 Programming

Syndication

Introduction to TestApi – Part 2: Command-Line Parsing APIs

Command-line parsers remind me of linked lists in C++: everybody has written several at various points in their careers. While everybody should write each of those at least once, I doubt that many people out there are particularly excited about writing and re-writing fundamental data structures on a regular basis – it gets old very quickly. Not to mention that doing so is error-prone and decreases the maintainability of a world that’s already hard to maintain.

That’s why modern-day frameworks such as .NET provide standard implementations of the common data structures. And that’s why TestApi provides a reusable command-line parsing APIs via the CommandLineDictionary and CommandLineParser classes, the latter being a type-safe layer on top of the former. Obviously, these are not test APIs per se – they are general utility APIs that happen to be more often used when writing tests.

A few quick examples follow.

Simple Command-Line Parsing

As seen from the first example below, extracting command-line parameters that are primitives is easy. Primitive command-line parameters are either boolean (e.g. the “verbose” flag below), or a key-value pair, that one can extract with the indexer of the CommandLineDictionary instance (see the “testId” key below), just as one would expect from a Dictionary.

// 
// EXAMPLE #1: Parsing a command-line such as "RunTests.exe /verbose /testId=123"
// 

using System;
using Microsoft.Test;

public class Program 
{ 
    public static void Main(string[] args) 
    { 
        CommandLineDictionary d = new CommandLineDictionary(args);

        bool verbose = d.ContainsKey("verbose");
        int testId = Int32.Parse(d["testId"]);
                
        // use the parsed command-line parameters
    }
}

By default flags/keys are indicated with the forward slash (“/”) character and values are indicated with the equals character (“=”), but the user can override that upon initialization of of the CommandLineDictionary object:

// 
// EXAMPLE #1b: Parsing a command-line such as "RunTests.exe –verbose –testId:123"
// 

...
        CommandLineDictionary d = new CommandLineDictionary(args, '-', ':');
...

Finally, you one can use the ToString method to get a string representation of the command-line arguments.

 

Command-Line Argument Structures

Another common pattern when dealing with command-line arguments is populating a structure which contains all parsed arguments. The CommandLineParser class makes this easy:

// EXAMPLE #2:
// Sample for parsing the following command-line:
// Test.exe /verbose /runId=10
// This sample declares a class in which the strongly typed arguments are populated
public class CommandLineArguments
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }
}

CommandLineArguments a = new CommandLineArguments();
CommandLineParser.ParseArguments(a, args);

 

Type-Safe Commands

A third common approach is forming strongly-typed commands from the command-line parameters. This is common for cases when the command-line looks as follows:

some-exe  COMMAND  parameters-to-the-command

The parsing in this case is a little bit more involved:

  1. Create one class for every supported command, which derives from the Command abstract base class and implements an expected Execute method.
  2. Pass an expected command along with the command-line arguments to CommandLineParser.ParseCommand – the method will return a  strongly-typed Command instance that can be Execute()-d.

// EXAMPLE #3:
// Sample for parsing the following command-line:
// Test.exe run /runId=10 /verbose 
// In this particular case we have an actual command on the command-line (“run”), 
// which we want to effectively de-serialize and execute.
public class RunCommand : Command
{
   bool? Verbose { get; set; }
   int? RunId { get; set; }

   public override void Execute()
   {
      // Implement your "run" execution logic here.
   }
}

Command c = new RunCommand();
CommandLineParser.ParseArguments(c, args); 
c.Execute();

Besides the parsing logic, CommandLineParser provides a few additional helper methods. One of them is CommandLineParser.PrintCommandUsage, which prints the usage for specific commands (or all supported commands) to the console.

 

In Conclusion

The command-line parsing APIs released with TestApi provide a simple and “layered” access to the command-line. Strictly speaking these APIs are not test APIs, but have nevertheless been included in TestApi as tests often have a need of parsing parameters on the command-line.

Published Wednesday, December 17, 2008 2:15 PM by ivom

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Announcing WPF TestAPI 0.2 release @ Monday, April 27, 2009 5:35 PM

Last week, the WPF test team released a new version of their Test API: 0.2. You can download the new

Jaime Rodriguez

# Announcing WPF TestAPI 0.2 release | Coded Style @ Monday, April 27, 2009 7:20 PM

PingBack from http://www.codedstyle.com/announcing-wpf-testapi-02-release-8/

Announcing WPF TestAPI 0.2 release | Coded Style

# Announcing WPF TestAPI 0.2 release | Coded Style @ Monday, April 27, 2009 7:20 PM

PingBack from http://www.codedstyle.com/announcing-wpf-testapi-02-release-2/

Announcing WPF TestAPI 0.2 release | Coded Style

# Announcing WPF TestAPI 0.2 release | Coded Style @ Tuesday, May 05, 2009 1:26 AM

PingBack from http://www.codedstyle.com/announcing-wpf-testapi-02-release/

Announcing WPF TestAPI 0.2 release | Coded Style

# Announcing WPF TestAPI 0.2 release | Coded Style @ Tuesday, May 05, 2009 1:27 AM

PingBack from http://www.codedstyle.com/announcing-wpf-testapi-02-release-9/

Announcing WPF TestAPI 0.2 release | Coded Style

# Announcing WPF TestAPI 0.2 release | Coded Style @ Tuesday, May 05, 2009 1:29 AM

PingBack from http://www.codedstyle.com/announcing-wpf-testapi-02-release-20/

Announcing WPF TestAPI 0.2 release | Coded Style

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
Page view tracker