On Mon, Oct 26, 2015 at 8:27 AM, jtuchel@objektfabrik.de��<jtuchel@objektfabrik.de>��wrote:
Am 25.10.15 um 16:33 schrieb Peter Uhn��k:
I'm sorry, but what you are saying doesn't make any sense. Even if I "only" want to test code (which is exactly what you do in TDD, btw.), I need good feedback.��> assert:equals:�� it's just more typing than #= with no additional outcome
I also disagree, but that may be also because maybe we write tests for different purpse.If you write tests just to test your code, then whatever... I don't do that so I can't comment on that.
However if you do TDD, then tests are to provide feedback, and from that perspective you want to see immediately what is the difference. If I see that the assertion failed I have to start digging to find out what is the difference, which is extra work and bad from feedback perspective. If I instead immediately see what I need to see it allows me to faster deduce the source of the problem and resolve it.
Well, that was a bit of generalization on my part. The point was, that many people write tests as an afterthought... which means they have different means of getting feedback from the system (e.g. logging, running manually the code, etc.). In such situation they often end up testing already mostly working code, and thus the feedback from the tests is not as important, because you end up less digging up problems (since large portion were found and resolved during manual testing).
Well, I actually mean a new generation of #assert:description: that concentrates more on the #description: part. Remember: some assertion methods have been added as a way to provide "more suitable" feedback, like handing in an object or two to be mentioned in the description string. So the problem at hand wasn't that the standard assert: method was insufficient, just its output.��We could think about subclassing TestFailure and a way to hand information to the TestFailure so that a nice String can be produced. Like a method like cull: that adds arguments' printString representation into the failure description.��
You mean #assert:description: ? Because we already have that.��
Well, that is probably not really true for unit tests, because you may want to test something in a very specific way to prove your thesis about how to solve a problem is true under several circumstances.Please step back for a second and think again: these are two very different things. The job of an Assertion is to make a problem visible. The representation of the problem is something else, even if these are closely related. This is object thinking lesson #2 or so.
Object thinking lesson #3 tells me that I should not care about what is going on behind the curtains.
Convenience methods are not bad per se, as long as they add value and clearly communicate what they do. Pharo and other Smalltalks are stuffed with lots of bad examples here. Sometimes Convenience methods are a symptom of design problems or the lack of multiple inheritance. Sometimes they are just a good idea.And while I could explicitly separate the two, if I do it all the time I don't see what's bad about having a convenience method. (And by looking at Object or String protocol, Pharo is a lot about having convenience over engineering rigidness).
But: adding more and more misnamed and misleading assertion methods makes the use of SUnit frustrating and will make it obsolete over time. If I have to hunt for design problems in SUnit because it assumes something to be wrong even though my understanding of waht I tested is different, I lose way more time than I am ready to accept. This doesn't happen to me often. If finding that I misunderstood an assertion method means I lost a few hours, the best thing that may happen is that I never use that method again. In the worst case, I decide I think SUnit is useless for me. That would be really bad, don't you think?
I am not sure if we are talking about the same SUnit. Sure, there are 32 methods in the "asserting" protocol, however most of them are either opposites of one another "#assert: vs #deny:", or they provide some customization such has "#assert:description:", "#should:raise:" ... so if I count only meaningfully different methods the number 7 (not to mention that some of the methods are not even used). But if you have trouble understanding the purpose of seven methods, then the problem is on your end, and don't blame SUnit for it.
��> assertCollection:hasSameElements:> So, let's start by asking what the question really means. Does it mean that one collection is a subset of the other? What about ordering then? Does it mean both contain the same elements at the same position or just the fact that if they both were Sets contained the exact same elements. The question itself is not exact, so how could an answer possibly be?
There is no question about this method, since this is implemented in code there is nothing ambiguous. This method effectively converts both arguments to sets and compares them like that.
Sorry to say that, but this is ambiguity by design: you define hasSameElements: as "both result in the same Set". So the name of this assertion method is a great example of bad naming, IMO.
Yes, the naming is confusing. My point was, that instead of philosophizing about the meaning you can look at the code. Of course if you use the method for the first time (like I did), you will get burned by it (as I did).
This is not about how to test for something. Our discussion is about the question whether a certain wayto test something should be added to the framework or not. Is the test generic and important enough so that it should make its way into SUnit. And if it should be added, what is a good name for it, so that others find the method as the right thing to use for their purpose or will it disturb them in their proces more than it helps.I don't really care. If what you try t say is that the testing code can be ugly and long, then I agree. If you need tests like this very often and want something to make this easier, I understand and agree that some additions to SUnit can be helpful. But the way this has been tried so far seems completely wrong to me.��self assert: result asOrderedCollection asSortedCollection equals: (1 to: 10) asOrderedCollection
This is what I usually do now (although I convert to Array, not OrderedCollection, because the expected one is usually created by hand with #() or {} ).
How would you test it then? Some problem domains deal with certain kind of problems more than others and thus benefit more from appropriate assertions.
Phew. Thank you. I am glad we agree on this. So let's carry on with the SUnit related stuff.��
So what, again, was the point of naming a method after a general Collection class and use a question that is very unspecific? A Collection has the same elements as another does not necessarily mean they both result in the same set. Can we agree on that? All the question asks if all Elements in Collection A can also be found in Collection B. The method name states nothing more than that.��> Just a few weeks ago, we discussed something similar about the equality of two Collections. Endless discussions where people try convince others that their definition of equality and/or sameness is correct with no outcome.
I don't see a problem with that because collections truly can have different equalities based on the context and their purpose. And while you can call this rat poison, it effectively tells what kind of behavior you expect from the collections, which seems ok.
We agree that the method is badly named. (However what equality of two Collections means is context-dependent.)
Now I have you in the corner I want you in ;-)��My point here is that a general purpose framework like SUnit should be free of such debatable things. SUnit has to be reliable and understandable.
There is nothing wrong with providing some "plugins" for problems like Collections that make life easier.
It would be desirable to have more control over SUnit's feedback with little typing.
Well but we need a way to provide context for the assertion. If I could type less then I would be happier user, however currently I don't see a way how to make it more general (so I don't need to type) and more precise (it still understands context) at the same time.
No. For several reasons (based on how I interpret the names you provide as an example):So going back to your earlier suggestion with the class... you imagine something like this?self assert: a equals: b strategy: CollectionHasExactlyTheSameElementsAsAnotherAtTheSamePosition
let's put a check mark on this one. It was just an example1. #assertCollection:hasSameElements: is a bad name, because it treats arguments as sets, not generic collections
it could be renamed or removed (no code in Pharo itself uses it (only Spec, but the use there is wrong))
I think I made it clear that this will be a less than perfect solution that doesn't jump far enough
2. Providing selectors such as #assertCollection:equals: and similar just to get different description may not be the best idea, which leads to point 3
I am convinced this is the way to go. But I have no good answer to it. Just a spark for now.
3. An easy way to extend printing/assertions/plugins; but what would that look like?
Maybe#assert: a = b description: [ Diff collectionDiffBetween: a and: b ]
See above. Better than another assert:-variation, but still too heavyor#assert: a equals: b strategy: CollectionHasExactlyTheSameElementsAsAnotherAtTheSamePosition
orsomething else...
Peter
-- ----------------------------------------------------------------------- Objektfabrik Joachim Tuchel mailto:jtuchel@objektfabrik.de Fliederweg 1�� �� �� �� �� �� �� �� �� �� �� �� ��http://www.objektfabrik.de D-71640 Ludwigsburg http://joachimtuchel.wordpress.com Telefon: +49 7141 56 10 86 0�� �� �� �� ��Fax: +49 7141 56 10 86 1