Keyboard Shortcuts
ctrl + shift + ? :
Show all keyboard shortcuts
ctrl + g :
Navigate to a group
ctrl + shift + f :
Find
ctrl + / :
Quick actions
esc to dismiss
Likes
- Testdrivendevelopment
- Messages
Search
Re: "bottom-up" TDD and common behaviors
If I understand correctly, the code here is specifically?for doing an Ecto transformation, correct? If you decide not to use Ecto the need for this abstraction is removed? brought to you by the letters A, V, and I and the number 47 On Tue, Dec 3, 2019 at 2:18 AM Brian Marick <marick@...> wrote:
|
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýTL;DR: For various reasons, I was trying to avoid the use of mocks in this app. I¡¯m asking how a particular problem would be nicely solved without them.? I should note that I have a guideline that a test should contain no words except those that highlight what¡¯s special about it - about what the test is *for*. ------------------ That represents one row from an `animals` table. It also represents two rows from a `service_gaps` table, specifically two rows with a foreign key that points at the animal.? Ecto is an Elixir structure-to-relational-table mapper. It¡¯s easy to ask it for the animal plus its service gaps, in which case it does all the appropriate joins and produces a structure that looks like this (with some fields stripped for concision): That looks different than what the form displays. Somehow, the nil `out_of_service_date` has been turned into the string ¡°never¡±, and the `span` structure in the service gap has been ¡°flattened¡± into two strings. That is, you could imagine that what¡¯s actually rendered is a derivative structure like this: If you imagined that, you¡¯d be wrong. Ecto really wants you to put the actual database fields and also the ¡°virtual¡± fields that hold form values into a single structure that looks like this: ***Whether it's a good idea for a database mapper to know a bunch of things about how the client works is NOT at issue here. Ecto is what it is.*** When you read an animal from the database, it comes back as the previous structure with the three highlighted lines set to `nil`. That¡¯s suitable for lots of operations on animals, but it¡¯s not suitable for producing a form that can be readily used to update an animal and its service gaps. For that, you need to derive the appropriate values for the highlighted fields (fill them in as shown). Once you do that, it¡¯s *really easy* to write code that takes the result of an HTTP POST and updates the database: atomically applying all the changes from the form data, including creating a new ¡°service gaps¡± row. (The rather grotty data structure makes for simpler code, which is why I still don¡¯t know what to think about the design of the Ecto library.) So let¡¯s consider a function that converts an animal `id` into an initialized form. That function is called when a user clicks on a table element like this: ¡ and it produces an `Animal` structure like the one above. Here¡¯s an implementation of that function: It has two responsibilities:? 1. Fetch the corresponding animal in the normal way, including the associated service gaps (etc.)? 2. Augment that data to make it suitable for a form. In a mockish approach, I¡¯d TDD that with pseudocode like this: ? ?updatable(5, ¡°test¡±) produces `..result..` ? ?provided ? ? ? ?Read.one([id: 5], ¡°test¡±) produces `..animal..`, and ? ? ? ?Read.put_updatable_fields(`..animal..`) produces `..result..` (The `..animal..` notation is for what I call ¡°metaconstants¡±, which are values about which nothing is known except their name and that two instances of the same name refer to the same value. My Midje library for Clojure has metaconstants built in, so you *can¡¯t* do anything else with them. In a dynamically-typed language, it¡¯s easy to use strings or symbols for the same thing. Static typing makes metaconstants much harder.) I like this test because it doesn't set up specific animal data that gets checked for facts that *imply* that updatability was handled correctly. It says it directly: ?¡°An updatable animal N is an existing animal that¡¯s read and then modified to be updatable¡±. I like to think of such tests as being like proofs that use lemmas: *if* animal reading works correctly, and making an animal updatable works correctly, then fetching an updatable animal is works correctly.? (That is, I¡¯m working at the conceptual level, not the implementation level, so the ¡°you¡¯re just testing implementation¡± argument against mocks doesn¡¯t apply. After all, *shouldn¡¯t* our implementations be structured around relevant concepts?) However, for various reasons, I was trying to avoid the use of mocks in this app. So, if you were doing this in a non-mockish way, what tests would you have? (Remember, there are four functions that do pretty much the same thing.) |
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýWe still don't know the context, but it seems like we have some kind of a thing that either has fields that are sometimes mod and sometimes not, or sometimes has mod fields added to it. That could be built in lots of interesting ways, as with an adapter that covers up the fields making them unmodifiable, or a partner object adapter that knows the secret handshake.My basic approach would be to ask the question I want to know the answer to, roughly, "are those fields modifiable", and then let the code tell me more about the implementation. If that question became more complex to answer, that might be just fine. Without building the thing, I cannot know.?
Ron Jeffries Perfectionism is the voice of the oppressor -- Anne Lamott |
Re: "bottom-up" TDD and common behaviors
What motivates implementing a setter method under TDD unless there is a test that requires it to exist and work?? Extra tests would only be required if we also need to implement is<X>Modifiable() for some field X. On Mon, Dec 2, 2019 at 12:26 PM Ron Jeffries <ronjeffriesacm@...> wrote:
|
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýIf we're gonna be like that, wouldn't you need a test for every modifiable field? :)
Ron Jeffries Master your instrument, master the music, then forget all that shit and just play. -- Charlie Parker |
Re: "bottom-up" TDD and common behaviors
Just because an object has a method implemented to "know" whether or not a field is modifiable?does not mean that that method is correctly implemented.? If there is such a method, you would still have to have at least two tests that verifies returns true only when that field is actually modifiable and false only when it is not.?? Unless the application itself needs such a method, I would have a test that gets the fields value, sets it to a different value, and gets the field value to verify it changes. On Mon, Dec 2, 2019 at 6:30 AM Ron Jeffries <ronjeffriesacm@...> wrote:
|
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýYes. And if I didn't mind modifying a field, testing it that way is OK.If I knew the context I'd have a better idea but as it stands I'm thinking my object must know whether it can modify fields or not. I suppose a modifyField operation might return T/F ... R
Ron Jeffries If it is more than you need, it is waste. -- Andy Seidl |
Re: "bottom-up" TDD and common behaviors
Best to test to behaviour, not implementation/capability, I think. brought to you by the letters A, V, and I and the number 47 On Mon, Dec 2, 2019 at 2:33 PM Ron Jeffries <ronjeffriesacm@...> wrote:
|
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýI was thinking I'd ask the object if it had updatable fields, but it'd depend on an understanding of the problem and solution that I don't presently have.
Ron Jeffries If another does not intend offense, it is wrong for me to seek it; if another does indeed intend offense, it is foolish for me to permit it. ? -- Kelly Easterley |
Re: "bottom-up" TDD and common behaviors
The way I test if animals have updatable fields, I try to update a field and check that it updated. Alan Baljeu alanbaljeu@...
On Sunday, December 1, 2019, 07:16:01 p.m. EST, Brian Marick <marick@...> wrote:
What I¡¯m guessing is that you invent an assertion that, when true of the return value, implies that it has been made ¡°with updatable fields¡±. So it¡¯s a property of the data rather than a property of how it was created. Yeah, that probably makes sense. Forget I asked.
|
Re: "bottom-up" TDD and common behaviors
¿ªÔÆÌåÓýWhat I¡¯m guessing is that you invent an assertion that, when true of the return value, implies that it has been made ¡°with updatable fields¡±. So it¡¯s a property of the data rather than a property of how it was created.Yeah, that probably makes sense. Forget I asked.
|
"bottom-up" TDD and common behaviors
Here¡¯s some code I have:
Here¡¯s a correctness claim about that code: ¡°any function that returns one or more Animals must ensure that those animals have ¡®updatable fields¡¯¡±. I come from a mockish tradition, in which that claim would be stated directly by an assertion that `put_updatable_fields` would be called and be used as the return value.? I¡¯ve been trying to do non-mockish testing in this app, and I¡¯ve gotten myself all bollixed up. Without mocks, what would tests for these four functions look like? I think I once knew the answers to such questions, but I can¡¯t remember them. |
Re: REQ: Moderators
Thank you, everyone, who volunteered. I think we have enough for now.
You who have become moderators will notice new emails notifying you of messages waiting for approval. View them online, where you will easily be able to approve the messages and remove the poster from moderation OR reject the messages and possibly ban the poster. If anyone notices that messages stay pending for several days, then we need more moderators. In that case, just say so. :) Thank you! -- J. B. (Joe) Rainsberger :: :: :: Teaching evolutionary design and TDD since 2002 |
Re: "Find or Create" functions: a discussion
I have a system that is doing this part of the time.? It is fraught with problems when doing the search.? In your case, searching for "John Smith" may return a set of records, while the creation is creating a record which needs some unique identifier for the real John Smith you want to add to the database.? Even just using first name and last name , or partial of SSN , etc? makes for complicated code for what keys you are going to use , are those keys also using SOUNDEX() feature of SQL ?? For those who will follow you, just make it classical CRUD application without mixed or confusing methods or functions.?
|
Re: REQ: Moderators
Hi J.B. If you still need moderators, then I'll volunteer?to help.? Let me know what?you need me to do. Thanks, Rick On Mon, Nov 25, 2019 at 8:07 AM J. B. Rainsberger <[email protected]> wrote: Hi, folks. |
Re: REQ: Moderators
Guilherme Froes
I volunteer! -Guilherme Froes Em seg., 25 de nov. de 2019 ¨¤s 10:07, J. B. Rainsberger <[email protected]> escreveu: Hi, folks. |
Re: "I think the community needs more explicit direction...."
On Mon, Nov 25, 2019 at 10:22 AM Steve Gordon <sgordonphd@...> wrote:
?? So is education a lost cause? Surely not. I hope not! Are we trying to "educate" too quickly? Should we provide more time for students to read, try some problems on their own, and then and only then provide lectures to help cement their understanding? Today we do it backward and students, in my opinion, are encouraged to memorize by the presentation format. There is no time to internalize any information and then tests reinforce the notion that memorization is the best approach. Are we really preparing students for their future this way? What are other countries doing? Are we seeing the same behaviors outside the US as well? |
Re: REQ: Moderators
Also happy to help. On Mon, 25 Nov 2019 at 13:07, J. B. Rainsberger <[email protected]> wrote: Hi, folks. |
Re: "I think the community needs more explicit direction...."
On Mon, Nov 25, 2019 at 11:07 AM Edwin Castro <egcastr@...> wrote:
When I was a professor, all I taught was problem solving.? Students hated it because they could not just memorize terms for my tests, and the student evaluations reflected it.? Grading also took a lot of time away from research because unlike my fellow professor's multiple choice tests, I actually had to read my student's solutions.? It was a lose-lose for my academic career.?? The invention of the automatically graded, multiple-choice test is what lead to the slow erosion of American education.? Not everything should be automated. |
Re: "I think the community needs more explicit direction...."
¿ªÔÆÌåÓýSince the busy days of this list all those years ago I¡¯ve retired, but I still code in partnership with my son. He¡¯s fairly receptive to the idea of TDD, less interested in the refactoring part. He doesn¡¯t like reading either. The way we work usually is that he explains some functional requirement and I create a library ¨C nicely TDD¡¯d of course. He¡¯s dabbled with TDD but usually he¡¯ll just jump straight into code. ? To be fair, he works at the visual interface end, the UX. And has produced some interesting stuff with front-ends such as Unity. ? Nice to see all these names in my inbox again ? ? John D. |
to navigate to use esc to dismiss