python怎么测试程序_Python 程序的测试

测试的种类

根据关注点不同,测试分为两大类acceptance tests: 也就说,测试需要完成的功能,是否都已经实现

unit test:测试程序中不同的模块,是否能够正常、正确的相互调用

这两大类里面,都包含以下三个方面:exploratory testing

regression testing

integration testing

测试程序

doctest

这是一个自动化的测试程序,你把你的测试命令写在 docstring 或者 readme.txt,这个 package 会帮你做测试。

举个栗子

"""

This is the "example" module.

The example module supplies one function, factorial(). For example,

>>> factorial(5)

120

"""

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

"""

import math

if not n >= 0:

raise ValueError("n must be >= 0")

if math.floor(n) != n:

raise ValueError("n must be exact integer")

if n+1 == n: # catch a value like 1e300

raise OverflowError("n too large")

result = 1

factor = 2

while factor <= n:

result *= factor

factor += 1

return result

if __name__ == "__main__":

import doctest

doctest.testmod()

运行代码

python example.py -v

得到的结果如下

Trying:

factorial(5)

Expecting:

120

ok

Trying:

[factorial(n) for n in range(6)]

Expecting:

[1, 1, 2, 6, 24, 120]

ok

Trying:

factorial(1e100)

Expecting:

Traceback (most recent call last):

...

OverflowError: n too large

ok

2 items passed all tests:

1 tests in __main__

8 tests in __main__.factorial

9 tests in 2 items.

9 passed and 0 failed.

Test passed.

这种测试方法不适合大规模测试。

手工写测试

主要用到的语法是

try ... except ... 和 assert

比如

import sys

def test_quadroots_types():

try:

quad_roots("", "green", "hi")

except:

assert(sys.exc_info()[0] == TypeError)

test_quadroots_types()

import sys

def test_quadroots_zerocoeff():

try:

quad_roots(a=0.0)

except:

assert(sys.exc_info()[0] == ValueError)

test_quadroots_zerocoeff()

pytest

这里用实例来说明这个包怎么用。

首先,我们有一个 root 函数

%%file roots.py

def quad_roots(a=1.0, b=2.0, c=0.0):

"""Returns the roots of a quadratic equation: ax^2 + bx + c = 0.

INPUTS

=======

a: float, optional, default value is 1

Coefficient of quadratic term

b: float, optional, default value is 2

Coefficient of linear term

c: float, optional, default value is 0

Constant term

RETURNS

========

roots: 2-tuple of complex floats

Has the form (root1, root2) unless a = 0

in which case a ValueError exception is raised

EXAMPLES

=========

>>> quad_roots(1.0, 1.0, -12.0)

((3+0j), (-4+0j))

"""

import cmath # Can return complex numbers from square roots

if a == 0:

raise ValueError("The quadratic coefficient is zero. This is not a quadratic equation.")

else:

sqrtdisc = cmath.sqrt(b * b - 4.0 * a * c)

r1 = -b + sqrtdisc

r2 = -b - sqrtdisc

twoa = 2.0 * a

return (r1 / twoa, r2 / twoa)

然后写一个 test 文件

%%file test_roots.py

import pytest

import roots

def test_quadroots_result():

assert roots.quad_roots(1.0, 1.0, -12.0) == ((3+0j), (-4+0j))

def test_quadroots_types():

with pytest.raises(TypeError):

roots.quad_roots("", "green", "hi")

def test_quadroots_zerocoeff():

with pytest.raises(ValueError):

roots.quad_roots(a=0.0)

最后调用 pytest

python -m pytest ./test_roots.py

输出结果大概长这样

============================= test session starts ==============================

platform darwin -- Python 3.6.7, pytest-3.8.2, py-1.6.0, pluggy-0.7.1

rootdir: xx

plugins: remotedata-0.3.0, openfiles-0.3.0, doctestplus-0.1.3, cov-2.5.1, arraydiff-0.2

collected 3 items

test_roots.py ... [100%]

=========================== 3 passed in 0.03 seconds ===========================

pytest-cov

有时候,一个文件里面的函数很多,你希望确保所有的函数都被测试程序覆盖掉了。所以这个时候需要 pytest-cov 上场了。

%%file roots.py

def linear_roots(a=1.0, b=0.0):

"""Returns the roots of a linear equation: ax+ b = 0.

INPUTS

=======

a: float, optional, default value is 1

Coefficient of linear term

b: float, optional, default value is 0

Coefficient of constant term

RETURNS

========

roots: 1-tuple of real floats

Has the form (root) unless a = 0

in which case a ValueError exception is raised

EXAMPLES

=========

>>> linear_roots(1.0, 2.0)

-2.0

"""

if a == 0:

raise ValueError("The linear coefficient is zero. This is not a linear equation.")

else:

return ((-b / a))

def quad_roots(a=1.0, b=2.0, c=0.0):

"""Returns the roots of a quadratic equation: ax^2 + bx + c = 0.

INPUTS

=======

a: float, optional, default value is 1

Coefficient of quadratic term

b: float, optional, default value is 2

Coefficient of linear term

c: float, optional, default value is 0

Constant term

RETURNS

========

roots: 2-tuple of complex floats

Has the form (root1, root2) unless a = 0

in which case a ValueError exception is raised

EXAMPLES

=========

>>> quad_roots(1.0, 1.0, -12.0)

((3+0j), (-4+0j))

"""

import cmath # Can return complex numbers from square roots

if a == 0:

raise ValueError("The quadratic coefficient is zero. This is not a quadratic equation.")

else:

sqrtdisc = cmath.sqrt(b * b - 4.0 * a * c)

r1 = -b + sqrtdisc

r2 = -b - sqrtdisc

twoa = 2.0 * a

return (r1 / twoa, r2 / twoa)

然后加入还是只测试 quad_roots 这个函数,故意漏掉 linear_roots。看看 pytest-cov 能不能帮我们发现。

运行 python -m pytest ./test_roots.py --cov --cov-report term-missing

============================= test session starts ==============================

platform darwin -- Python 3.6.7, pytest-3.8.2, py-1.6.0, pluggy-0.7.1

rootdir: xx

plugins: remotedata-0.3.0, openfiles-0.3.0, doctestplus-0.1.3, cov-2.5.1, arraydiff-0.2

collected 3 items

test_roots.py ... [100%]

---------- coverage: platform darwin, python 3.6.7-final-0 -----------

Name Stmts Miss Cover Missing

---------------------------------------------

roots.py 13 3 77% 22-25

test_roots.py 10 0 100%

---------------------------------------------

TOTAL 23 3 87%

=========================== 3 passed in 0.04 seconds ===========================

可以告诉你 line 22-25 没有 cover 到。

你可能感兴趣的:(python怎么测试程序)