Arc Forumnew | comments | leaders | submitlogin
1 point by Pauan 5024 days ago | link | parent

I would just like to point out that I love Python's doctest module. It lets you embed Python code in a docstring, which is then evaluated for correctness:

  def foo():
    """
      >>> foo()
      42
    """
    
    return 42
When you use doctest, it will look for >>>, evaluate it, then check if the result matches the expectation. It's great because:

A) it's really simple and easy to use

B) unlike prose, the documentation is actually evaluated, so it's kept up to date

C) provides documentation for how the program is expected to behave in various situations

---

In fact, I usually don't write unit tests for my JavaScript code, but I write doctests for my Python code all the time, simply because it's so darn easy to use.

What if you don't want to embed the tests in your code itself? You can also tell doctest to load and eval a file instead:

  # tests/foo

  >>> foo()
  42
Then in Python:

  import doctest
  doctest.testfile("tests/foo")
I'm using this approach in PyArc with great success, with hundreds of tests spread across 9 files. And the doctest module lets you embed prose/comments in the tests as well:

  # tests/foo

  The foo function is very very very complicated:

  >>> foo() # this calls the foo function
  42
Thus, it provides a way to easily document and write unit tests at the same time. Such a system is not necessarily competing with things like Javadoc, but instead could be used to complement them.

---

By the way, unit testing isn't exactly a new idea: aw already has a collection of unit tests written in Arc. The reason I like doctest is because it lowers the cost of entry as much as possible. Sure, you could use something like this:

  (testis (foo) 42)
But I think it's easier and clearer to use something like this:

  >>> (foo)
  42
Another difference is that you don't need specialized functions like test-iso, testnil, testt, catcherr, etc. It matches the printed output with the expected output:

  >>> '(1 2 3)
  (1 2 3)

  >>> nil
  nil
And it would work for errors, too:

  >>> (err "foo")
  error: foo
This isn't meant to be a slight on aw: most unit testing frameworks I've seen do something similar, including QUnit (which is what I use for JS). Even my own Arc unit tester that I quickly whipped together does it like that. But I like Python's doctest approach.