Keyboard Shortcuts
Likes
- Testdrivendevelopment
- Messages
Search
paper: Test-Driven Development Benefits Beyond Design Quality: Flow State and Developer Experience
Hey everyone,
Some months ago I asked for help in the group and some of you gently answered my survey; now the research paper is out! You can check the preprint here And I will be glad to discuss future work and evolutions of what is discussed here. Merry Christmas, Pedro Calais |
Re: Survey: Impact of TDD on developer's productivity and well-being.
I've not taken the time to look at the survey - sorry. However I did think the OP might be interested in a recent item from?Christiaan Verwijs:?
BTW Christiaan has been doing survey work towards his PhD for some years. Cheers Mark - a human |
Re: Survey: Impact of TDD on developer's productivity and well-being.
What do you mean by polarization? I went on your personal page and discovered you've worked on polarization, biases and misinformation. Like Steve I was surprised by the content of the survey oriented "feelings" and wondered if your goal was to measure how biased tdd practioners are or something like that. Practicing tdd or not, polarize dev because it's hard to have tdd practioners and non-practioners working on the same source code. Also I think, but I may be wrong, once you've been in tdd, you won't go back to writing tests after or no test at all.? I don't want to talk for others so personnaly, I'd immediatly refuse a project where I won't be able to do tdd (among other practices, this one is mandatory) It might seem an extreme position that might have interests for research. Regards,? Gregory |
Re: Survey: Impact of TDD on developer's productivity and well-being.
Software development is a people problem, not a technical problem.? Understand that you are actually researching people and how they work, so do not ignore hundreds of years of social science research techniques.? On Tue, Sep 13, 2022 at 10:08 AM Steven Gordon <sgordonphd@...> wrote:
|
Re: Survey: Impact of TDD on developer's productivity and well-being.
However, if you survey the people you observe, then you have something useful.? If you are not doing observations of how people are actually working, it?does not matter what your other dimensions are because it is divorced from reality,? Most people do not actually know how they work and/or answer?survey questions based on rationalizations.? Involve at least one real social scientist in your research group to avoid wasting your efforts. Uncontrolled surveys are not just limited - they are deceptive and can easily move your research in a useless direction. On Mon, Sep 12, 2022 at 4:54 AM <pedro.calais@...> wrote: Hi Steve! |
Re: Survey: Impact of TDD on developer's productivity and well-being.
Hi Steve!
I see your point on the limits of surveys; that's why this is just on of the 3 dimensions we are looking at! And I think the survey is probably the weakest evidence due to the reasons you just pointed out... I think it has its value as a complement though. This may be a nice read: Survey Guidelines in Software Engineering: An Annotated ReviewPedro |
Re: Survey: Impact of TDD on developer's productivity and well-being.
Sorry, but as a retired academician and developer, such "promiscuous" surveys are totally worthless as a research tool.? No control for biases, especially self-selection biases.?? Please, work directly with software development organizations to observe what people do instead of what they say they do, and then survey only?the people you observe.? Why do computer scientists have no knowledge of social science research precepts? On Sat, Sep 10, 2022 at 3:14 PM <pedro.calais@...> wrote: Hey folks, how are you? |
Re: Survey: Impact of TDD on developer's productivity and well-being.
Hi Pedro, Is this work related to polarization ? Would you share with us your results ? Regards, ³Ò°ù¨¦²µ´Ç°ù²â Le dim. 11 sept. 2022, 00:14, <pedro.calais@...> a ¨¦crit?: Hey folks, how are you? |
Survey: Impact of TDD on developer's productivity and well-being.
Hey folks, how are you?
I am a member of a group of researchers interested in studying the impact of testing practices on developer's productivity and well-being. ?
Our goal is to improve the software engineering community understanding on how and why practices such as unit testing and test-driven development are effective beyond the impact on code design.
?
If you are willing to help, we have 12 quick questions to you!
Best, Pedro Computer Scientist P.hD. |
Re: Please critique this TDD flow
On Thu, Jul 7, 2022 at 10:16 AM Matteo Vaccari <matteo.vaccari@...> wrote: Hi Mike, I have a similar impression. You will probably notice, if you continue this way, that you will eventually be duplicating a lot of silly details about GraphQL in your tests, even though the code you write ends up being mostly plain JavaScript to make the new tests pass. At some point, you might decide that this feels wrong somehow and it would help you to isolate the plain JavaScript behavior from the GraphQL parts. This would make the tests simpler and execute more quickly, which improves your feedback loop and helps you change the "core business" behavior more easily.
Again, I agree that this will probably eventually happen. The same advice applies: if you continue by putting everything in one place, then eventually you'll notice that some of your tests have copy/paste duplication of distracting details, and if you separate these three bits of behavior into separate pieces, then the distracting details go away and the remaining details feel much more relevant and meaningful. I interpret this as a good sign, generally. Good luck. J. B. (Joe) Rainsberger :: ?:: :: -- J. B. (Joe) Rainsberger :: :: :: Teaching evolutionary design and TDD since 2002 |
Re: Please critique this TDD flow
Hi Mike,
?
my first impression is that you have some interesting logic that is now coupled to your GraphQL engine.? Are you sure you want this?? Since the business logic around your use case might be non-trivial, then implementing it all in GraphQL could be non-trivial and the resulting code might by hard to change.? It's all fair if the logic is very stable and you need every drop of performance.? An alternative way would be to query GraphQL for the minimal set of data that your logic needs to make a decision, and then implement the interesting business logic in a separate function, that is pure and synchronous.
?
I also question whether you really want a single function that does querying, business logic, and saving an updated state on the DB.? Perhaps you would be better served by 3 separate functions.
?
Hope this?helps a bit,
?
Matteo |
Please critique this TDD flow
I have a domain entity called a "Booking Window" that has a Start Date and End Date, and defines a period in which a Member can make a Booking.? The business is a mobile car wash, and Members can book a wash every 14 days.
I have a means of establishing the first Booking Window - at the point of the Member signing up.? Now I feel like the next most useful function is one that finds all Booking Windows closing "today" and makes new ones. So I wrote a test like this (kinda pseudo coded) test("nothing to do when no booking windows at all", async () => { ? ? const client = stubGraphQlClientContainingNothing() ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(0) }) export async function makeTodaysBookingWindows(client: GraphQlClient, clock: Clock): Promise<BookingWindow[]> { ? ? return [] ? } test("nothing to do when no booking windows end today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(tomorrow())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(0) ? }) test("create a new booking window when one expires today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(1) ? ? expect(window[0].startDate).toBe(today()) ? ? expect(window[0].endDate).toBe(today() + 14 days) ? }) test("create a new booking window for every window ending today", async () => { ? ? const client = stubGraphQlClientContaining(bookingWindowEnding(today()), bookingWindowEnding(today())) ? ? const clock = new FixedClock(new Date()) ? ? const windows = await makeTodaysBookingWindows(client, clock) ? ? expect(windows).toHaveLength(2) ? ? expect(window[0].startDate).toBe(today()) ? ? expect(window[0].endDate).toBe(today() + 14 days) ? ? expect(window[1].startDate).toBe(today()) ? ? expect(window[1].endDate).toBe(today() + 14 days) ? }) |
Re: Subclass to Test in JavaScript?
Here are two techniques for injecting a dependency using the previous example with minimal modification: 1. A function that returns the Product function // the "real" production price logic function calculatePrice(sku, quantity) { ... } // Sort of a "constructor constructor" that allows // injecting alternate implementation function makeProduct(calculatePrice) { ? return function Product(sku) { ? ? let quantity, sku; ? ? return { ? ? ? setQuantity(val) { ? ? ? ? quantity = val ? ? ? }, ? ? ? getPrice() { ? ? ? ? return calculatePrice(sku, quantity) ? ? ? } ? ? } ? } } // in production, use the "real" implementation const Product = makeProduct(calculatePrice) // in test, something like: const TestProduct = makeProduct(calculatePriceTestDouble) 2. Optional argument with default value function calculatePrice(sku, quantity) {...} // default argument value that is overridable function Product(sku, calculator = calculatePrice) { ? let quantity, sku; ? return { ? ? setQuantity(val) { ? ? ? quantity = val ? ? }, ? ? getPrice() { ? ? ? return calculator(sku, quantity) ? ? } ? } } // in production, the default arg is used const realProduct = Product('abc-123') // in test, override const testProduct = Product('abc-123', calculatePriceTestDouble) On Fri, Jun 10, 2022 at 5:16 AM J. B. Rainsberger <me@...> wrote:
|
Re: Subclass to Test in JavaScript?
On Tue, Jun 7, 2022 at 5:23 AM Avi Kessner <akessner@...> wrote:
This is what I had expected to do, but since I was working with methods that changed the state of variables closed inside the object... I was just very very wrong about the whole thing. ?
Ooh. Can you throw together a quick example of that? I'm not _quite_ getting it yet. J. B. (Joe) Rainsberger :: ?:: :: -- J. B. (Joe) Rainsberger :: :: :: Teaching evolutionary design and TDD since 2002 |
Re: Subclass to Test in JavaScript?
On Sun, Jun 5, 2022 at 1:42 PM Dave Foley <davidmfoley@...> wrote: ?
Indeed, this was the conceptual mistake I made on stage. I was overriding a method that queried a closed variable in the SUT and simultaneously expecting the underlying value to change later. It was a mess and I hope I was just tired. :P
Thank you for confirming this. I think I understand better now. J. B. (Joe) Rainsberger :: ?:: :: -- J. B. (Joe) Rainsberger :: :: :: Teaching evolutionary design and TDD since 2002 |
Re: Subclass to Test in JavaScript?
I looked up Subclass to Test here,? and I'm still not sure if I'm understanding the use case correctly... However.? One thing I like about JavaScript is the ability to just replace a function or property on an object with another one. I do this alot with reporting code.? const oldLog = console.log console.log = myNewFunction .... console.log = oldLog? This lets me do some quick mocking for just a subsection of object without having to replicate everything.? The other thing we sometimes do is extract a new function which returns the function we are working on, and then allow our outer function to modify or provide some context variables.? And lastly, we might refactor a module and what it exports and requires to modify dependencies that go in or out.? On Sun, 5 Jun 2022, 15:42 J. B. Rainsberger, <me@...> wrote:
|
Re: Subclass to Test in JavaScript?
Sadly Dave is right here - the contents of a closure are, well,
toggle quoted message
Show quoted text
closed. Hence the name. Luckily Crockford's Module Pattern is a rare sight these days, I can count on the fingers of one mouse the number of times I've seen it in the wild in the last ten years. These days the focus tends to be far more on 'faux-O' Javascript, 'Haskell-wannabe Typescript', or some functional-style code that looks like a mashup of Clojure, Ruby & Absinthe. If the Module Pattern _is_ your problem, then a refactoring like 'extract method to helper object' is a reasonable choice, and the path you'd take would be very similar to that in a typical OO language environment. Fox --- On Sun, 5 Jun 2022 at 17:42, Dave Foley <davidmfoley@...> wrote:
|
Re: Subclass to Test in JavaScript?
I don't believe that using the prototype chain quite accomplishes what is being asked for. "Objects, but not classes" implies the usage of closures to encapsulate data, and I *think* that what is being asked for is to have access to the bits that are "closed" similar to how one might?access protected members in a class in java. The?closed values are not accessible to "subclasses" on the prototype chain. I'm imagining that the legacy code you are talking about is structured something like?this: // a function that returns an object function Product(sku) { ? // these values are "closed" aka "private" ? let quantity, sku; ? // this is also "private" / closed ? function calculatePrice() { ? ? ?// ... some logic here that we want to either: ? ? ?//? ?1. test directly or? ? ? ?//.? 2. stub to allow us to test other parts of this object ? ? ?// this function's behavior depends on the closed values ? } ? // the object returned ? return { ? ? setQuantity(val) { ? ? ? quantity = val ? ? }.? ? ? getPrice() { ? ? ? calculatePrice() ? ? } ? } } In this case, there is not?a good way to get access to the "innards" without modifying the SUT. On Sun, Jun 5, 2022 at 8:41 AM Sleepyfox <sleepyfox@...> wrote:
|
Re: Subclass to Test in JavaScript?
Hi JB, This is trivially simple in JS, simply create a new object (your "subclass to test") that has its prototype set to your SUT object. All of your SUT methods and attributes will now be accessible in your child object. Simples! --- a = { ? f: (x) => x + 1, ? z: 2 } b = {} b.__proto__ = a console.log(b.z)? ? ?// 2 console.log(b.f(4))? // 5 On Sun, 5 Jun 2022, 13:43 J. B. Rainsberger, <me@...> wrote:
|