473,399 Members | 3,656 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,399 software developers and data experts.

Creating module skeleton from unit tests


Greetings, fellow Pythonistas!

I'm about to create three modules. As an avid TDD fan I'd like to create
typical 'use-cases' for each of these modules. One of them is rather large,
and I wondered if it would be easy enough to create a code skeleton out of
unit test module.

Consider the following, though contrived, unit test code snippet:

================================================== ========================

import player

class TestClass:

def setup_method(self, meth):

self.obj = player.Player('Fred the Adventurer')

def test_name(self):

assert self.obj.name == 'Fred the Adventurer'

def test_inventory(self):

# player always starts with a dagger
assert self.obj.inventory == {'dagger': [(1, 4)]}

# dagger is an initial weapon
assert self.obj.weapon_type == 'dagger'

# add sword to player and wield it
self.obj.add_item('sword', (1, 8))

# wield the first sword in the backbag
self.obj.wield('sword')

assert self.obj.weapon_type == 'sword'

assert self.obj.inventory == {'dagger': [(1, 4)], 'sword': [(1, 8)] }

def test_level(self):

cur_level = self.obj.level

self.obj.level_up()

assert cur_level + 1 = self.obj.level

def test_hitpoints(self):

start_hp = 30
sword_damage = 6

assert self.obj.hitpoints == start_hp

self.obj.damage(sword_damage)

assert self.obj.hitpoints == start_hp - sword_damage

================================================== ========================

Now it would be nice if I could do

$ python test2skel.py test_player.py

$ cat player.py

class Player:

def __init__(self, str): # constructor was called with a string,
# so we create init with str arg

# self.weapon_type was compared to string and no parenthesis were
# used, so the best guess is it's an attribute

self.weapon_type = None

# ditto for inventory, name and hitpoints

self.inventory = None

self.name = None

self.hitpoints = None
def add_item(self, str, tpl):
# add_item() was called with a string arg and a tuple

pass

def damage(self, obj):
# damage() was called with an argument

def wield(self, obj):
# wield was called with an arg

def level_up(self):
# level_up() was called without args
Now I'm thinking of at least three possible ways to implement that, all of
which may not be very sensible, but what I could come up with:

1. Try to run the test case and capture exceptions. Trying to import player
and failing means there is no module player.py. The script could create a
file player.py. Running the tests again imply there's an attribute Player
which seems like a method call or class (both are 'called' in the same
way). Nothing is created, but an ambiguous state is set for Player: it's
either a class or module method. Later calls for Player instance remove the
ambiguity and then we know it's a class, and as such the class skeleton
is created. Proceeding this way a skeleton could probably be created by
catching Import/Attribute errors and so forth.

2. Parse the test cases module as Python code, and extract all possible
information therein. Probably the best-working method, but needs Python
parser and some serious semantic logic. Probably the most obvious but also
hardest(?) way to do it.

3. Parse the test case as a text file, and extract only necessary
information. Eg. creating needed module files is probably very easy: for
practical purposes, you could just grep "import <modlist>" and "from
<module> import <classes/method>" to find out what module files need to be
created. Hackish and not elegant but would probably work for custom
purposes well enough (especially if we restrict ourselves to only lines
starting with 'import module' statements in the test module). However,
eg. associating an instance method call with the class used in object
creation would be quite hard, if the parser is just a simple one.

4. Use a completely different approach, eg. create a module skeleton using a
custom markup (easily generated from many graphical design tools) and use
that for creating both the test skeleton and module itself. However, it
wouldn't be TDD because then you'd be designing the module the usual way

Also remember that the program wouldn't need to be very clever. A strict
coding standard can be assumed, and eg. the fact that all classes are in
CamelCase would help in deducing whether foo.Bar() is a method call or
Bar-class object instantiation (methods are always lower_case_with_underscore,
according to PEP 8 we try to follow).

What do you think? I know that probably the best way to go on is just do it
the old way (ie. code both the test and module by hand), or look for more
intelligent IDEs.

For what it's worth, I still use most recent XEmacs for coding because it is
just so handy in many areas - sometimes I miss Eclipse-like IDE and I have
even tried pydev for Eclipse (which is a good plugin, btw!), but to this day
I've went back to XEmacs every time because in the end I've always been
lacking something I couldn't find a decent substitute for.
Obligatory note: According to the XP folks, TDD is not as much about testing
as it is about design: "Test Driven *Development*" or maybe even "Test Driven
*Design*". The problem can be solved more easily if you design the module
skeleton first, then the tests and then the logic for the skeleton
- you would be creating tests before the code, but many people wouldn't regard
it as TDD then.

--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!

$_ = '456476617264204d616a616b6172692c20612043687269737 469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";
Jul 18 '05 #1
4 2716
Edvard Majakari schrieb:
Greetings, fellow Pythonistas!

I'm about to create three modules. As an avid TDD fan I'd like to create
typical 'use-cases' for each of these modules. One of them is rather large,
and I wondered if it would be easy enough to create a code skeleton out of
unit test module.
I think this is too difficult, because there are many ways to write
code (even skeletons) for a use case. An easier approach would
be to write the skeleton manually, embed the test cases in the doc
strings and generate the test code from the doc strings. If I
remember correctly IBM has published something to generate unit
tests from code. Python has a doctest module to support testing
derived from doc strings. This can be combined with unit tests.
The problem can be solved more easily if you design the module
skeleton first, then the tests and then the logic for the skeleton
- you would be creating tests before the code, but many people
wouldn't regard it as TDD then.


You shouldn't care if your approach works for you.

--
-------------------------------------------------------------------
Peter Maas, M+R Infosysteme, D-52070 Aachen, Tel +49-241-93878-0
E-mail 'cGV0ZXIubWFhc0BtcGx1c3IuZGU=\n'.decode('base64')
-------------------------------------------------------------------
Jul 18 '05 #2
I think that the best approach I saw to this was in the Eclipse java
ide... You can basically go on the declaration of

self.obj = player.Player('Fred the Adventurer')

press Ctrl+1 and it adds a suggestion to create the class Player.

Then go to

assert self.obj.name == 'Fred the Adventurer'

press Ctrl+1 and it adds suggestion: Declare field name in class
Player... and so on for methods... (true, you still have to go and
press some Ctrl+1s, but that should be fairly easy, especially if you
had some hints on what is missing... Python has a very dynamic nature,
but most of it can still be done...

I think that most Python IDEs are still not in the same level, but some
day they might get there...
Being the maintaner of PyDev (http://pydev.sf.net), I think it will get
there someday, true, lots of work to make it happen, right now only few
things in Ctrl+1 are available like that (still, some already are)...
and that's the way things work... nothing's always perfect (but at least
they evolve).

Regards,

Fabio
Peter Maas wrote:
Edvard Majakari schrieb:
Greetings, fellow Pythonistas!

I'm about to create three modules. As an avid TDD fan I'd like to create
typical 'use-cases' for each of these modules. One of them is rather
large,
and I wondered if it would be easy enough to create a code skeleton
out of
unit test module.

I think this is too difficult, because there are many ways to write
code (even skeletons) for a use case. An easier approach would
be to write the skeleton manually, embed the test cases in the doc
strings and generate the test code from the doc strings. If I
remember correctly IBM has published something to generate unit
tests from code. Python has a doctest module to support testing
derived from doc strings. This can be combined with unit tests.
The problem can be solved more easily if you design the module

skeleton first, then the tests and then the logic for the skeleton
- you would be creating tests before the code, but many people

wouldn't regard it as TDD then.


You shouldn't care if your approach works for you.

--
Fabio Zadrozny
------------------------------------------------------
Software Developer
ESSS - Engineering Simulation and Scientific Software
www.esss.com.br

Jul 18 '05 #3
Peter Maas <pe***@somewhere.com> writes:
I think this is too difficult, because there are many ways to write
code (even skeletons) for a use case. An easier approach would
be to write the skeleton manually, embed the test cases in the doc
strings and generate the test code from the doc strings. If I
remember correctly IBM has published something to generate unit
tests from code. Python has a doctest module to support testing
derived from doc strings. This can be combined with unit tests.
Yes - actually I channged my mind in somewhere in the article - I actually
don't want to create typical use-cases in the test bed, rather create a
skeleton which covers each method at least somehow (no code inside skeleton
would be needed).
> The problem can be solved more easily if you design the module
skeleton first, then the tests and then the logic for the skeleton
- you would be creating tests before the code, but many people
> wouldn't regard it as TDD then.

You shouldn't care if your approach works for you.


Yes, you are right. I didn't select my words very well - I just meant that it
wouldn't be TDD then. Of course it might work, but I'd like to to it the TDD
way for now.

But thanks for the tip, I could see what IBM has done and then forget about
doing it automatically :)

--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!

$_ = '456476617264204d616a616b6172692c20612043687269737 469616e20'; print
join('',map{chr hex}(split/(\w{2})/)),uc substr(crypt(60281449,'es'),2,4),"\n";
Jul 18 '05 #4
Fabio Zadrozny <fa****@esss.com.br> writes:
I think that the best approach I saw to this was in the Eclipse java
ide... You can basically go on the declaration of

self.obj = player.Player('Fred the Adventurer')

press Ctrl+1 and it adds a suggestion to create the class Player.

Then go to

assert self.obj.name == 'Fred the Adventurer'

press Ctrl+1 and it adds suggestion: Declare field name in class
Player... and so on for methods... (true, you still have to go and press
some Ctrl+1s, but that should be fairly easy, especially if you had some
hints on what is missing... Python has a very dynamic nature, but most of it
can still be done...
Yes, I know. Eclipse is an excellent Java IDE - I've already seen ''quick
assist'' at work and I envy those Eclipse users for having such a nice tool :)

PyDev for eclipse seems /very/ promising, though.
I think that most Python IDEs are still not in the same level, but some day
they might get there... Being the maintaner of PyDev (http://pydev.sf.net),
I think it will get there someday, true, lots of work to make it happen,
right now only few things in Ctrl+1 are available like that (still, some
already are)... and that's the way things work... nothing's always perfect
(but at least they evolve).


Thanks for the comments - and for your pydev plugin, too.

--
# Edvard Majakari Software Engineer
# PGP PUBLIC KEY available Soli Deo Gloria!

"Debugging is twice as hard as writing the code in the firstplace. Therefore,
if you write the code as cleverly as possible, you are, by definition,
not smart enough to debug it." -- Brian W. Kernighan
Jul 18 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

14
by: | last post by:
Hi! I'm looking for unit-testing tools for .NET. Somthing like Java has --> http://www.junit.org regards, gicio
72
by: Jacob | last post by:
I have compiled a set og unit testing recommendations based on my own experience on the concept. Feedback and suggestions for improvements are appreciated: ...
10
by: Ben Finney | last post by:
Howdy all, Question: I have Python modules named without '.py' as the extension, and I'd like to be able to import them. How can I do that? Background: On Unix, I write programs intended to...
6
by: Michael Bray | last post by:
I've just inherited a fairly large project with multiple classes. The developer also wrote a huge number of unit tests (using NUnit) to validate that the classes work correctly. However, I don't...
10
by: Tom Plunket | last post by:
I've got a bunch of code that runs under a bunch of unit tests. It'd be really handy if when testing I could supply replacement functionality to verify that the right things get called without...
5
by: shuisheng | last post by:
Dear All, I was told that unit test is a powerful tool for progamming. If I am writing a GUI code, is it possible to still using unit test? I have a little experience in using unittest++. But...
6
by: Silfheed | last post by:
Heyas So we have the following situation: we have a testee.py that we want to automatically test out and verifiy that it is worthy of being deployed. We want our tester.py to test the code for...
6
by: Joel Hedlund | last post by:
Hi! I write, use and reuse a lot of small python programs for variuos purposes in my work. These use a growing number of utility modules that I'm continuously developing and adding to as new...
3
by: =?ISO-8859-15?Q?Arne_Vajh=F8j?= | last post by:
Alain Boss wrote: Believe it or not, but I have actually seen getters and setters being wrong after too much copy paste (it was not C# but that does not really matter). As a consequence I am...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.