[Edu-sig] Game of Life in Sketchup; unittesting and TDD (pedagogy)

Kirby Urner kurner at oreillyschool.com
Tue May 10 03:46:24 CEST 2011


On Mon, May 9, 2011 at 6:06 PM, Corey Richardson <kb1pkl at aim.com> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 05/09/2011 07:11 PM, Kirby Urner wrote:
> > It's like doctest but different in that we're not showing interactions,
> > though we could be.
>
> I saw in #python that someone was working on making doctest even more
> useful, and having some of the features of unittest (and I believe he
> was working on running doctests from unittests). I don't mind doctest in
> smaller quantities, and sphinx makes it look good on the user-facing side.
>
> When I'm teaching newcommers I used to avoid testing until the last
> possible moment (even in my AP CS class we never once had to have formal
> tests for our code...) to cover it, and it was scanty. Now I usually
> teach mostly full TDD with the doctest module, and then show them
> unittest later on. I think it makes the docstrings look ugly, but
> testing is more important than aesthetics.
>
> my 2c,
> - --
> Corey Richardson
>

Seems a reasonable approach.  Likewise this OST curriculum sanely
begins with core basics, phases in doctest, then unittest.  The TDD
philosophy is well demonstrated and the author (SH) walks his talk.

However, I'm thinking to wedge something TDDish between doctest
and unittest that's just the engaged coder testing her own module in
top-level run mode (versus importing).  It's one of those delegating of
responsibility things that a module should have some standalone
behaviors to model / demo what it brings to the table.  To that end,
a structure like:

def _test( ):
    """ testing code goes here, TDD is your friend """

if __name__ == "__main__":
   _test( )

is considered "good to go".  How does this support the "write tests
first" philosophy?

Well, imagine having this class:

class Farm:

    def __init__(self, rows=8, columns=8, bg="*"):
        self.h = rows
        self.w = columns
        self.bg = bg  # background character
        self.tractors = []  # like Snake or Dog stomach
        self.field = [list(bg*self.w) for x in range(self.h)]  # model
        self.framenumber = 0
        self.trace = []

    def render(self):
        display=""
        for line in self.field:
            display += "".join(line)+"\n"
        return display  # view

    __str__ = render

    def __repr__(self):
        return "Farm({},{}) @ {}".format(self.w, self.h, id(self))

It basically builds an M x N array of stars, and now you want
to add the feature that you can peek or poke to that array
using a FORTRAN-like syntax i.e.

>>> myfarm = Farm(10,20)
>>> myfarm(3, 5) = "@"

will "plant" a "@" in row 3 column 5 of the data structure,
named self.field.  The coder would simply embed this expected
feature in _test:

def _test():
    myfarm = Farm(10,20)

    # before picture
    print(myfarm)

    myfarm(3, 5) = "@"

    # after picture
    print(myfarm)

It's clear to the coder what's expected, so there's the test.  Now
the goal is to add the minimum code to Farm that makes this work.

Example (continued):


class Farm:

    # << code already shown >>

    def __getitem__(self, key):   # from arr4.py
        "Returns the appropriate element for a two-element subscript tuple."
        r, c = key
        return self.field[r][c]   # from arr4.py

    def __setitem__(self, key, value):
        "Sets the appropriate element for a two-element subscript tuple."
        r, c = key
        self.field[r][c] = value

Run the module top-level, triggering _test, and do so again and again,
as contingencies and corner cases get tested.  Leave a representative
set of tests behind as evidence of your audit.  You may write a more
formal unittesting framework later, but there's no guarantee that's
something to release with the module.  The _test( ) function serves
as an "on board payload" while the unittest framework stays behind
"near the launch pad".

The goal is to put the learner in the role of Quality Assurance tester,
at least at first.  Eat your own dog food.  Keep the code to be tested
and the tester code together, but that doesn't have to mean doctest.

Kirby
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20110509/aff8f4c1/attachment-0001.html>


More information about the Edu-sig mailing list