I'm fairly old fashioned at times ... but should I embrace unit testing?
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
We did some unit testing with Nunit in the past, but it proved too time-consuming to keep up with the rapid pace of changes of our software. So I think the idea is good, but not for our situation (small team, rapid changes) I also shiver when I read articles about "Test Driven Development" :-\ Oh, and of course the obligatory: Slant: best-unit-testing-frameworks-for-net[^]
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
OriginalGriff wrote:
as best I can
Which is why I don't bother. There is no way to test for many of the bugs I write. ;P Just yesterday I ran into a situation which I'm sure can't be tested statically, the problem arose because I fed two incompatible CSV files into a parser -- and it blew up with an
IndexOutOfRangeException
. Today I'm telling the parser to catch the Exception and returnnull
. Maybe it can protect large teams from simple mistakes made by inexperienced developers. -
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
Not only I do it but I ended up writing my own unit test framework (and published it on CodeProject[^]) It is so easy to create new tests that most bugs I find end up as test cases and serve as regression tests.
Mircea
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
I use MSUnit but am quite strict about using it to test units, not larger lumps of functionality so broadly speaking there is not much of a maintenance cost to keep the tests working...then it is automated as part of the CI/CD pipeline on Azure DevOps.
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
+ 1 for philistine methodology :-D
"Life should not be a journey to the grave with the intention of arriving safely in a pretty and well-preserved body, but rather to skid in broadside in a cloud of smoke, thoroughly used up, totally worn out, and loudly proclaiming “Wow! What a Ride!" - Hunter S Thompson - RIP
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
It's the debate between "is it good enough to ship?" and "we have 500 unit tests but haven't shipped anything in 2 years". (True story).
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
Unit tests are often a waste of time. See the articles linked here[^]. Coplien is one of the few "gurus" for whom I have much use. Unit tests are orthogonal to whether tests are automated. Automation, and system and regression tests, are essential to anything beyond toy projects.
Robust Services Core | Software Techniques for Lemmings | Articles
The fox knows many things, but the hedgehog knows one big thing. -
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
Best unit test I have ever found= user (see idiot) :laugh:
>64 Some days the dragon wins. Suck it up.
-
We did some unit testing with Nunit in the past, but it proved too time-consuming to keep up with the rapid pace of changes of our software. So I think the idea is good, but not for our situation (small team, rapid changes) I also shiver when I read articles about "Test Driven Development" :-\ Oh, and of course the obligatory: Slant: best-unit-testing-frameworks-for-net[^]
RickZeeland wrote:
but not for our situation (small team, rapid changes)
That's supposed to be the point of unit testing. :laugh:
Latest Articles:
ASP.NET Core Web API: Plugin Controllers and Services -
Not only I do it but I ended up writing my own unit test framework (and published it on CodeProject[^]) It is so easy to create new tests that most bugs I find end up as test cases and serve as regression tests.
Mircea
How did that article not get any votes? Well, it got mine now (a 5).
Latest Articles:
ASP.NET Core Web API: Plugin Controllers and Services -
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
For algorithmic things like what you posted, unit tests are great, and I would definitely write that with a unit test "engine." That said, I also end up spending time debugging the tests, not the algorithms. :laugh:
Latest Articles:
ASP.NET Core Web API: Plugin Controllers and Services -
How did that article not get any votes? Well, it got mine now (a 5).
Latest Articles:
ASP.NET Core Web API: Plugin Controllers and ServicesThank you Marc :) It was one of my first CodeProject articles and probably not very good.
Mircea
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
My experience is that most test frameworks rapidly grows into such a complexity that you spend far more time on all the required red tape than on developing good tests. It may pay for huge systems that will be in development for many years, by scores of developers, but for smaller systems, you can do 99% of the same amount of testing with a much simpler infrastructure, with far less test management. Certainly: Do systematic testing! And have a setup that allows you to play old tests again - a.k.a. regression testing. Just don't let the testing infrastructure completely take over. The important tasks in testing is not managing the tests, but rather to identify relevant test cases. All corner cases - and sometimes the cartesian product of all possible cases (when the product is within reasonable limits). How to provoke synchronizing and timing issues. Identify relevant stress testing. And so on. I have seen cases where far more time was spent on test management than on developing relevant tests. Regression testing is essential (and I am surprised by how often I see new software releases witn regression from earlier releases!), but sometimes I wonder if it is getting out of hand: Some years ago, I worked in a development environment having collected regression tests for many years. Before a release, we started the test suite before going home on Friday evening, hoping that it would complete before Monday morning ten days later. So for bugs/fails reported by that week (++) run, there was a ten day turnaround. We invested in the very fastest Sun machine available on the market, cutting the time to complete the tests started on Friday afternoon to complete some time on the (first) following Monday, a week earlier than with the old setup. Yet I was asking myself if we should possibly consider reducing the amount of regression testing, or trying to make the structure more efficient. Fact is that continuous unit, module and system tests regularly applied during development were so complete that the week long (later: weekend long) regression test run practically never revealed any problems. In later jobs, I have seen tests requiring magnitudes more power than they should have, due to lack of proper unit and module tests. Or rather: Management of such. The developers do not trust that units have been properly tested, so in every module where the unit is used, the unit tests are run again, 'in this context'. Then for every (sub)system referencing a module, all the module tests are repeated, repeat
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
I don't always test my code, but when I do, I do it in Production.
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
I'm both old and old-fashioned. I view the unit testing fad with the same disdain as I do Scrum. It's double the work and I am set in my ways for testing. I build internal-facing apps only, and I just don't see the benefit to TDD. That's what users and UAT is for. :laugh: But I am impressed with your test code. Kind of already looks all unit testy to me.
If you think 'goto' is evil, try writing an Assembly program without JMP.
-
I'm both old and old-fashioned. I view the unit testing fad with the same disdain as I do Scrum. It's double the work and I am set in my ways for testing. I build internal-facing apps only, and I just don't see the benefit to TDD. That's what users and UAT is for. :laugh: But I am impressed with your test code. Kind of already looks all unit testy to me.
If you think 'goto' is evil, try writing an Assembly program without JMP.
I'm old too. Had a manager who was into TDD. He said things like "write the test before the method" How in the blue heck am I supposed to write a test for something I haven't figured out what it's supposed to do yet? Mercifully he moved to Washington state then Idaho. Don't have to deal with him anymore.
I’ve given up trying to be calm. However, I am open to feeling slightly less agitated.
-
At the moment, when I create a public class called Foo, I also create a static test class called FooTester which exercises the public members of the class as best I can. For example, my non-contiguous range class Range has a RangeTest class that looks like this:
public static string Run() { try { testsRun = 0; testsPassed = 0; testsFailed = 0; outText.Clear(); Range ra = new Range(0, 4); // Range rb = new Range(5, 9); // Contiguous with ra Range rc = new Range(10, 14); // Contiguous with rb Range rd = new Range(1, 3); // Intersects ra, not contiguous with rb Range re = new Range(6, 8); // Intersects rb, not contiguous with rc Range rf = new Range(16, 19); // Not contiguous with anything. Range rg = new Range(0, 0); // Single element. Range rh = new Range(1, 1); // Single element. Range ri = new Range(2, 2); // Single element. Range rj = new Range(0, 19); // All elements. Range rk = new Range(0, 4); // Identical to ra CheckInt(ra.Count, 5); CheckInt(ra.Min, 0); CheckInt(ra.Max, 4); CheckString(ra, "(0:4)"); CheckString(ra.UnionWith(re), "(0:4) | (6:8)"); Check(Range.GetEmpty(), new int\[0\]); Check(ra, new int\[\] { 0, 1, 2, 3, 4, }); Check(new Range(new int\[\] { 0, 1, 2, 5, 6, 7 }.AsEnumerable()), new int\[\] { 0, 1, 2, 5, 6, 7 }); Check(ra.UnionWith(ra), new int\[\] { 0, 1, 2, 3, 4 }); Check(ra.UnionWith(rb), new int\[\] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); Check(rb.UnionWith(rc), new int\[\] { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(rc), new int\[\] { 0, 1, 2, 3, 4, 10, 11, 12, 13, 14 }); Check(ra.UnionWith(re), new int\[\] { 0, 1, 2, 3, 4, 6, 7, 8 }); Check(ra.UnionWith(rg), new int\[\] { 0, 1, 2, 3, 4 }); Check(rb.UnionWith(rg), new int\[\] { 0, 5, 6, 7, 8, 9 }); Check(rg.UnionWith(rh).UnionWith(ri), new int\[\] { 0, 1, 2 }); CheckInt(ra.UnionWith(rc).Count, 10); CheckInt(ra.UnionWith(rc).Min, 0); CheckInt(ra.UnionWith
OriginalGriff wrote:
but should I embrace unit testing?
I do, because it lets me sleep at night. :) But I'd be lying if I said I do TDD - I don't. I write unit tests after the fact (but I do write them), and after I've written integration tests. Why? Because I find them more valuable than unit tests, but don't consider them to be a substitute for unit tests. Integration tests first, then unit tests. At least that's how I run. /ravi
My new year resolution: 2048 x 1536 Home | Articles | My .NET bits | Freeware ravib(at)ravib(dot)com