|From:||Brandon J. Van Every|
|Subject:||[Chicken-users] Re: Integrating unit tests into source code|
|Date:||Thu, 14 Dec 2006 15:41:44 -0800|
|User-agent:||Thunderbird 220.127.116.11 (Windows/20061025)|
Peter Bex wrote:
On Thu, Dec 14, 2006 at 04:45:11AM -0800, Brandon J. Van Every wrote:Some tests need additional code for support (setting things up in a particular way etc). Why would one want to put all that code (which may be twice as big as the code itself, or even bigger, if done properly) in one huge file? You do it if you want your code to actually work, and you think it's better to run the automated tests than to pay someone $XX/hour after-the-fact to show you your bugs.I know and understand why to use tests. I'm not opposed to tests, but I am opposed to lumping the tests in with the main code. I'd much rather just keep the code clean and put the tests in another file.
Well, I question why we have files. We have historical reasons for it; all of our text editors are built in terms of them. But a program is really just one big database of stuff, and it might make more sense to have it all uniformly accessed and searched, rather than being cobbled across a filesystem.
Thus I am saying, "why should it appear together" vs. "why should it appear apart," is pretty arbitrary and historical. If one regarded the program as a database, then either is just a view of the database.
Inline documentation is useful to the reader,
and so are contracts since they describe the specification a function should adhere to.
Only if those specifications are terse, legible, and universal enough to describe nearly any class of problem that needs specification. I have my doubts, but I haven't tried this paradigm. I suspect my eyes will glaze over, and that deciphering contracts isn't much better than deciphering simple tests.
Tests don't say shit. They're a very low-level and nonsemantic way of groping around to ensure your corner cases are covered.
Depends on the test. I think the comments are what help. I don't care what kind of code someone writes, it's gonna make my eyes glaze over.
Contracts are more semantic and declarative, so they tell you more about what type of input is expected.
Declarative styles are not panacea. Some problems are better specified imperatively. Sometimes you really want to know that "A happens, then B happens, then C happens" and it's easier to debug.
What would you prefer? (define/contract (+ a b) ((is-natnum a) (is-natnum b) (result-natnum)) (if (= 0 a) b (+ (sub1 a) (add1 b)))) (define/test (+ a b) ((throws negativeerror (+ -1 1)) (throws negativeerror (+ 1 -1)) (= 1 (+ 0 1)) (= 1 (+ 1 0)) (= 2 (+ 1 1)) (= 0 (+ 0 0)) (if (= 0 a) b (+ (sub1 a) (add1 b)))))
The latter. Because I'm probably implementing a bit twiddling optimization algorithm, and I need to know exactly what's happening as the code converts to machine instructions. When you state a preference for declarative interfaces, you are implicitly stating you don't want to be bothered with the implementation details. That you prefer abstract problems. Now that may have its place in various problem domains, but not typically in mine.
As you can see, proper testing often results in bigger code.
Bigger is fine. I'm interested in *clearer*. Declarative may be more terse, but that doesn't make it more clear. And for some problems, declarative makes it verbose, if you actually want A --> B --> C.
Brandon Van Every
|[Prev in Thread]||Current Thread||[Next in Thread]|