If you don't hear the siren, police are sure you'll feel the Rumbler
-
The Los Angeles Police department announced its intention to install the
low-frequency Rumbler siren into 20 black-and-white vehicles before a
larger exp...
Showing posts with label note-to-self. Show all posts
Showing posts with label note-to-self. Show all posts
Thursday, June 11, 2009
WinMerge in VS2008
James Manning has an MSDN post for VS2005 that still helps when configuring alternative merge and compare tools.
Friday, April 10, 2009
Obsolete attribute in .NET
More from the note-to-self category: the [Obsolete] attribute generates compile-time warnings (or errors) but is not enforced by the framework at runtime. This is pretty obvious when you realize its purpose (backwards compatibility that warns but does not break) but spooked one of my coworkers.
Tuesday, March 10, 2009
Bulk unblock in Vista
Vista's UAC suspicion of downloaded code (and other files) manifests itself as a warning on each such file, cropping up when you open them. I usually see this when I download sample code, open the VS .sln, and collapse under the slew of warning windows.
Ideally, my antivirus software would have a setting to remove these values after a successful scan, or at least prompt me. It doesn't.
The fix, like so many fixes, comes from SysInternals. The underlying problem is that the downloaded files have been associated in NTFS's mind with the "main unnamed data stream". Si's streams utility strips off this association, and will do it recursively:
streams -s -d .
The "." for current directory is necessary.
I must have Googled and re-learned this a dozen times.
Ideally, my antivirus software would have a setting to remove these values after a successful scan, or at least prompt me. It doesn't.
The fix, like so many fixes, comes from SysInternals. The underlying problem is that the downloaded files have been associated in NTFS's mind with the "main unnamed data stream". Si's streams utility strips off this association, and will do it recursively:
streams -s -d .
The "." for current directory is necessary.
I must have Googled and re-learned this a dozen times.
Wednesday, November 19, 2008
Test pattern
File this under note to self. Say you have a method to test, and inside it looks something like:
public class Foo
{
public bool Bar()
{
return A && B && C && D == "https";
}
}
Meaning, your method has several dimensions of possible inputs, and only one or a handful of acceptable states. Obviously, if the function really is as simple as that, you might not even want a test; static inspection might suffice. But suppose that the evaluation of A, B, and C is a little more complex or expensive, and suppose that there are, say, 3 different acceptable combinations among the full permuation of inputs.
Further suppose that A..D are each enumerable domains. (The actual use case that made me think of this was something like: A is "whether a page requires SSL", B is "the user is authenticated", C is "a certain control is visible", and D is "the protocol on the page request".)
What should the test look like?
The code that began to test-drive the implementation started out like this:
[Test]
public void Bar()
{
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.Https };
Assert.That(foo.Bar(), Is.True);
// cases 2 and 3 not shown but expect true
// everything else expects false
foo.A = false;
Assert.That(foo.Bar(), Is.False);
// tedious and brittle cut-and-paste looms if not careful...
}
This is the sort of situation you get into with TDD and Simplest Thing That Could Possibly Work. Having plucked the low-hanging fruit in the first few passes, you then need to cover something like "all the other situations". You're tempted to write something like:
[Test]
public void Bar()
{
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
Assert.That(foo.Bar(), Is.EqualTo(a && b && c && d == Uri.Https));
// okay, this only covers one of the three acceptance cases; you get the idea, though
}
}
In other words, your verification looks suspiciously like your implementation. Nine times out of ten, that will work. But every so often you discover that you've overlooked some aspect of the problem, and your mirror-image test code didn't identify the discrepancy because it was so similar to the implementation that both had the same bug. (For example: maybe the evaluation of A, B, and C can have side effects that create a subtle a temporal dependency in the order of evaluation, and by duplicating the SUT logic in the test, you never exercise alternative paths.) In general, I feel much safer if the test code takes a different route over the problem space than the SUT does.
You could go table-driven, but then you've got a table to maintain, and how do you know the table is correct? (Read: exhaustive.) Really, you want to codegen the table, which is why I actually like the nested foreach() blocks that iterate over explicit sets in the second version. The loops are clear, terse, and exhaustive. I'd like to keep that portion of the structure while having something that is logically equivalent without being codewise identical.
So, here's the pattern I prefer:
[Test]
public void Bar()
{
// explicitly test each of the small number of outliers
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.UriSchemeHttp };
Assert.That(foo.Bar(), Is.True);
// repeat for the two other affirmative cases
int trues;
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
if(foo.Bar()) trues++;
}
Assert.That(trues, Is.EqualTo(3));
}
Terse? Check. Exhaustive? Check. Sufficiently different? Check. It seems unlikely that, if I refactor this code six weeks from now, I'd make a mental mistake on the implementation that would easily transfer to the test as well.
As they say in math, the proof is by counting.
public class Foo
{
public bool Bar()
{
return A && B && C && D == "https";
}
}
Meaning, your method has several dimensions of possible inputs, and only one or a handful of acceptable states. Obviously, if the function really is as simple as that, you might not even want a test; static inspection might suffice. But suppose that the evaluation of A, B, and C is a little more complex or expensive, and suppose that there are, say, 3 different acceptable combinations among the full permuation of inputs.
Further suppose that A..D are each enumerable domains. (The actual use case that made me think of this was something like: A is "whether a page requires SSL", B is "the user is authenticated", C is "a certain control is visible", and D is "the protocol on the page request".)
What should the test look like?
The code that began to test-drive the implementation started out like this:
[Test]
public void Bar()
{
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.Https };
Assert.That(foo.Bar(), Is.True);
// cases 2 and 3 not shown but expect true
// everything else expects false
foo.A = false;
Assert.That(foo.Bar(), Is.False);
// tedious and brittle cut-and-paste looms if not careful...
}
This is the sort of situation you get into with TDD and Simplest Thing That Could Possibly Work. Having plucked the low-hanging fruit in the first few passes, you then need to cover something like "all the other situations". You're tempted to write something like:
[Test]
public void Bar()
{
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
Assert.That(foo.Bar(), Is.EqualTo(a && b && c && d == Uri.Https));
// okay, this only covers one of the three acceptance cases; you get the idea, though
}
}
In other words, your verification looks suspiciously like your implementation. Nine times out of ten, that will work. But every so often you discover that you've overlooked some aspect of the problem, and your mirror-image test code didn't identify the discrepancy because it was so similar to the implementation that both had the same bug. (For example: maybe the evaluation of A, B, and C can have side effects that create a subtle a temporal dependency in the order of evaluation, and by duplicating the SUT logic in the test, you never exercise alternative paths.) In general, I feel much safer if the test code takes a different route over the problem space than the SUT does.
You could go table-driven, but then you've got a table to maintain, and how do you know the table is correct? (Read: exhaustive.) Really, you want to codegen the table, which is why I actually like the nested foreach() blocks that iterate over explicit sets in the second version. The loops are clear, terse, and exhaustive. I'd like to keep that portion of the structure while having something that is logically equivalent without being codewise identical.
So, here's the pattern I prefer:
[Test]
public void Bar()
{
// explicitly test each of the small number of outliers
Foo foo = new Foo() { A = true, B = true, C = true, D = Uri.UriSchemeHttp };
Assert.That(foo.Bar(), Is.True);
// repeat for the two other affirmative cases
int trues;
foreach(bool a in new[] {true, false})
foreach(bool b in new[] {true, false})
foreach(bool c in new[] {true, false})
foreach(string scheme in new[] {Uri.UriSchemeHttp, Uri.UriSchemeHttps, Uri.UriSchemeFile})
{
Foo foo = new Foo() { A = a, B = a, C = a, D = scheme};
if(foo.Bar()) trues++;
}
Assert.That(trues, Is.EqualTo(3));
}
Terse? Check. Exhaustive? Check. Sufficiently different? Check. It seems unlikely that, if I refactor this code six weeks from now, I'd make a mental mistake on the implementation that would easily transfer to the test as well.
As they say in math, the proof is by counting.
Subscribe to:
Posts (Atom)