
Two upcoming events you might want to go to:
Tuesday, August 2nd, the Charlotte Enterprise Developer’s Guild is a presentation on Web Application Attacks by SPI Dynamics. From the description:
This session demonstrates how to defend against common attacks at the Web application layer with examples covering Web application hacking methods such as SQL Injection, Cross Site Scripting, Parameter Manipulation, Session Hijacking, and LDAP Injection. In addition, the session covers the techniques and processes that can be easily implemented into the application development lifecycle to ensure protection from such common attacks without requiring security expertise.
Also, on September 17th, Charleston, S.C. is having their first ever MSDN Code Camp! If you haven’t been to one before, you definately need to check it out. Low cost, amazing speakers, and, unlike Charlotte’s Code Camp, the Beach! Get registered soon.
One of the things about this town (Charlotte) is that pretty much every IT person here has worked for either BoA or Wachovia at some point in their careers. Between the two they employ something like 150,000 total employees in Charlotte. In fact, the building I worked in at Wachovia, the CIC, has over 10,000 people in it.
When I worked at Wachovia, the department I was contracting for started the CMM process. The consultants came in, reviewed the processes, and started to put together plans for how to eventually achieve CMM 5. Which, in and of itself, isn’t necessarily bad (though I think they would be much better off trying to be more agile instead of trying to be more rigorous in their process, but that’s for another post). But then Wachovia announced plans to cut 4,000 jobs and $500 Million in costs (My favorite quote after mentioning that Wachovia is posting record revenue: “And chief executive officer Ken Thompson vowed that the company’s strong results would not get in the way of ongoing efforts to cut costs.”). Suddenly, everything becomes a little more relevant.
But, honestly, I hadn’t thought about it much, because I left Wachovia nearly a year ago now. But we interviewed a developer candidate for our team on Tuesday, and he happened to mention that the team he was working on had not pushed to do any kind of process certification (other than the standard Bank stuff). Which got me thinking, I wonder if the departments they don’t want to cut right off the bat they are putting through the CMM process, so that once they reach level 5, they can just redirect the process documents to an off-shore development shop, especially since one of the things I see a lot of the offshore firms pushing is that they are CMM certified.
It will be interesting to watch, especially still having friends at BoA and Wachovia (though we are doing everything we can to hire them away :)).
Last week I was struggling with a way to test editing capabilities of my DataGrids using NUnitASP. The premise is that I have a data management page that has two DataGrids. Each had an EditCommandColumn defined so users could do inline editing of the information. I didn’t feel comfortable with it, though, because I couldn’t get it wrapped in Unit Tests with NUNitASP. The reason is that when you define and EditCommandColumn you can define the text of the links or push button, but .NET doesn’t render the controls with an ID, which happens to be how NUnitASP hooks everything up.
I knew there was TemplateColumn, but I really didn’t want to roll my own solution to editing DataGrids. What I found was an easy solution which is only slightly harder than using EditCommandColumn.
First, create a DataGrid that looks like:
ReadOnly="True" />
Note that the TemplateColumn defines both an ItemTemplate and an EditItemTemplate.
Next, wire up the code behind. I used a general approach for Edit and Cancel, since all the DataGrids will do the same thing with that:
protected void cmdEdit_Click(object source, EventArgs e)
{
LinkButton edit = (LinkButton)source;
DataGrid dg = (DataGrid)edit.Parent.Parent.Parent.Parent;
int itemIndex = ((DataGridItem)edit.Parent.Parent).ItemIndex;
dg.EditItemIndex = itemIndex;
BindData();
}
protected void cmdCancel_Click(object source, EventArgs e)
{
LinkButton edit = (LinkButton)source;
DataGrid dg = (DataGrid)edit.Parent.Parent.Parent.Parent;
dg.EditItemIndex = -1;
BindData();
}
protected void ReasonCodeGrid_UpdateCommand(object source, EventArgs e)
{
DataGridItem rowBeingEdited = ReasonCodeGrid.Items[ReasonCodeGrid.EditItemIndex];
int reasonCodeId = int.Parse(rowBeingEdited.Cells[0].Text);
string englishDesc = ((TextBox)rowBeingEdited.Cells[1].Controls[0]).Text;
string spanishDesc = ((TextBox)rowBeingEdited.Cells[2].Controls[0]).Text;
ReasonCode reasonCode = new ReasonCode(reasonCodeId);
reasonCode.ReasonCodeEnglish = englishDesc;
reasonCode.ReasonCodeSpanish = spanishDesc;
reasonCode.Update();
ReasonCodeGrid.EditItemIndex = -1;
BindData();
}
(For those interested, my BindData() method just sets the DataSource of the DataGrid).
The key here is the EditItemIndex. Setting it to something other than -1 is just like having an EditCommandColumn and clicking on the Edit button. Setting it back to -1 is the same thing that Update and Cancel does in the EditCommandColumn.
So now you have a DataGrid that displays an Edit button, and when you click on the Edit button, Update and Cancel links appear for that row. Knowing now how that works, I can drive my UI with NUnitASP tests like:
public void TestEditReasonCodeGrid()
{
AuthenticateUser();
Browser.GetPage(DATA_MANAGEMENT_URL);
DataGridTester.Row editRow = reasonCodeGrid.GetRow(0);
LinkButtonTester editLink = new LinkButtonTester("cmdEditReasonCode", editRow);
AssertVisibility(editLink, true);
editLink.Click();
LinkButtonTester updateLink = new LinkButtonTester("cmdUpdateReasonCode", editRow);
LinkButtonTester cancelLink = new LinkButtonTester("cmdCancelReasonCode", editRow);
AssertVisibility(updateLink, true);
AssertVisibility(cancelLink, true);
}
From http://idiacomputing.com/moin/FortuneCookies:
Here is Edward Bear, coming downstairs now, bump, bump, bump, on the back of his head. It is, as far as he knows, the only way of coming downstairs, but sometimes he feels that there really is another way, if only he could stop bumping for a moment and think of it. And then he feels that perhaps there isn’t.
- A.A. Milne
Tomorrow’s CharJUG presentation is on JUnit. JUnit, for those of you who are not aware, is a unit-testing framework for Java. (Well, it is officially labeled as a regression-testing framework, but you do that through Unit Tests). It is part of the xUnit family of Unit Testing frameworks, where you replace the x with some other language of choice such as C++ (cppunit), .NET (NUnit), Javascript (JsUnit), etc.
The concept behind these tools is that you write a test in your chosen language which results in some sort of check, like Assert.IsTrue(customer.DidPay). Then, the framework runs these tests and spits back a result. When using the GUI versions of these tools it returns a red bar if any test failed, and a green bar if they all passed.
Now, writing Unit Tests seems about as exciting as replacing every instance of the letter q that your uber-3l1t3 developer used as the variable name for a critical component, manually. But while there are many reasons one would think of testing as an activity for those strange QA guys, I want to introduce the idea of using tests to design your code.
I’ll start with a simple example of how to use a test to design my code. Let’s say I want to calculate sales tax for an item. Being the good OO developer I am, I could just write something like:
private const double SALES_TAX = 7.5;
public double CalculateSalesTax(double amount)
{
return amount * SALES_TAX;
}
Four lines of code later, I’m done. But, let’s say I wanted to let tests drive the design instead. I would start out with something like:
public void TestSalesTaxCalculatedCorrectly()
{
double amount = 10.00;
double expectedSalesTax = 0.75;
double salesTax = CalculateSalesTax(amount);
Assert.AreEqual(expectedSalesTax, salesTax);
}
But this wouldn’t compile, because we hadn’t written our CalculateSalesTax method yet. But now we would, and it would look just like it did above.
What did we gain? Nothing much yet. But now, let’s say our app is going to be used in two different states, so the sales tax is different. We now add a test for Florida:
public void TestSalesTaxCalculatedCorrectlyFlorida()
{
double amount = 10.00;
double expectedSalesTax = 0.65;
double salesTax = CalculateSalesTax(amount);
Assert.AreEqual(expectedSalesTax, salesTax);
}
Which fails, because our CalculateSalesTax method had the Sales tax hardcoded. So we know we need to modify our sales tax method to calculate based on state:
public double CalculateSalesTax(double amount, State state)
{
if(state == State.NORTH_CAROLINA)
{
return amount * 7.5;
}
else
{
return amount * 6.5;
}
}
Which now causes our tests to fail, because they aren’t passing in the state. So we modify them:
public void TestSalesTaxCalculatedCorrectlyNorthCarolina()
{
double amount = 10.00;
double expectedSalesTax = 0.75;
double salesTax = CalculateSalesTax(amount, State.NORTH_CAROLINA);
Assert.AreEqual(expectedSalesTax, salesTax);
}
public void TestSalesTaxCalculatedCorrectlyFlorida()
{
double amount = 10.00;
double expectedSalesTax = 0.65;
double salesTax = CalculateSalesTax(amount, State.FLORIDA);
Assert.AreEqual(expectedSalesTax, salesTax);
}
And now all of our tests pass. So now what have we gained? The confidence and knowledge that our CalculateSalesTax method correctly calculates Sales Tax for Florida and North Carolina. What else have we gained? The lowering of the test barrier. You’ve got the tests written, so if you think of another condition that you want to check, you just add a test for it. Finally, if you ever modify the CalculateSalesTax method, say to have the sales tax rates pulled from a more dynamic source, you can know that you didn’t break anything, because you have the tests to show it.
This concept of letting your tests drive your design is called, aptly enough, Test-Driven Development. Of course, TDD is part of the whole Extreme Programming movement, but this, along with automated builds, is one of the things you can do today, with little impact to your skeptical developing peers, that will have a big impact on producing quality, bug free code.
I was in Sam Ash on Friday (trying to pick up one of these) chatting with one of the guys in Pro Audio. He found out I do software development, and said that he had asked over 20 different people how he can get a simple printout of all the files in a directory, including the files in any subdirectories.
I looked around on Google for a bit, and did find one Sourceforge project, and found the command line switch for it (dir /s if interested), but I wanted a more tree view. So I threw together a simple directory traversal printer. Not much to it really, the heart of it is a GetFilesAndDirectoriesRecursive method:
private string GetFilesAndDirectoriesRecursive(DirectoryInfo dir, string prefix)
{
DirectoryOutput.Text += ".";
DirectoryOutput.Refresh();
System.Text.StringBuilder output = new System.Text.StringBuilder();
output.Append(prefix + "+" + dir.Name + LINE_BREAK);
DirectoryInfo[] dirs = dir.GetDirectories();
foreach(DirectoryInfo d in dirs)
{
output.Append(GetFilesAndDirectoriesRecursive(d, INDENT_PREFIX + prefix));
}
FileInfo[] files = dir.GetFiles();
foreach(FileInfo file in files)
{
output.Append(prefix + INDENT_PREFIX + "-" + file.Name + LINE_BREAK);
}
return output.ToString();
}
Anyway, if you need something like this, you can grab it from here, full source included.
(EDIT: A good friend (and awesome developer) Brady Gaster rewrote this using delegates and callbacks. Definately worth checking out.)
So, I’ve got this Panasonic MiniDV camera (in PAL format – not NTSC) that I’ve had. It’s been an awesome camera, but I’m looking to get an 8-track recorder for some of my music stuff, so it’s for sale. I’ve got it up on Ebay but if someone is willing to trade an 8-track Tascam or similar recorder for it let me know.
Back from Florida. It was a good trip – though we forgot just how hot it is down there in the summer. I got to spend 8 hours cooking barbecue chickens for my old fire department’s Fourth of July parade – it was a great time, and I’ll talk some more about that later.
But one of my coworkers swung by and asked a very simple question – how do you get the results of a stored procedure (that returns a result set) into a table that you can query or join or use somewhere else? The simplest way is that temp tables are your friend, and you just insert the results into your temp table:
CREATE PROC test_proc
AS
SET NOCOUNT ON
SELECT TOP 10 id, name FROM employee
CREATE TABLE #tmp(
[id] int,
name varchar(64)
)
INSERT INTO #tmp
exec test_proc
With that, you can now treat the temp table like any other table:
SELECT *
FROM #tmp
Just don’t forget to clean up when you are done!
DROP TABLE #tmp