|
|
Comments and Discussions
|
|
 |

|
He he, yeah that would probably keep you out of trouble for years to come.
-
Andrew T Finnell
Active Solutions LLC
andrew@activesol.net
|
|
|
|

|
I'm all for better testing and defined testing processes. I'm the first to admit that I don't do enough myself.
We in the SD business have a real problem, though. Management and customers rarely understand the importance of testing (from a time and money perspective) at least until something goes wrong. Developers are also doing a poor job (in general) of delivering well tested applications. Some developers will say that if a customer is not willing to pay for testing, they won't do business with them. That's fine when working in a sellers market, and especially when working with larger clients, but when you're in a buyers market or dealing with mostly small firms, this is a serious problem.
In my mind, what is needed, is a much better development platform, better devlopment practices and less testing. The reality is that much of the testing methodologies being employed cannot identify problems in a real world situation, especially when working with vastly distributed systems, web applications, etc. I am not saying testing is bad, quite the contrary, but I believe that testing should lead to better development and less testing, not the same development and more testing and more seemless testing.
Many of the tests are targeted at testing boundary conditions, ranges, null handling, etc. In my mind all of this testing should be dealt with completely through declarative specifications within and without the code. As an example, consider the function protoype below (C++ style).
int ComputeDistance(LPCTSTR lpszZipCode1, LPCTSTR lpszZipCode2);
This is a very simple function, but it leaves open to guess lots of details. First of all, is the return value in miles, KM, meters???? Second, can lpszZipCode1 or 2 be NULL. A better way to write this is by providing actual class types to accomodate the data passed and returned.
DistanceInMiles ComputeDistance(ZipCode ZipCode1, ZipCode ZipCode2);
This is better, but puts a burden on the developer to build lots of tiny classes. Another way this could be done is declaratively:
int ComputeDistance(LPCTSTR lpszZipCode1, LPCTSTR lpszZipCode2)
:: return is Distance, Miles, Not Nullable, Positive or Zero,
:: lpszZipCode1 is 5 digits, numeric, Not Nullable
:: lpszZipCode2 is 5 digits, numeric, Not Nullable
By declaring the meaning of parameters and return types (and other details if desired), a runtime can test inputs/outputs and throw exceptions before the function is executed. Add this to runtime automated instrumentation and logging, automated test tools and many testing problems are resolved. A validator could be written to interpert declarations for validity, possibly by comparing to known norms, etc.
I would add, that the second example I gave should also be doable, because I would be able to wrap the declarative constratints into a reusable class. Some of this can be done with templates and generic programming, but not all of it. Eifel supports a form of what I am talking about, design-by-contract, but I don't know all the details of how it works.
Obvoiusly, declarative programming does not solve every problem, far from it. BUT, it is a progressive RESULT of testing, instead of just progressing testing.
|
|
|
|

|
Matt Gullett wrote:
Obvoiusly, declarative programming does not solve every problem, far from it. BUT, it is a progressive RESULT of testing, instead of just progressing testing.
That is true and certainly helpful. But you move the problem. In declarative programming you then need to test the declarations. Remember Ariane?
|
|
|
|

|
Stephan Meyn wrote:
In declarative programming you then need to test the declarations.
Indeed you do. MyXaml Lint[^]
Marc
|
|
|
|

|
First of all, I want to thank Marc for doing an excellent job on this article. This is one of many articles he has written that are must reads for any good software developer. What I like most about Marc's articles is that he usually comes up with some new ideas that are worthwhile and thought provoking.
I would like to think of these "Test Patterns" more like "Best Practices" in our testing efforts. Like many of the popular design patterns, we read about these patterns and realize that we have been using them without even realizing it. We just needed someone smart enough (like Marc) to come along to describe it, illustrate it, and attach a name to it. As I was reading this article, I was saying to myself "ooohhhh yeeeeaaaa, I have used this pattern in my testing". Did any of you have this same experience?
As I was reading about all these test patterns that I probably should be using (by the way Marc, thanks for making feel guilty about not testing like I should), I asked myself the following question over and over again "which of these test patterns are an absolute must in my development efforts". I wish I could do them all, but I just don't have time (sound familiar); so I am curious, how many of these test patterns are developers using. Which of these test patterns are absolutely essential to the success of a software development project?
Last but not least, what would it take to motivate a developer to use more of these test patterns on their own software development projects? I know what your probably going to say, more time and more money!!! I myself have discovered a few tricks, and have changed the way I develop software so that I have enough time to do more testing and use more of the test patterns that Marc is talking about in this article. Marc has suggested a few ideas in his article that are worth considering.
Interested in your feedback and experiences,
Kent
|
|
|
|

|
(stream of unconsciousness warning)
I think it is practical, actually. As suggested in another comment, automated testing of certain types of objects (IEnumerator, not IEnumerable, etc) can be made part of the build, as it should. Also, having a catalog of testable things and the ways in which they can be tested can give good cues for the design of new things.
As for which are essential? That of course is up to the project. Given the nature of the work I've had to perform over the last couple years, anything involving collections is fair game, as is object persistence and application state. For me (and I imagine most), this is the typical application model and, in my experience, testing is at best hand-held and inconsistent.
For C# development, NUnit strikes me as a fairly good way for automated testing. It has some improvements that could be made for IDE integration, though, to make it less hands-on, and always used (at compile-time, for instance -- one less click). The idea of automatic testing of classes that conform to an interface would be a great start. I think the biggest impediment is getting people to take the time to devise these tests, and once the tests are created, getting the data to use for them.
.....
What I'd *really* like is to have pattern support in the programming language, or at least the framework. C# has delegate: Singleton would be reasonable to add, and IFactory could be added to the framework.
Bridges and Adapters could be cobbled together, at least as a type of object that you initialize with knowledge of the classes in question; I think they'd need language-level support to be compile-time checked. Perhaps databinding would be a good route?
|
|
|
|

|
Testing is great in theory, but it is difficult at best to get customers to pay for the initial code let alone the 40% overhead for unit tests. Unfortunately a lot of customers only look at the cosmetics and unit testing does not cover GUIs, they don't often see under the hood.
I found unit testing useful on critical parts of an application, but for most part a diligent step through the code and/or development of prototyped components are just as effective.
The patterns you have described look great on paper but as you say hide the complexity and difficulties one can have simply designing and defining test criteria especially with asynchronous processes. Due to the dynamic nature of programming, one may destroy wholesale sections of code: if an array of tests are created around that code you have the extra overhead of removing the tests or redesigning them to accommodate the new coding.
To sum up, the hardest part is working out that balance of what needs testing and keeping a very tidy house when developing the tests so that it is easy to manage the tests.
(It would also be useful if you could try to demonstrate say a small asynchronous app against the patterns you have described, and maybe a scope change effect on the tests with analysis of the change impact.)
My two bobs worth..
|
|
|
|

|
Stuart Kinnear wrote:
Testing is great in theory, but it is difficult at best to get customers to pay for the initial code let alone the 40% overhead for unit tests.
Yup. But what the customer doesn't realize is that he's paying for testing one way or the other. The question is, can unit testing effectively replace some of the QA process?
Stuart Kinnear wrote:
Unfortunately a lot of customers only look at the cosmetics and unit testing does not cover GUIs, they don't often see under the hood.
Here you hit right on the end. This is an issue that I'm trying to get my arms around, because not being able to interact at the GUI level with unit testing is a serious drawback, IMHO.
Stuart Kinnear wrote:
if an array of tests are created around that code you have the extra overhead of removing the tests or redesigning them to accommodate the new coding.
Exactly. Like documentation, unit tests become a maintenance liability. This is supposed to trade off with the time savings they provide. This is like a jellyfish-it squirms and writhes away from your grasp. It's impossible to prove one way or the other, that unit testing saves time. I think the only thing that gives some assurance of saving time is the skill of the programmer.
Stuart Kinnear wrote:
(It would also be useful if you could try to demonstrate say a small asynchronous app against the patterns you have described, and maybe a scope change effect on the tests with analysis of the change impact.)
An excellent suggestion!
Thanks for the feedback,
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|

|
Thanks Marc, I feel that you are the only one who has replied so, who has read my comments properly.
I am not saying "don't do unit testing", I am not that shortsighted. In fact I wrote an article a year or two back on unit testing for Microsoft Access in Pinnacle Publishing's Smart Access magazine.
What I am saying however, is that we live in commercial world, therefore it is important to try and judge what impact unit testing will have in terms of time, cost and maintenance.
It is all well and good to set up hundreds of tests, but what of getting the project complete and on time and within budget? What is the life of the project 1 year, 2 or 20. I would say the way this industry is going 3 to 5 years is lucky.
In "compromise mode", I suggest:
- that all code should be written, as far as possible, to allow the hookup of an unit testing framework. This is so that tests can be applied when desired without impact to the system.
- that the critical sections of the application be identified and tests written only for them.
- that time should be spent how to properly organise tests so that they can be easily maintained.
|
|
|
|

|
If the customer knew what they would save by requiring the developers to write unit tests, I think they would be willing to pay. I don't know of a customer that has enjoyed dealing with bugs and problems. I have been on some projects where the bugs were so bad that they almost cancelled the project. Unit tests are kind of like insurance. Without unit tests, I think it is a risky proposition to develop any kind of software application.
I have personally seen the benefits from writing good unit tests, and what is difficult to understand is that unit tests in most cases actually saved time. How does a developer test changes that are down in the core of the application? Are they really going to make sure that a single change (that may affect many parts of the app) are tested without a good unit test? We both know the answer to that question.
Last but not least, unit tests are no gaurantee that the software is going to work well, but it surely is better than the other alternatives we have that are not cutting it.
Something worth considering.
Kent
|
|
|
|

|
"Testing is great in theory"?
I'm sorry, but I think you're taking a very narrow and short-term view of software development.
Testing (of which unit-testing is one facet) is something that is crucial to any software project and the more complex the project, the more complex and thorough the testing needs to be. Customers *may* only look at cosmetics as you say but they'll always complain if it doesn't work because of a bug "under the hood" that wasn't picked up because of a lack of unit-testing.
A good testing strategy (including unit testing) is especially important if you're talking about developing software that will be maintained by many developers and released according to a quarterly release-schedule to several customers. Then testing is for YOUR benefit. Yes, stepping through code is good and should be performed by the developer *during* development, but writing a good unit test harness protects your code for the future. Repeatedly stepping through thousands of lines of code every time a module changes is far too expensive an activity.
Imagine what it would be like if a developer adds code to the module you wrote 9 months ago and the bug it causes in your code (because the then-correct assumptions you made aren't applicable now) isn't found until 3 months later by a customer. Still think you or someone else can find what's wrong in the 30k lines of code you wrote last year? Probably not without a lot of effort, time and expense.
This is when unit testing comes into its own - the developer adding the bug would have run the unit test which would have shown him or her that they've caused a regression in the module and shouldn't release the code they've just added. As someone else has pointed out, testing is an insurance policy for the longer-term.
As to your comment about having to maintain test harnesses as code is added and removed - yes I agree its a pain, but that's life and a price that simply has to be accepted if you want to write reliable, maintainable software that your customers are happy with and continue to be happy with. Ultimately, they're the ones who keep you in employment.
So in response to your question of who pays? You do. You're investing in your software's future after all. If you can get a contract that also pays for testing time, then count yourself ahead in the game.
Kev
|
|
|
|

|
I think we're missing the point here. The article isn't about why we need to conduct unit test. The article isn't about why customer should pay for unit test. The article isn't about why we should allocate adequate resource to quality assurance. These are business issues: If you plan too aggressively, the risk of overrunning the budget will, inherently, be higher. When you overrun your budget, the first place to cut-cost, naturally, is quality assurance and documentation.
What Marc contributed is a set of test patterns which provides us the necessary foundation/mental framework to help eliminate blind spots in executing unit test and development of test plans.
Norman Fung
|
|
|
|

|
The cost of testing should be in your initial estimate for the project. If the customer shows concern about the cost of testing (either money or time), you, as a developer/engineer, must show them the benefits that come from unit testing.
Take for instance the Pharmaceutical industry. Could you imagine what would happen if the FDA did not enforce rigorous testing on new and existing drugs? And who do you think pays for that testing?
|
|
|
|

|
I think most of the points about negatives against unit testing are made by those who have never done a project in this way.
Unit testing saves time, creates higher quality code and ensures that the code delivered is as close to the customers requirements as possible (not more not less). It answers the question of "are you finsished?" which is difficult without test cases and it means you can refactor/redisign/expand/fix a system so simply because you can test the behavoiur of the code.
As for developer productivity ask anyone who does unit testing correctly how much time they spend in the debugger - it will be close to never.
To the comment that unit testing requires upfront design this I believe is incorrect. Unit testing requires upfront tests - this is one of the biggest benifits of unit testing - you write code to pass tests and then you can refactor to design. You don't design code, write code to the design and then write tests to the code (which is, if one thinks about it - the completely wrong way round.)
For example TDD says: customer wants a search engine, they/we write up test lists and test data such as "Si" should find "Simon" and "Simone" but not "Jessica". Then the programmers write test fixtures to test against those requirements. The design is one which best meets those customer requirements.
Also, testing the GUI is not a massive issue. The GUI should be an extremely thin layer ontop of the code. You test the code and you've tested 99.9% of your program - the GUI is just .1%. Of course you still have to test the GUI but you aren't testing your entire application - you are mostly testing that the GUI layers calls your system correctly.
|
|
|
|

|
the urls for the 'Previous articles in the series' are incorrect, they should be .asp not .html.
another great article though
|
|
|
|

|
netclectic wrote:
the urls for the 'Previous articles in the series' are incorrect, they should be .asp not .html.
Fixed!
Thanks for pointing that out.
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|

|
Mark,
Great article. I always enjoy reading your articles.
The link at the top for "Fixture Setup/Teardown, Test Repetition, And Performance Tests" looks like it should be '...\..autp4.asp' rather than the '...\..aut4.asp' (or something similar, I am going on memory here). The link you have for it further on in the article is correct.
I'll reiterate the question that Nitron had: How do you find time? However you do it, keep up the good work!
Mike
|
|
|
|

|
Nice article! I liked your introduction on NUnit testing. You really got to the point.
I would to propose another pattern: Interface Test Pattern which would be a "higher level" pattern (a pattern using other patterns) that could test all the classes that implement an interface.
What I'm thinking of is , for example, writting a test fixture for IEnumerable and then automatically test all classes implenting this interface.
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|

|
Jonathan de Halleux wrote:
I would to propose another pattern: Interface Test Pattern which would be a "higher level" pattern (a pattern using other patterns) that could test all the classes that implement an interface.
Excellent idea!
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|

|
Ok, here I go with my ideas on the implementation of the InterfaceTest Pattern:
We will need a new TestFixture type that is intends to test interfaces implementation. Here are some important points (and new attributes):
- [InterfaceTestFixtureAttribute]: The objective is to design a way to create a single TextFixture for an interface and apply it to every class that implements the interface. This attribute denotes a testfixture class that tests interfaces.
- [InstanceProviderAttribute] The tester should be able to provide "interface instance providers" that will create new instance, manipulate it and return it to the test class. For example, if you want to test IEnumerableArrayList, you may first want to create a ArrayList, fill it with some elements and then apply the tests on the interface. Testing an empty ArrayList is pretty much useless.
- [InterfaceTest]: A problem with the above is that we need to use the class provided before the provider produces. A possible solution is to use a base class InterfaceTest that defines a public method Current:
public Object Current{get;set;}
This method can then be used at compile time to get a grip on the interface instance (see example below).
Let's see a bit of code that illustrates all that:
First of all, the provider class, which does not provide a particular interface, but is a provider for a class. Therefore one provider can be used to test all the interfaces that the class implements.
[InstanceProvider(typeof(MyClass))]
public class MyClassProvider
{
[CreateInstance]
public MyClass Instance {get...}
}
Note that this provider could be reused in other
interface test if the MyClass would implement
multiple interfaces.
Then, the InterfaceTest base class:
public class InterfaceTest
{
public Object Current {get;}
}
Ok, now the interface test class:
[InterfaceTestFixture(typeof(IMyInterface))]
public MyInterfaceTest : IInterfaceTest
{
[Test]
public void Test()
{
IMyInterface if = (IMyInterface)Current;
}
}
So what would NUnit do to get things working (pseudo-code)
providers = Create a type -> provider map;
foreach( interfaceTest in the test assembly)
{
foreach( class that implement the testedInterface)
{
if (!providers.Contains(class))
continue;
interfaceTest t = new interfaceTest();
t.Current = providers[class].Instance;
...
}
}
Comments ?
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|
|

|
Nifty idea. The only limitation I see off-hand is in the case where the interface doesn't specify the form the output takes. EG: IEnumerable. It simply specifies that an Enumerator can be had -- it doesn't specify what order, etc, to expect. The compiler will ensure that IEnumerable is implemented, which I think is about as far as it could be taken.
It would be trivial to extend this to testing subclasses of a given base class. Same limitation regarding overridden members, but I would somewhat expect that specifications are more likely to exist for classes than interfaces.
|
|
|
|

|
Keith Farmer wrote:
Nifty idea. The only limitation I see off-hand is in the case where the interface doesn't specify the form the output takes. EG: IEnumerable. It simply specifies that an Enumerator can be had -- it doesn't specify what order, etc, to expect. The compiler will ensure that IEnumerable is implemented, which I think is about as far as it could be taken.
Well ensuring that GetEnumerator() actually returns a non null enumerator automatically is already a (useless) test.
Ok, IEnumerable is not a good example, but take IEnumerator. There is quite a number of tests that you could be automated, no matter what object type is iterated:
- Reset should reset the enumerator,;
- Current should fail if MoveNext was not called,
- MoveNext should fail if it is called after the last element, etc...
When you are implementing custom enumerator, this kind of test should be automated so you know your custom enumerator class has the expected behavior.
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|

|
Right.. In that instance, the behavior is part of the interface specification.
|
|
|
|

|
I was pondering something similar the other day. I brought up a WebControl in the VS designer and the whole think bombed out with a stack overflow exception. The source of the problem wasn't immediately obvious, and though a more through unit test would have found it the way I actually located it was to write a unit test that tested all the System.Web.UI.Controls in the assembly for basic 'control-ness' - ie that all their properties could be succesfully read straight after construction. There I found my problem (and incidentally a few others).
So the concept of interface testing applies to any 'interface', rather than just those with a capital I - ie any derived class always inherits some functionality from the base class that should also be 'regression' tested when the derived class is tested. This seems to suggest three things:
- Unit tests need to be distributed along with any class intended for derivation (or even just any non-sealed class)
- Unit testing frameworks need to have a mechanism for discovering unit tests that apply to base classes, and applying them to the derived class being tested
- 'Reference' / library tests for common class types should be more widely available.
Do we have a generally agreed on library for .net unit tests yet?
|
|
|
|

|
piers7 wrote:
a unit test that tested all the System.Web.UI.Controls in the assembly for basic 'control-ness' - ie that all their properties could be succesfully read straight after construction.
Hi, I have implemented a similar concept in my Unit library (GUnit) which tests types. However, it is different from yours because it asks the user to provide "initialize" instances of the type:
[TypeFixture(typeof(System.Web.UI.Control))]
public class ControlTest
{
[Provider(typeof(MyControl)]
public MyControl ProvideMyControl()
{
...
}
[Test]
public void SomeTest(System.Web.UI.Control ctrl)
{
...
}
}
Of course, we could further imporve this by letting the framework load entire namespaces...
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|

|
piers7 wrote:
Do we have a generally agreed on library for .net unit tests yet?
lots of folks are using, and nearly all extensions flocking to, NUnit...works great for me....
|
|
|
|

|
pholser wrote:
lots of folks are using, and nearly all extensions flocking to, NUnit...works great for me....
hehe. Every read Jonathan Livingston Seagull?
Marc
Microsoft MVP, Visual C#
|
|
|
|

|
Marc, this Jonathan Livingston Seagull story has a lot of "historical" conotation with me. In fact, my folks named me after this movie/book... but somehow my father swithched bird and started to call me "pelican" which later on became "peli", This is my "official" name now.
NUnit is in fact the dominant and most used unit test framework, (although csUnit is trying to get a grip on this too but I don't really the point, thought they do not bring anything new into the game).
Anyway, after sending a few message on the NUnit forums, the answers were really like: "our solution is the best, don't bother with inovative ideas". Fact is they are stuck in their minimalist design! Am-I the only one feeling Unit Testing needs "a kick in the butt". I mean, we are in the era of RAD, so logically you would hope to get tests generated automatically or do some more intelligent testing that what is proposed in NUnit.
NUnit has opened the eyes of many people to the power of Reflection and meta data but I'm sure there is much work to do here. For example, combining IL exploration, executaion graph, and CodeDom generation, a unit test framework should be able to generate "empty" test classes whith one method for each execution path. Therefore, the tester knows how much tests he has to write...
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|

|
Jonathan de Halleux wrote:
Am-I the only one feeling Unit Testing needs "a kick in the butt". I mean, we are in the era of RAD, so logically you would hope to get tests generated automatically or do some more intelligent testing that what is proposed in NUnit.
I totally agree. When I first looked at NUnit, I laughed my head off--it was like, come on, this is *all* that it does? And there's a community of people oohing and aahing over it? Unbelievable. And even worse, there was no semblence of bringing some formal engineering practices to unit testing. It reminded me of the days when us 15 year old kids would get together and yack about the latest cool technology without a clue as to what we were really talking about. But since NUnit has its roots in Java, I don't really expect much more *cough* intelligence out of the community.
(yes, I am biased. I'm trying not to be, but hey, if there's a platform, I'll stand on it until I'm shoved off of it!)
Jonathan de Halleux wrote:
NUnit has opened the eyes of many people to the power of Reflection and meta data but I'm sure there is much work to do here. For example, combining IL exploration, executaion graph, and CodeDom generation, a unit test framework should be able to generate "empty" test classes whith one method for each execution path. Therefore, the tester knows how much tests he has to write...
Absolutely. We're progressing in that direction with VTS. There's a few things on the todo list that are simple and are higher priority (like running unit tests automatically from the command line and unloading/reloading assemblies), but then it's on to forward engineering and things of that nature. Eduard on the AUT site has been making major contributions to VTS.
Unfortunately, I've been so swamped that I can't do much right now myself.
Marc
Microsoft MVP, Visual C#
|
|
|
|

|
No sorry, I meant a library for the *tests*, not the framework for running them.
Not (obviously) a library full of people's highly-specific unit tests, but the generic ones: reference test harnesses for classes inheriting from 'wellknown' bases like Control (Web / Windows) and Component for example.
(Put it this way, if you were writing a device driver, would you write your test harness from scratch, or use a standard one, and write specific tests for your specific functionality)
Now admittedly each test implementation has a degree of framework-specificity about it, but the underlying test code is normally fairly portable.
My original point was that as I started writing my generic System.Web.UI.Control test it occurred to me that a) someone must have written this before and b) if not I should probably post it somewhere
|
|
|
|

|
piers7 wrote:
My original point was that as I started writing my generic System.Web.UI.Control test it occurred to me that a) someone must have written this before and b) if not I should probably post it somewhere
a) I don't know any implementation.
b) GUnit (sorry about lamming with this) is built such that you can create your own fixture. Therefore, we can think about a fixture that creates a control, try to call each property and do that for all the properties. The framework can take care of separating each "property" call into 1 separate test. Is that what you are looking for ?
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|

|
http://www.placebosoft.com/abstract-test.html
|
|
|
|

|
Huh. Thanks for the link. I found another page on Testing Patterns. That's the first time I ever came across anything on test patterns. Must not good keywords for google to pick up.
Marc
Microsoft MVP, Visual C#
|
|
|
|

|
The example presented in this paper is easily implemented in GUnit without the hassle of inhereance. Moreover you can give multiple providers directly in the same class:
[TypeFixture(typeof(StatPack))]
public class TestStatPak
{
[Provider(typeof(SuperFastStatPack)]
public StatPack ProviderSuperFastStatPack()
{
return new SuperFastStatPack();
}
[Provider(typeof(AnotherSuperFastStatPack)]
public StatPack ProviderAnotherSuperFastStatPack()
{
return new AnotherSuperFastStatPack();
}
[Test]
public void testMean(StatPack statPack)
{
statPak.addValue(2.0);
statPak.addValue(3.0);
statPak.addValue(4.0);
statPak.addValue(2.0);
statPak.addValue(4.0);
Assert.Equals("Mean value of test data should be 3.0",
3.0,statPak.getMean());
}
}
Jonathan de Halleux.
www.dotnetwiki.org
|
|
|
|
|

|
You forgot some for Collection-Order -- reversed sequence of input, unsequenced, and reverse-ordered. I get the impression you were thinking of it in your description of the Enumeration pattern. You could argue that this is just an expansion on the test results you mentioned. I see this sort of test as useful for stack/queue implementations.
Examples
--------
input:
3 1 4 2
output:
1 2 3 4 (ordered, unsequenced)
4 3 2 1 (reverse-ordered, unsequenced)
3 1 4 2 (unordered, same)
2 4 1 3 (unordered, reverse-sequenced)
1 3 2 4 (unordered, unsequenced)
input:
4 3 2 1
output:
1 2 3 4 (ordered, reverse-sequenced)
4 3 2 1 (reverse-ordered, same)
1 3 2 4 (unordered, unsequenced)
As I see it, there are two primary results of the test: absolute ordering direction, and relative sequencing. What I've stated above just enumerates some of the values that could be returned.
Also, I would argue that the Collection-Constraint pattern would apply to mathematical sets generally, not just key-value pairs. It's just a realization that the set is equivalent to a collection of keys with ignored values. Nonetheless, you need not implement a value to ignore.
Overall, not the best of your work that I've read (proofreading, mostly.. see the " and ' mismatch, for example), but insightful nonetheless.
|
|
|
|

|
Keith Farmer wrote:
Overall, not the best of your work that I've read (proofreading, mostly.. see the " and ' mismatch, for example), but insightful nonetheless.
Yeah, I was tired and fighting a cold. I noticed some of the errors when I re-read it for the umpteenth time. I'll fix them tomorrow.
Thanks for the comments, BTW. This is rather undiscovered territory, as far as I can see. Maybe someone will provide some links to enlighten me.
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|

|
Once you derive them (or even use generics in next version of VS.NET) from tested base classes, what could possibly go wrong with range checks?
Tomaz
|
|
|
|

|
tstih wrote:
Once you derive them (or even use generics in next version of VS.NET) from tested base classes, what could possibly go wrong with range checks?
Well, if I understand what your saying, I guess the thing is that a derived class is performing some specialization, so at least those methods overridden by the derived class need to be re-tested.
I think some of the confusion also comes from how collections are used. I see a lot of cases where collections are passed around from class to class. This raises a lot of red flags, because if what the collection is managing needs to change, then a lot of other classes are affected. I prefer to manage all but the simplest collections by wrapping them in containers. This creates some extra work as I have to create a facade for the collection methods, but it sure has saved my butt on several occasions when suddenly I need a sorted list rather than an array (a trivial example).
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|

|
Also, if you're getting a collection from some source you don't control, but (as Marc suggests) your algorithm requires a sorted list, this is something that needs to be tested.
Perhaps your enumerator is something like an Enigma device, or some performs some other complex calculation to determine order, returning the next n solar eclipses viewable from Fiji at sunrise (don't scoff...). You need some means to determine that the output is as expected, and if it isn't, some diagnostics to provide clues as to what could be wrong with the ordering (sign reversal, poor assumptions about sorting, etc).
And there's another collection test: set differences. Granted, that should just be a function in the main Collection libraries, IMHO. It came in really handy doing my quantum mech homework in college.
|
|
|
|

|
do you find the time? That's all I've got to say! (Oh, nice piece BTW)
~Nitron.
ññòòïðïðB A start
|
|
|
|

|
Well said, Marc. Kent Roylance my friend and colleague pointed me to this article. First thing, I would like to say is that you really have some good original ideas and some of these patterns are probably being already used. I found that it would be useful if you give some examples on these patterns to elaborate their usage.
|
|
|
|

|
Krishna Patil wrote:
I found that it would be useful if you give some examples on these patterns to elaborate their usage.
Definitely. The article would have been way to big if I had done that though, and I wanted to have a fairly generic (non-language specific) article.
Marc
Latest AAL Article
My blog
Join my forum!
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
An Introduction To The Concept Of Unit Test Patterns
| Type | Article |
| Licence | |
| First Posted | 4 Jan 2004 |
| Views | 523,654 |
| Bookmarked | 340 times |
|
|