3 posts tagged “.net”
In a recent job interview, the hiring manager was looking over my résumé, and noted that I said I had experience with ".Net 3.0". He then asked, "You mean .Net 3.5, right?" At the moment, I really didn't know what the differences were between the two, even though I was pretty sure the answer was yes. I bluffed with a "yes." He took my answer at face value, but it has bothered me since then. So, for those who are curious, here's a link to where the author untangles Microsoft's branding/versioning mess with the latest releases of .Net, C# and Visual Studio:
It turns out that I was correct. My skill set is fully up to date with .Net 3.5, C# 3 and VS 2008.
I recently ran into a situation where my test code was failing only under certain types of test pass runs on machines that I have no access to. To diagnose the problem, I wanted to log the contents of the filesystem under certain directories.
I was already familiar with System.Diagnostics.Process and System.Diagnostics.ProcessStartInfo, which exist to let you launch processes from your .Net program. In fact, the problem was that I was attempting to launch an executable using these classes, but the executable file wasn't being found. I struggled for over an hour with trying to run 'dir /s', the command for recursively listing the contents of a folder and all subfolders, using the Process class. Eventually, I worked out one solution, shown in the C# fragment below, that allows me to run the command and grab the output into a string.
using System.Diagnostics;
using System.IO;
/// <summary>
/// Outputs recursively the contents of the specified path to
/// the test log.
/// </summary>
/// <param name="path">The path to list contents from.</param>
private static void LogRecursiveDirectoryContents(string path)
{
string batchFile = Path.ChangeExtension(Path.GetTempFileName(),".bat");
string commands = "dir /s" + Environment.NewLine;
File.WriteAllText(batchFile, commands);
ProcessStartInfo batchInfo = new ProcessStartInfo(batchFile);
batchInfo.UseShellExecute = false;
batchInfo.RedirectStandardOutput = true;
batchInfo.WorkingDirectory = path;
using (Process batchProcess = Process.Start(batchInfo))
{
SuiteLogger.LogInfo(batchProcess.StandardOutput.ReadToEnd());
batchProcess.WaitForExit();
}
}
As you can see, I used static methods in System.IO.Path and System.IO.File to generate a temporary batch file with my shell command as the contents. Then, I create a ProcessStartInfo object for running the batch file, setting 'UseShellExecute' to false and 'RedirectStandardOutput' to true. Setting these two properties will allow me to get the ouput of the batch file process from the Process's StandardOutput stream. The final step before launching the process is to set the 'WorkingDirectory' where the batch file will be executing from. In my case, I used the result of Environment.GetEnvironmentVariable("programfiles").
Finally, the process is launched in the context of a 'using' block, since Process uses native resources and needs to have Dispose() called on it in order to release them. I log the output using boilerplate code from the documentation of Process.StandardOutput and my test environment's logger.
I hope you found this useful and interesting.
I just finished this book. It was the first book I ever read devoted to the subject of test-driven development (TDD). I highly recommend the first 3 chapters where the topic is introduced by way of using TDD to implement an object stack from scratch, and then to refactor a prime numbers calculator. The rest of the book is devoted to a fictional web services application. Once you've read a couple of chapters of that, the rest of the chapters start to blend together. The chapter on customer tests was also a worthwhile read.
I found it worthwhile. I thought I'd been doing test driven development, but really I was writing my code, then immediately validating selected aspects of it with pseudo-unit tests. By pseudo-, I mean that I was actually putting multiple tests together into each routine. Also, I wasn't using (because I wasn't aware of) the classic TDD workflow described in the book:
- Try to think of all the tests you'll be needing. This is also great for planning the time you'll spend on your project.
- Pick a test. You could start simple, then go complex. With experience, you could start with a more complex, but more "fundamental" test for your problem space.
- Write your test.
- Write the minimum implementation that lets your test compile.
- Run your test. If it fails (it usually will, if you were truly minimal), write what's needed to get it to pass.
- Pick another test. Repeat steps 3-5 until all existing tests pass.
- Refactor. Look for code smells in both the test and the implemention to fix. The book mentions a heirarchy of priorities to follow when making refactoring decisions. I'll leave it to you to pick the book up and find out what they are.
- Repeat steps 3-7 until all tests have been written and are passing.
A surprising thing for me was the constant refactoring, especially of test code. It shouldn't have been, but it was. Also, it's completely normal to think of more tests that are needed as you cycle through this workflow. I can't wait to put this into action!