2013-10-30 24 views
0

我从其他讨论中看到,重装被认为是不必要的操作,也是开发程序的坏方法。人们说使用doctest和unittest。我肯定错过了什么。为了开发一个程序,我把它写在一个模块中,将模块加载到Eclipse控制台中,通过运行少量代码示例在控制台中进行试验,然后在模块中发现错误或决定更改某些内容。最快的做法是保存模块,重新加载并在控制台中继续工作。
有没有更好的方法?开发程序时不使用重装的最佳方式

+0

听说过测试驱动的Devlopment不同于Tickering驱动编程 –

+0

Doctest和unittest适用于测试。运行代码的小部分代码不太可能捕捉到所有的错误,但这并不够方便。 – rlms

+0

@sweeneyrod我同意有条件的测试有一个重要的地方,但有时候我不想编写最后一段代码,我只是想试验。即使在程序开发早期想制作一些经过适当测试的东西,我只想尝试并尝试不同的想法。在那个阶段,我不会认为doctest会非常有用。这只会让我放慢脚步。 – hfffoman

回答

0

这里有一个如何你可以在比较通过在控制台输入代码,用递归阶乘函数被用作一个实例使用doctest和测试驱动的开发与测试一个人为的例子:

控制台:

第一次尝试:

def factorial(x) 
    pass 

控制台:

>>> factorial(7) 
SyntaxError: invalid syntax 

第二次尝试:

def factorial(x): 
    return x*x-1 

控制台:

>>> factorial(7) 
42 

第三次尝试:

​​

控制台:

>>> factorial(7) 
RuntimeError: maximum recursion depth reached  # StackOverflow! (basically) 

第四次尝试:

def factorial(x): 
    if x == 0: 
     return 1 
    else: 
     return x * factorial(x-1) 

控制台:

>>> factorial(5) 
120 

最终,我们得到正确的答案,但在每一个阶段,我们必须回到控制台和写同样的事情。对于像这样的短程序来说,这是可以的,但对于具有许多功能的程序,以及更复杂的交互和可能被测试的程序来说,这需要很长时间。编程是关于重复性任务的自动化,而测试是一个重复的任务,所以自动化它是有意义的。在Python中,为您提供的工具就是为您提供的。

看哪 - 该文档测试模块(例如,从文档拍摄)

第一次尝试:

def factorial(n): 
    """Return the factorial of n, an exact integer >= 0. 

    >>> [factorial(n) for n in range(6)] 
    [1, 1, 2, 6, 24, 120] 
    >>> factorial(30) 
    265252859812191058636308480000000 
    >>> factorial(-1) 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 

    Factorials of floats are OK, but the float must be an exact integer: 
    >>> factorial(30.1) 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
    >>> factorial(30.0) 
    265252859812191058636308480000000 

    It must also not be ridiculously large: 
    >>> factorial(1e100) 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 
    """ 

if __name__ == "__main__": 
    import doctest 
    doctest.testmod(verbose=True) 

首先测试(只运行程序):

Trying: 
    [factorial(n) for n in range(6)] 
Expecting: 
    [1, 1, 2, 6, 24, 120] 
ok 
Trying: 
    factorial(30) 
Expecting: 
    265252859812191058636308480000000 
ok 
Trying: 
    factorial(-1) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 
ok 
Trying: 
    factorial(30.1) 
Expecting: 
    Traceqwrqaeqrback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
********************************************************************** 
File "C:/Python33/doctestex.py", line 14, in __main__.factorial 
Failed example: 
    factorial(30.1) 
Exception raised: 
    Traceback (most recent call last): 
     File "C:\Python33\lib\doctest.py", line 1287, in __run 
     compileflags, 1), test.globs) 
     File "<doctest __main__.factorial[3]>", line 1, in <module> 
     factorial(30.1) 
     File "C:/Python33/doctestex.py", line 32, in factorial 
     raise ValueError("n must be exact integer") 
    ValueError: n must be exact integer 
Trying: 
    factorial(30.0) 
Expecting: 
    265252859812191058636308480000000 
ok 
Trying: 
    factorial(1e100) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 
ok 
1 items had no tests: 
    __main__ 
********************************************************************** 
1 items had failures: 
    1 of 6 in __main__.factorial 
6 tests in 2 items. 
5 passed and 1 failed. 
***Test Failed*** 1 failures. 
>>> ================================ RESTART ================================ 
>>> 
Trying: 
    [factorial(n) for n in range(6)] 
Expecting: 
    [1, 1, 2, 6, 24, 120] 
********************************************************************** 
File "C:/Python33/doctestex.py", line 4, in __main__.factorial 
Failed example: 
    [factorial(n) for n in range(6)] 
Expected: 
    [1, 1, 2, 6, 24, 120] 
Got: 
    [None, None, None, None, None, None] 
Trying: 
    factorial(30) 
Expecting: 
    265252859812191058636308480000000 
********************************************************************** 
File "C:/Python33/doctestex.py", line 6, in __main__.factorial 
Failed example: 
    factorial(30) 
Expected: 
    265252859812191058636308480000000 
Got nothing 
Trying: 
    factorial(-1) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 
********************************************************************** 
File "C:/Python33/doctestex.py", line 8, in __main__.factorial 
Failed example: 
    factorial(-1) 
Expected: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 
Got nothing 
Trying: 
    factorial(30.1) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
********************************************************************** 
File "C:/Python33/doctestex.py", line 14, in __main__.factorial 
Failed example: 
    factorial(30.1) 
Expected: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
Got nothing 
Trying: 
    factorial(30.0) 
Expecting: 
    265252859812191058636308480000000 
********************************************************************** 
File "C:/Python33/doctestex.py", line 18, in __main__.factorial 
Failed example: 
    factorial(30.0) 
Expected: 
    265252859812191058636308480000000 
Got nothing 
Trying: 
    factorial(1e100) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 
********************************************************************** 
File "C:/Python33/doctestex.py", line 22, in __main__.factorial 
Failed example: 
    factorial(1e100) 
Expected: 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 
Got nothing 
1 items had no tests: 
    __main__ 
********************************************************************** 
1 items had failures: 
    6 of 6 in __main__.factorial 
6 tests in 2 items. 
0 passed and 6 failed. 
***Test Failed*** 6 failures. 

那么当我们完成程序(以及之间的所有阶段),我们只需按一个按钮,即可完成我们所有的测试。如果您正在与一个团队合作开发一个更大的项目,那么您可以将测试数据写入文件并使用失败来查看需要关注的位置。

Trying: 
    [factorial(n) for n in range(6)] 
Expecting: 
    [1, 1, 2, 6, 24, 120] 
ok 
Trying: 
    factorial(30) 
Expecting: 
    265252859812191058636308480000000 
ok 
Trying: 
    factorial(-1) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 
ok 
Trying: 
    factorial(30.1) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
ok 
Trying: 
    factorial(30.0) 
Expecting: 
    265252859812191058636308480000000 
ok 
Trying: 
    factorial(1e100) 
Expecting: 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 
ok 
1 items had no tests: 
    __main__ 
1 items passed all tests: 
    6 tests in __main__.factorial 
6 tests in 2 items. 
6 passed and 0 failed. 
Test passed. 

和(前提是您添加的所有测试用例文档字符串),现在你可以运送或整合或任何程序,它少得多的错误比,如果你只是测试你觉得要紧的事情就真是每次你改变了一些东西,而不是你在开发过程开始时可能会遇到的事情。

更不用提你现在有你的文档的基础!在控制台中运行该程序,然后进入help(factorial)现在给你这样的:

Help on function factorial in module __main__: 

factorial(n) 
    Return the factorial of n, an exact integer >= 0. 

    >>> [factorial(n) for n in range(6)] 
    [1, 1, 2, 6, 24, 120] 
    >>> factorial(30) 
    265252859812191058636308480000000 
    >>> factorial(-1) 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be >= 0 

    Factorials of floats are OK, but the float must be an exact integer: 
    >>> factorial(30.1) 
    Traceback (most recent call last): 
     ... 
    ValueError: n must be exact integer 
    >>> factorial(30.0) 
    265252859812191058636308480000000 

    It must also not be ridiculously large: 
    >>> factorial(1e100) 
    Traceback (most recent call last): 
     ... 
    OverflowError: n too large 

然后,您可以使用一些工具(pydoc是一个标准库)打开文档字符串成格式化的HTML帮助文档。

当然,这只是您可以在Python中使用的许多测试工具之一。其他功能包括功能更强大的unittest模块,以及将assert语句添加到代码中的功能较弱的技术。

+0

感谢您的全面讨论。这很有趣,你可能猜到的人是Python的noob(尽管不是数学编程的noob)。我的第一种方法是将函数写入文件,导入,运行,编辑,重新加载,运行,编辑等。为了检查我是否正确理解,doctest的优点是同样快速地做同样的事情并带来额外的好处,还是稍微慢一点,但认为值得的额外严谨? – hfffoman

+0

@hfffoman我会说'doctest'的好处是你在开始时做了更多的工作,但是这样可以减少长时间的写入测试 - 文件 - 然后 - 运行 - 它的周期以及其他好处(文档被写入随你走)。但是我认为,测试工具的威力随着程序越大而变得越明显 - 如果没有正式的测试和工具,你永远不会想要编写一个大型项目(比如说Eclipse),这可能比标准库中的更重。 – rlms

1

基本上不是在控制台中尝试一下,而是通过编写测试来尝试一些事情。这几乎与键入的量相同,但是可重复(您可以检查更改后是否仍然有效),并且它可以作为文档的基本形式。

+0

+1是否意味着在一个文件中写入语句,然后在将它们变成函数之前先运行它们?那么最快的方法是将测试文件加载(并重新加载)到控制台中? – hfffoman

相关问题