June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joakim | The only time I ever did TDD was when I had to implement a really specific set of number and date format strings for a company, because the users were used to them. It was pretty natural for that. This format string x must take number y, and yield the string result z. Write a bunch of tests for those, take a step back, implement the format strings how you think they should work, and see if the tests pass. Unless I'm doing really specific "this input yields precisely this output" stuff, I won't ever bother with TDD. I often end up with "Test a little bit after" design. I think his point in the talk about objects taking on roles might map nicely to the way ranges were implemented. A object doesn't behave as a range because it inherits an interface, it behaves that way because it has the right stuff for it. Essentially, I think he's getting close to saying "statically-checked duck typing." Like all things, this is good *some of the time.* |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Cain | On Thursday, 20 June 2013 at 01:15:58 UTC, Chris Cain wrote:
> On Wednesday, 19 June 2013 at 23:44:29 UTC, Walter Bright wrote:
>[...]
> Ultimately, the "goal" of TDD is to have the programmer sit down and look at code from a USER'S (as in, user of the API) point of view _FIRST_. "Writing a test" as the first step is really just suggesting "as a user, how would you find it convenient to use this thing?"
Just left enough context to ask the following question, I hope I did not left out too much.
How does TDD then help how a user of my application will use the application UI?
This is the area where I usually make TDD evangelists go speechless in conferences, as they start to present ad-hoc solutions and end up changing subject.
--
Paulo
|
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On Wednesday, 19 June 2013 at 17:31:33 UTC, H. S. Teoh wrote: > On Wed, Jun 19, 2013 at 04:52:22PM +0200, bearophile wrote: >> irritate: >> >> >My feelings about TDD changed when I saw that talk explaining TDD >> >in the context of double-entry bookkeeping in accounting > Before methodologies like TDD could even begin to work, one has to > *solve* the problem at hand first -- analyse the problem, explore its > structure, invent an algorithm, then one can verify the correctness of > one's implementation with unittests. You have to already have an idea > about how things are going to work, before TDD can help you. For me, it is like this: TDD is rather similar to bookkeeping; design is similar to doing (or managing) businesses. While being (or having) a good bookkeeper will definitely help your business to perform, the reverse is not true: being the most careful accountant in the world does not mean that you will do successful businesses. |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Joakim | On Thursday, 20 June 2013 at 05:05:29 UTC, Joakim wrote: > I think their argument would be that if you're only interested in "classic algorithms" or "the best way" that is known, then you may not get much out of TDD. But if you're exploring the solution space and trying to come up with a design that emerges with use, as opposed to thinking up a complete design in your head and then simply implementing it, I think they'd say TDD is a good solution for that. Szymon mentioned uncle Bob earlier, I thought I'd see what he had to say about the design benefits of TDD. Here's an archived blog post he wrote about the benefits of TDD: http://web.archive.org/web/20120201002523/http://blog.objectmentor.com/articles/2009/10/08/tdd-triage From a design standpoint, he says you need to do all the usual up-front design, but that TDD will help you modify and iterate on your inevitably incomplete initial design quicker. |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paulo Pinto | On Thursday, 20 June 2013 at 07:36:41 UTC, Paulo Pinto wrote:
> ...
> Just left enough context to ask the following question, I hope I did not left out too much.
>
> How does TDD then help how a user of my application will use the application UI?
>
> This is the area where I usually make TDD evangelists go speechless in conferences, as they start to present ad-hoc solutions and end up changing subject.
>
> --
> Paulo
Sure. The user, in this case, isn't the user of your application. The "user" is the person using your API (other programmers). TDD has nothing to do with the visual design of your application and everything to do with the software engineering design. It's to help guide you to the answer to the questions "how should I define the behavior of this class/how should this class be used in practice?"
If your question is how to use TDD for UI, the answer is that you might use TDD for defining the interface to your UI API. But defining an actual UI using TDD is usually kind of awkward and I feel it's missing the point. I'm not saying I haven't seen it done, but typically what people do to "test first" UI designs isn't really what TDD was meant to do, I feel.
---
I guess the short answer is that TDD doesn't make sense to be used for that (IMO). Just like a knife can't be used to cook an egg. I suppose this is where the phrase "there is no silver bullet" should be put? :)
|
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 2013-06-19 23:19, H. S. Teoh wrote: > How do you write a test that covers "enough" cases for a sudoku solver? I don't know. I you're about to create a sum function and use TDD. 1. Create the test: auto result = sum(1, 2); assert(result == 3); 2. Implement: int sum (int a, int b) { return 3; } In the above case you obviously haven't enough cases in your test to assert that your implementation does what it supposed to do. This example is very simple compared to sudoku. -- /Jacob Carlborg |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paulo Pinto | On 2013-06-20 00:13, Paulo Pinto wrote: > The issue is not to test third party libraries, far from it. > > The problem is that you cannot mock them, specially if you rely a lot on > non virtual methods or pure function calls. Or on framework code that > calls your code back, after certain events happened in the system. I would only mock an external service that needs to be available online. I don't mock third party code. That would be insane. There's no limit. Should I mock the standard library? > To do that properly, you end up wrapping third party code into code that > can be replaced for unit tests execution, thus making the test effort an > herculean task. I have only had a few cases where I needed to mock. I have only done that in our Ruby on Rails project. I guess that's quite a lot easier since you can very easy replace any method at runtime. -- /Jacob Carlborg |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2013-06-19 23:54, Walter Bright wrote: > TDD strikes me as an ad-hoc way of constructing code, and is a poor > substitute for thinking about the problem as a whole. For example, I > don't really see how getting a square root function to pass its test > cases is going to lead one to implementing one of the classic algorithms > for computing square roots. I don't see how TDD for a compiler will lead > one to rediscover what is known about the best way to organize the logic > of a compiler. > > TDD is "curve fitting" which is what one does when one has no > understanding. I have not watch the video(s) but I think you completely failed to understand what TDD is about. This is how I think about TDD: 1. You have a problem to solve 2. You think about how to solve the problem and how a design can look like 3. You come up with a design 4. Write a test according to the design 5. Write the implementation 6. Run the test to see that the implementation matches your design 7. Repeat 2-6 until satisfied Example, write a compiler: Problem: Lex string literals Test: auto code = `"asd"`; auto token = lex(code); assert(token.lexeme == code); assert(token.type == Type.stringLiteral); Implementation: Write the implementation to pass the above test. Token lex (string code) { return Token(code, Type.stringLiteral); } This is obviously a dummy implementation but it's enough to pass the test. The you need write more tests that force you to implement the function correctly. Like below. Test again: auto code = `"foo""bar"`; auto token = lex(code); assert(token.lexeme == `"foo"`); assert(token.type == Type.stringLiteral); Fix the implementation to pass the above test. Test again: auto code = `"foo`; auto token = lex(code); assert(token.type == Type.error); // unterminated string literal Fix the implementation to pass the above test. Usually I write the test first and immediately write the "correct" implementation instead of these dummy implementation. Then I add some more tests which possibly will fail because I found an edge case I forgot to think about when I implemented the code. BTW, when you don't know how to implement something and you're trying your way forward. You can write proper tests instead of using printf or similar. -- /Jacob Carlborg |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Szymon Gatner | On 2013-06-20 00:23, Szymon Gatner wrote: > TDD claims to help with this by forcing you to code client code first > (the test) which arguably leads to better decoupling of components. You > don't have to split components for reuse later because they are already > being used in unrelated contexts in tests. This is a very good point. -- /Jacob Carlborg |
June 20, 2013 Re: TDD is BS? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 2013-06-20 01:44, Walter Bright wrote: > I just can't accept that. For one thing, implementation details often > must drive the interface. Just writing specs without any knowledge of > how it would be implemented will not produce an efficient design. > > For the square root, there's a definite tradeoff between accuracy and > speed. With no knowledge of those tradeoffs, and just coming up with a > spec, how can you make the right decisions? First, just because you have written a test doesn't mean you can't change it. Second, if you need on beforehand that solving this particular problem need to use a given algorithm which will require this certain API, then write your tests to match that. Otherwise, I would say, that write an API that is as straightforward and easy to use as possible. Then benchmark and profile your code and see where the implementation need to be change to satisfy your needs. If changing the implementation requires you to change the API, then do that and change the tests as well. And in the end, don't be so religious about these things and use your common sense :) -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation