views:

49

answers:

3

Today we have documentation and code implementation in the same file:

# @returns <String> A combined string
def say :this :that
   return "#{this} "{that}"
end

I have never seen unit testing in the same file like:

# @if_insert "good", "morning"
# @should_return "good morning"
#
# @returns <String> A combined string
def say :this :that
   return "#{this} "{that}"
end

I think all these three parts are better to be clustered at one place (but with better syntax than the above quick examples)

Isn't it better not divide the unit testing from the actual code implementation? I don't see any benefit doing so, just like we are not separating documentations from code implementations.

+2  A: 

Python has a very nice implementation which allows unit tests to be interspersed with documentation, called doctest.

Clojure also allows tests to be included in the source files by adding it to the function metadata:

(defn
  ^{:doc "mymax [xs+] gets the maximum value in xs using > "
  :test (fn []
          (assert (= 42  (mymax 2 42 5 4))))
  :user/comment "this is the best fn ever!"}
 mymax
 ([x] x)
 ([x y] (if (> x y) x y))
 ([x y & more]
   (reduce mymax (mymax x y) more)))

Personally I find that adding lots of test code in the production hinders readability. When tests become real logic more than simple calls then I prefer them to be separated

Peter Tillemans
+3  A: 

There are plenty of languages which allow tests to be embedded with the code. D, Cobra and Clojure come to mind.

The main problem with this is that unit tests test units of behavior, and a unit of behavior does not necessarily correspond to a unit of code. In other words, a unit test may only test half of a method, or two methods. Where do you attach that test?

Here is a stupid example of some Cobra code demonstrating language-integrated documentation, contracts and tests:

def sqrt(i as number) as number
    """
    square root of i
    """
    require
        i >= 0
    ensure
        result == i*i
        result >= 0
    test
        assert sqrt(4) == 2
    body
        # Imagine Newton-Raphson or something like that here ...
Jörg W Mittag
A: 

I think there's an important reason for separating test and implementation into separate files - we think better that way.

More precisely, we're better at writing tests that are real, independent and readable specifications when they are separate from the code. I don't think anyone can write the tests and not keep casting their eyes immediately to the code.

I'm not saying that unit tests should be written in isolation from the code, but I think there's a necessary separation.

I also hate introducing noise and a good unit test suit is going to create a lot more code than the code it is testing, which will make the core code harder to read for understanding. With a comprehensive suite, reading is not a linear experience but more of a hypertext or a graph - following from the tests back to the code to see what is being tested, and vice versa. Once you lose a one-one mapping between a code method and the test method(s) you need to separate them.

I suggest you read Doctest Considered Harmful.

Andy Dent
I do agree that doctests really only work for very simple functions, but I still think the *concept* still has potential.
TM
I put doctests in the same category as Literate Programming - it felt like it should work and I find it a really attractive concept but maybe the tools just aren't there yet. For example, what if we went beyond just the simple folding of Visual Studio at present, adding the ability to tag sections and fold and reveal things based on tags, not just one at a time. As an occasion tool developer and keen observer of them for over twenty years, I find the glacial pace of reform depressing :-(
Andy Dent