python中的单元测试pyUnit & what is unit test and why

python中的单元测试pyUnit
在Python中进行单元测试时需要用到PyUnit模块,Python 2.1及其以后的版本都将PyUnit作为一个标准模块,但如果你使用的是较老版本的Python,那就要自已动手安装了。在PyUnit的网站(http://sourceforge.net/projects/pyunit)上可以下载到PyUnit最新的源码包,此处使用的是pyunit-1.4.1.tar.gz。
PyUnit跟Junit很相似,甚至连一些基本的函数名都一样。例如测试类必须是TestCase的子类,且初始函数为setUp(self), 清理函数tearDown(self)。
 
widget.py
# 将要被测试的类
class Widget:
    def __init__(self, size = (40, 40)):
        self._size = size
    def getSize(self):
        return self._size
    def resize(self, width, height):
        if width  0  or height < 0:
            raise ValueError, "illegal size"
        self._size = (width, height)
    def dispose(self):
        pass 
 
# 执行测试的类
from widget import Widget
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
    self.widget = Widget()
def tearDown(self):
    self.widget.dispose()
    self.widget = None
def testSize(self):
    self.assertEqual(self.widget.getSize(), (40, 40))
def testResize(self):
    self.widget.resize(100, 100)
    self.assertEqual(self.widget.getSize(), (100, 100))
# 测试
if __name__ == "__main__":
# 构造测试集
suite = unittest.TestSuite()
suite.addTest(WidgetTestCase("testSize"))
suite.addTest(WidgetTestCase("testResize"))

# 执行测试
runner = unittest.TextTestRunner()
runner.run(suite)

可以分几步进行, 首先我们的测试类要继承于unittest.TestCase. 如果采用动态测试的方法可以为每个需要测试的方法编写测试方法,使用assertEqual( , ). 然后把我们的测试都放到unittest.TestSuite()容器中,最后使用 unittest.TextTestRunner().run(suite)方法自动测试。

参考:
http://www.ibm.com/developerworks/cn/linux/l-pyunit/index.html
http://www.cnblogs.com/ysisl/archive/2009/08/17/1548054.html 
===========================================================

python 单元测试 使用摘要
主要步骤:
1。编写完备的单元测试用例
2。根据测试用例测试点编写程序
3。每编写完一个功能,执行测试用例,然后修改代码,直到该点涉及用例全部通过
4。所有用例通过测试,停止编码
5。发现新bug和开发新版本时,及时更新测试用例


编写用例

使用方法
    python自带unittest模块,编写的测试用例类继承unittest.TestCase类,所有测试函数以test开头,执行时,执行unittest.main(),所有测试类中以test开头的函数自动执行
    简单例子如下:
    import unittest
    #import testproject
    class mytestproject1(unittest.TestCase):
            def testcase1(self):
                    #do some thing with testproject
                    self.assertEquals(7/2,3)
            def testcase2(self):
                    #...
                    self.assertEquals("".join(['a','b',' c']),"abc")
    class mytestproject2(unittest.TestCase):
            def testException(self):
                    #...
                    self.assertRaises(ZeroDivisionError,lambda x:3/x,0)
    if __name__ = __main__:
            unittest.main()
    执行后,会报告每个函数执行情况

测试用例的编写
1。针对性
        每个用例,即test函数,必须只解决一个问题,这样定位问题会很简单
2。独立性
        每个用例之间没有影响,一个的输出不会影响到另外一个的执行
3。完备性
        每个用例所挑选的例子应该有代表性,尽可能增加覆盖度
4。顺序
        对于每个功能点来说,可能涉及到不同的方面,这些用例最好用一个类组织起来,并按照一定的逻辑顺序排列,这个对开发是有指导作用的
        
从测试对象来讲,测试用例应该具备以下条件:
1。功能性用例
        做什么的问题
2。反面用例
        不能做什么的问题,对处理对象的限定
3。适应性,健壮性用例
        其他的输入,达到安全性,可知性
        
unittest的接口:
主要用到unittest.TestCase中的接口,基本的是equal系列和raises系列。具体格式参见 help(unittest)

unittest文档翻译 

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

Why unit test?

  • You're already doing it!

Speaker's notes:

You're probably already doing at least ad hoc testing at the interactive prompt. Why not get the most mileage out of that effort? Imagine if every little test that you already perform during development were somehow kept and could be rerun easily.

  • Testing helps you find errors in your code.

Speaker's notes:

Of course, you only find errors if you have written a test that exercises the particular functionality that's broken, but once you start writing unit tests, you may be surprised by how many errors you find. As you write test cases, you'll think, "Gee, I wonder whether I handle this case correctly," or, "Hm. I don't think that I handle this error correctly." When you're using a testing framework, you can simply add more test cases. The ease of adding new tests and running them encourages more thorough testing. Try it for a week, and you'll see what I mean. Many developers who have gotten in the habit of unit testing find programming without writing unit tests to be difficult and somewhat frightening. Programming is to driving like unit tests are to seat belts.

  • Testing helps you write better code.

Speaker's notes:

In addition to finding errors in your code, unit testing can help you during the initial development of your class or module's public interface. Unit tests force you to think about how another developer will want to use your code while you're writing that code. This shift in focus can help you present a smaller, cleaner interface to your classes and modules. This benefit is most often associated with test-driven development.

  • Writing test cases will save you time later.

Speaker's notes:

Imagine that you don't write test cases in code. You finish some module, and you start testing it at the interactive prompt. You realize that there's a tricky case your code doesn't handle correctly. A quick test reveals that you're right. You fix the module and move on. Later, you decide to rework the implementation of your module. Are you sure you didn't forget that tricky case? Can the new code handle it? If you had written test cases, you could just rerun the same set of tests (as long as the interface didn't change). As an added bonus, you can run your tests often so that you may find a bug after you've only written a few dozen lines of code. If a test suddenly fails, you know that it was introduced in the little bit of code you just changed. Not only is it easier to detect when you've introduced an error, but it is also easier to find the code that causes the error, reducing the time spent debugging.

  • Unit tests provide immediate feedback on your code.

Speaker's notes:

When you're writing code deep in a library or in a server side module for a user interface, a unit test gives you feedback as you work. You don't have to wait until after code in a separate part of the application is written before you can test and know whether your code works. Those little "throw-away" programs you may be writing to test your code become reusable unit tests attached to a consistent testing framework.

  • Test cases document intent.

Speaker's notes:

Test cases provide minimal documentation about what you think your code should do. Tests don't necessarily explain why your code should behave the way shown, but they can explain how it should behave. In fact, some developers write their tests before they write their code. The tests define how the unit should behave. In this case, tests always fail at first. The programmer writes code until all of the tests are passing again. This style of programming called test-first programming or test-driven programming. Test-driven development also ensures that you have unit tests for all of your code since all of the code was developed to satisfy a test.

 

Why unit test?

  • You're already doing it!

Speaker's notes:

You're probably already doing at least ad hoc testing at the interactive prompt. Why not get the most mileage out of that effort? Imagine if every little test that you already perform during development were somehow kept and could be rerun easily.

  • Testing helps you find errors in your code.

Speaker's notes:

Of course, you only find errors if you have written a test that exercises the particular functionality that's broken, but once you start writing unit tests, you may be surprised by how many errors you find. As you write test cases, you'll think, "Gee, I wonder whether I handle this case correctly," or, "Hm. I don't think that I handle this error correctly." When you're using a testing framework, you can simply add more test cases. The ease of adding new tests and running them encourages more thorough testing. Try it for a week, and you'll see what I mean. Many developers who have gotten in the habit of unit testing find programming without writing unit tests to be difficult and somewhat frightening. Programming is to driving like unit tests are to seat belts.

  • Testing helps you write better code.

Speaker's notes:

In addition to finding errors in your code, unit testing can help you during the initial development of your class or module's public interface. Unit tests force you to think about how another developer will want to use your code while you're writing that code. This shift in focus can help you present a smaller, cleaner interface to your classes and modules. This benefit is most often associated with test-driven development.

  • Writing test cases will save you time later.

Speaker's notes:

Imagine that you don't write test cases in code. You finish some module, and you start testing it at the interactive prompt. You realize that there's a tricky case your code doesn't handle correctly. A quick test reveals that you're right. You fix the module and move on. Later, you decide to rework the implementation of your module. Are you sure you didn't forget that tricky case? Can the new code handle it? If you had written test cases, you could just rerun the same set of tests (as long as the interface didn't change). As an added bonus, you can run your tests often so that you may find a bug after you've only written a few dozen lines of code. If a test suddenly fails, you know that it was introduced in the little bit of code you just changed. Not only is it easier to detect when you've introduced an error, but it is also easier to find the code that causes the error, reducing the time spent debugging.

  • Unit tests provide immediate feedback on your code.

Speaker's notes:

When you're writing code deep in a library or in a server side module for a user interface, a unit test gives you feedback as you work. You don't have to wait until after code in a separate part of the application is written before you can test and know whether your code works. Those little "throw-away" programs you may be writing to test your code become reusable unit tests attached to a consistent testing framework.

  • Test cases document intent.

Speaker's notes:

Test cases provide minimal documentation about what you think your code should do. Tests don't necessarily explain why your code should behave the way shown, but they can explain how it should behave. In fact, some developers write their tests before they write their code. The tests define how the unit should behave. In this case, tests always fail at first. The programmer writes code until all of the tests are passing again. This style of programming called test-first programming or test-driven programming. Test-driven development also ensures that you have unit tests for all of your code since all of the code was developed to satisfy a test.

Why unit test? (cont'd)

  • Test cases provide a sample use of your code. That is, programmers who want to use your code can read your unit tests to see how you expect client code to use it.

Speaker's notes:

If you are distributing Free Software or Open Source code, you can ship your unit tests to show others how to use your classes and modules. Even with code written for "internal use," unit tests provide simple examples of how you expect clients to interact with a unit. That way, you may be able to avoid writing separate sample programs for other programmers who need to use your code. They can just read the unit tests.

  • In a very dynamic language like Python, unit tests provide added safety. Unit tests make up for some of the compile time checks that you lose.

Speaker's notes:

For those who have never programmed in a less dynamic language, such as C++ or Java, you may not realize how important some developers feel compile-time checks are. In these languages, code is written to push as much error detection as possible to compile time so that errors won't be discovered by QA or customers at run time. In the absence of compile time checks, thorough unit testing is even more important because it can catch many simple bugs (NameErrors and such) that may only be detectable at runtime in Python.

We need a unit testing framework!

  • Testing without a framework is difficult to reproduce

Speaker's notes:

Testing without a framework is often ad hoc. The tests may not be expressed in code at all. If they are, they are often not written in a way that they can be run again in the future. If they are, the way they are written and reproduced may be different for each unit. If they are consistent, then congratulations, you've written your own framework. :-)

  • Reproducible tests that don't use a standard framework may be more difficult for other developers to understand.

Speaker's notes:

For example, the unittest (PyUnit) module implements a unit testing framework that is already implemented and used in many other programming languages. Even if a developer hasn't used the Python version of this framework, he may be familiar with it from another programming language.

  • A unit testing framework provides
    • A mechanism to organize and group multiple tests
    • A simple way to invoke tests
    • Clear indication of which tests passed/failed
    • A standard way to write tests and specify expected results.

Speaker's notes:

Of course, we still have to write the test code and specify the expected results. Even with a framework, that task can be challenging. Thus, you probably don't want to combine the challenge of writing tests with the difficulty of creating your own testing framework.

posted @ 2011-07-10 22:38 dkcndk 阅读(...) 评论(...) 编辑 收藏