0

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

4

2 回答 2

1

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

于 2013-10-30T13:58:58.797 回答
0

这是一个人为的示例,说明如何使用doctest和测试驱动开发与通过在控制台输入代码进行测试进行比较,并使用递归阶乘函数作为示例:

安慰:

第一次尝试:

def factorial(x)
    pass

安慰:

>>> factorial(7)
SyntaxError: invalid syntax

第二次尝试:

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

安慰:

>>> factorial(7)
42

第三次尝试:

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

安慰:

>>> 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 中,为您提供了执行此操作的工具。

看哪 - doctest 模块:(取自文档的示例)

第一次尝试:

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代码中添加语句的不太强大的技术。

于 2013-10-30T19:13:32.733 回答