[Python-ideas] where statement in Pyret

Tarek Ziadé tarek at ziade.org
Mon Nov 11 10:10:26 CET 2013


Le 11/11/13 2:21 AM, Terry Reedy a écrit :
> ..
>
>> Having the ability to distinguish tests and regular code at the language
>> level has benefits like the ability to ignore tests when you run the
>> app in
>> production etc.
>
> Functions only run when called.
I would not say that. You often have meta-level code like class-level
bits or decorators, the interpreter will
read -- that will load stuff.

In other words, a program with tests functions in your code will be
different in memory that the same program
without tests functions.

>
> For my book, most example code consists of classical functions. For
> these, I am doing the following, adapted for your sum example. For
> didactic reasons, I like having the tests immediately follow the
> function code; the input-output pairs serve as testable documentation.
> (This code does not run at the moment as I am midstream in changing
> the test module.) The first and last statements are boilerplate that
> is part of a _template.py file.
>
> ----
> from xploro.test import main, ftest
>
> def sum_rec(seq):
>   if seq:
>     return seq[0] + sum_rec(seq[1:])
>   else:
>     return 0
>
> def sum_for(seq):
>   ret = 0
>   for num in seq:
>     ret += num
>   return ret
>
> def test_sum():
>   ftest((sum_rec, sum_for), (([], 0), ([1], 1), ([1,2,3], 6),) )
>
> if __name__ == '__main__':
>   main()
> ----
>
> ftest calls each function with each input of the input-output pairs
> and checks that the function output matches the output given.
> main scans globals() for functions named 'test_xxx' and calls them.
>
> Anyway, I prefer the above to the 'where' suggestion.
That's a good template indeed,

I have 3 remarks though:

1/ you are importing your test framework even if you don't run the tests.
2/ those are not pure unit tests, since test_sum() tests 2 separate
functions - but I guess this rule can be broken in this case.
3/ main() is an optional artifact from unittest - most developers your a
script that takes care of the test discovery (unittest2, nosetests, etc)

So I would rather write in plain python:

----

def sum_rec(seq):
  if seq:
    return seq[0] + sum_rec(seq[1:])
  else:
    return 0

def sum_for(seq):
  ret = 0
  for num in seq:
    ret += num
  return ret

def test_sum():
  from xploro.test import main, ftest
  ftest((sum_for, sum_rec), (([], 0), ([1], 1), ([1,2,3], 6),) )

----

Cheers
Tarek




More information about the Python-ideas mailing list