473,569 Members | 2,648 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

PEP 299 and unit testing

Howdy all,

PEP 299 <URL:http://www.python.org/dev/peps/pep-0299details an
enhancement for entry points to Python programs: a module attribute
(named '__main__') that will be automatically called if the module is
run as a program.

The PEP has status "Rejected", citing backward-compatibility issues,
and Guido's pronouncement that "It's not worth the change (in docs,
user habits, etc.) and there's nothing particularly broken."

I don't deny the backward-compatibility issues in the cited
discussion, but I'd like to point out one thing that is broken by
this: unit testing of program modules.
Unit tests need to import a module and introspectively test small
units from the module to verify their behaviour in isolation. The
boundary of a unit test is the code that's actually in the module
under test: any functional code in that module needs to be tested by
the module's unit test, any code not in that module is outside the
scope of that unit test module.

The logical extension of this is to put *all* functional code into
discrete units, including the "main line" code that gets executed when
the module is run as a program. This leads to code of the type
discussed in PEP 299:

def main(argv):
""" Do the main stuff of this program """
parse_commandli ne(argv)
try:
do_interesting_ things()
except SystemExit, e:
exitcode = e.code
return exitcode

if __name__ == "__main__":
import sys
exitcode = main(sys.argv)
sys.exit(exitco de)

This allows the module's 'main' function to be called as a discrete
unit from the unit test module; the unit test passes in 'argv' as
desired, and fakes out other units that aren't being tested.

What it doesn't allow is for the testing of the 'if __name__ ==
"__main__": ' clause itself. No matter how simple we make that, it's
still functional code that can contain errors, be they obvious or
subtle; yet it's code that *can't* be touched by the unit test (by
design, it doesn't execute when the module is imported), leading to
errors that won't be caught as early or easily as they might.

So, I'd argue that "nothing particularly broken" isn't true: unit
testing is flawed in this scenario. It means that even the simple
metric of statement-level test coverage can't ever get to 100%, which
is a problem since it defeats a simple goal of "get all functional
code covered by unit tests".
On the other hand, if PEP 299 *were* implemented (and the
backward-compatibility issues solved), the above could be written as:

def __main__(argv):
""" Do the main stuff of this program """
parse_commandli ne(argv)
try:
do_interesting_ things()
except SystemExit, e:
exitcode = e.code
return exitcode

with no module-level 'if __name__' test at all, and therefore no
functional code unreachable by the unit test module. The effect of the
program is the same, but the invocation of the '__main__' function
isn't left to be implemented in every single program, separately and
subject to error in every case. Instead, it becomes part of the
*external* environment of the module, and is trivially outside the
scope of a unit test module for that program.

--
\ "What I have to do is see, at any rate, that I do not lend |
`\ myself to the wrong which I condemn." -- Henry Thoreau, _Civil |
_o__) Disobedience_ |
Ben Finney
Oct 29 '07 #1
5 2233
Ben Finney wrote:
What it doesn't allow is for the testing of the 'if __name__ ==
"__main__": ' clause itself. No matter how simple we make that, it's
still functional code that can contain errors, be they obvious or
subtle; yet it's code that *can't* be touched by the unit test (by
design, it doesn't execute when the module is imported), leading to
errors that won't be caught as early or easily as they might.
You could always use runpy.run_modul e.

STeVe
Oct 29 '07 #2
Steven Bethard <st************ @gmail.comwrite s:
Ben Finney wrote:
What it doesn't allow is for the testing of the 'if __name__ ==
"__main__": ' clause itself. No matter how simple we make that,
it's still functional code that can contain errors, be they
obvious or subtle; yet it's code that *can't* be touched by the
unit test (by design, it doesn't execute when the module is
imported), leading to errors that won't be caught as early or
easily as they might.

You could always use runpy.run_modul e.
For values of "always" that include Python 2.5, of course. (I'm still
coding to Python 2.4, until 2.5 is more widespread.)

Thanks! I was unaware of that module. It does seem to nicely address
the issue I discussed.

--
\ "Pinky, are you pondering what I'm pondering?" "I think so, |
`\ Brain, but Zero Mostel times anything will still give you Zero |
_o__) Mostel." -- _Pinky and The Brain_ |
Ben Finney
Oct 29 '07 #3
Ben Finney wrote:
Steven Bethard <st************ @gmail.comwrite s:
>Ben Finney wrote:
>>What it doesn't allow is for the testing of the 'if __name__ ==
"__main__": ' clause itself. No matter how simple we make that,
it's still functional code that can contain errors, be they
obvious or subtle; yet it's code that *can't* be touched by the
unit test (by design, it doesn't execute when the module is
imported), leading to errors that won't be caught as early or
easily as they might.
You could always use runpy.run_modul e.

For values of "always" that include Python 2.5, of course. (I'm still
coding to Python 2.4, until 2.5 is more widespread.)

Thanks! I was unaware of that module. It does seem to nicely address
the issue I discussed.
You might try the runpy module as-is with Python 2.4. I don't know if
it works, but it's pure Python so it's worth a try.

STeVe
Oct 29 '07 #4
Steven Bethard <st************ @gmail.comwrite s:
Ben Finney wrote:
Thanks! I was unaware of that module. It does seem to nicely
address the issue I discussed.

You might try the runpy module as-is with Python 2.4. I don't know
if it works, but it's pure Python so it's worth a try.
Drat. It uses (by explicit design) "the standard import mechanism" to
load the module, which means it doesn't work for exactly the thing I'm
trying to do: load a program file *not* named with a '.py' suffix.

I've long been able to load my program modules from no-suffix
filenames (or indeed any non-standard filenames) with this function::

def make_module_fro m_file(module_n ame, file_name):
""" Make a new module object from the code in specified file """

from types import ModuleType
module = ModuleType(modu le_name)

module_file = open(file_name, 'r')
exec module_file in module.__dict__
sys.modules[module_name] = module

return module

Unfortunately, it seems that "module is already present with name
'foo' in 'sys.modules'" is insufficient for the Python import
mechanism. The module loader used by 'runpy' still complains that it
can't find the module, which is no surprise because its filename is
not that of a library module.

Perhaps I need to delve into the details of the import mechanism
myself :-(

--
\ "With Lisp or Forth, a master programmer has unlimited power |
`\ and expressiveness. With Python, even a regular guy can reach |
_o__) for the stars." -- Raymond Hettinger |
Ben Finney
Oct 29 '07 #5
Ben Finney <bi************ ****@benfinney. id.auwrites:
Steven Bethard <st************ @gmail.comwrite s:
Ben Finney wrote:
What it doesn't allow is for the testing of the 'if __name__ ==
"__main__": ' clause itself. No matter how simple we make that,
it's still functional code that can contain errors, be they
obvious or subtle; yet it's code that *can't* be touched by the
unit test (by design, it doesn't execute when the module is
imported), leading to errors that won't be caught as early or
easily as they might.
You could always use runpy.run_modul e.

Thanks! I was unaware of that module. It does seem to nicely address
the issue I discussed.
Thinking about it further: I don't think it does address the issue.

Running the *entire* module code again in a single step (as
'run_module' seems to do) would happily overwrite any instrumented
faked attributes of the module that were inserted for the purpose of
unit testing, rendering it useless for unit test purposes.

The issue here is that there is an irreducible amount of functional
code inside the module that cannot be unit tested without running the
entire program with all its side effects.

PEP 299 promises to make that specific small-but-significant code
become an implementation detail in the language runtime, which would
mean it would no longer be prone to errors in the modules themselves,
and thus no longer the topic of a unit test on those modules. I think
100% statement coverage is not possible in Python programs without
this, or something that achieves the same thing.

--
\ "We spend the first twelve months of our children's lives |
`\ teaching them to walk and talk and the next twelve years |
_o__) telling them to sit down and shut up." -- Phyllis Diller |
Ben Finney
Oct 29 '07 #6

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

Similar topics

4
3727
by: Hugh Cowan | last post by:
Hello, I don't program full-time (anymore), but I do try and stay on-top of the latest technologies and like most are always trying to upgrade my skills and remain current (as much as is possible). Most of my programming these days involves using PHP for creating script files for automating tasks and procedures (locally), and also for...
11
2315
by: rhat | last post by:
Hi Everyone, I've recently been reading some articles about unit-testing in Python , but I am a bit confused: where do I go to get started with this? I tried googling for "unittest" but all I've found are some old links to projects that already use it, and the older (as the articles put it) PyUnit project. I'm sorry if this is a obvious...
14
2726
by: | last post by:
Hi! I'm looking for unit-testing tools for .NET. Somthing like Java has --> http://www.junit.org regards, gicio
4
2154
by: Peter Rilling | last post by:
Does VS.NET 2005 Professional support integrated unit testing, or is that only with the team system?
72
5188
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: http://geosoft.no/development/unittesting.html Thanks.
4
18953
by: Dat AU DUONG | last post by:
Hi, I am new to Unit testing, could you tell me where I could find information (hopefully step by step) and what is the benefit of unit testing. I am a sole developer in a company, therefore I don't get expose to much of this technology. Thanks in advance. Regards Dat.
5
6505
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 I can not work out a way to use it to test GUI code. Thanks a lot!
176
8268
by: nw | last post by:
Hi, I previously asked for suggestions on teaching testing in C++. Based on some of the replies I received I decided that best way to proceed would be to teach the students how they might write their own unit test framework, and then in a lab session see if I can get them to write their own. To give them an example I've created the...
48
2463
by: Ark Khasin | last post by:
Unit testing is an integral component of both "formal" and "agile" models of development. Alas, it involves a significant amount of tedious labor. There are test automation tools out there but from what limited exposure I've had, they are pricey, reasonably buggy, and require compiler/target adaptation. Out of my frustration with two out...
0
7701
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7615
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8130
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7677
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
6284
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3653
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2115
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1223
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
940
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.