Python中的单元测试和测试驱动开发

有哪些不同类型的软件测试?

通常,我们可以说有四种类型的软件测试:

  • 单元测试:着眼于软件的特定单元或组件,以确定每个单元是否功能齐全。

  • 集成测试:包括对单个构建基块或组件的组合测试。它检查各个功能之间是否存在任何接口缺陷。

  • 系统测试:系统测试是在完整的集成系统上进行的测试,以评估系统是否符合其特定要求。

  • 验收测试:此测试在生产环境中发布软件之前进行。用户将测试系统,以确定应用程序是否满足其业务需求

单元测试规范:

  • 测试单个功能

  • 应该针对每种功能的测试用例类型编写测试(所有正面和负面的测试用例)

  • 它应该在开发环境中执行

  • 加载和执行时间不应该花费更多的时间,因为开发人员不时需要它们来执行,因此它应该足够快

  • 测试应自动执行

什么是测试驱动开发或TDD?

在此过程中,单元测试是实际代码之前编写的。

现在,您一定想知道在编写实际功能之前,如何编写测试用例。不是我们要编写所有测试用例,然后再编写完整的代码,而是开始为其中一种功能编写测试用例,然后编写使该测试通过的代码。这样,我们的代码和测试将不断增长。以下步骤在TDD方法中非常重要:

1)首先编写一个失败的单元测试。

2)然后编写足够的代码以使测试通过

3)重构单元测试和生产代码以使其干净

4)重复该过程,直到功能完成

为了清楚地理解它,我将带您通过一个例子。

我们将以一个简单的例子来理解目的。我们的函数检查输入值是偶数还是奇数。由于我将使用“ pytest”框架,因此我们需要先安装它。我个人更喜欢使用“ pytest”而不是“ unittest”框架,因为它易于使用和学习,两个框架都有各自的优势,因此请根据您的用例进行选择。

python -m pip install pytest
 
因此,以下是针对我们的功能的测试用例:
  • 我可以打电话给evenOdd()吗
  • 如果我通过偶数,则应返回“偶数”
  • 如果我通过奇数,则应返回“奇数”
  • 如果我传递整数以外的任何东西,那么应该抛出异常

让我们一次检查每个测试用例,因此现在正在测试是否可以调用“ evenOdd()”函数。根据前面编写的步骤,我们需要首先编写一个失败的单元测试。下面,我在定义函数之前先对其进行调用。

 
#test_evenodd.py
import pytest

def test_call_evenOdd():
    evenOdd(1)

我们可以通过使用命令“ pytest”来运行以上测试,如下所示:

在“ pytest_unittest”文件夹中,我还有许多其他测试文件,当所有测试通过时,它将显示一个点“。”。如果测试失败,则会在控制台上写入“ F”,如上面的屏幕截图所示。如预期的那样,测试失败,因为我们没有函数evenOdd()。现在,我们将进入第二步,即“编写足够的代码以使测试通过”

 
#test_evenodd.py
import pytest

def evenOdd(value):
    return

def test_call_evenOdd():
    evenOdd(1)

以上测试的结果是:

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:721195303

 

从输出中,我们可以看到测试已通过。现在,我们将进入第三步,即“重构单元测试和生产代码以使其整洁”。那么有什么需要重构的吗?实际上不。现在让我们转到第二个测试用例。“如果我通过偶数,则应返回“偶数””,失败的测试用例将如下所示:

 
#test_evenodd.py
import pytest

def evenOdd(value):
    return 

def test_call_evenOdd():
    evenOdd(1)

def test_check_even():
    retval = evenOdd(2) 
    assert retval=='even'

现在,我将编写足够的代码以通过测试:

 
#test_evenodd.py
import pytest

def evenOdd(value):
    return 'even'

def test_call_evenOdd():
    evenOdd(1)

def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

现在我们可以看到测试已通过。

现在让我们检查一下是否有需要重构的东西?是的,我们可以重构测试,因为我们在两个测试用例中复制了函数调用。因此,重构后的代码将是:

 
#test_evenodd.py
import pytest

def evenOdd(value):
    return 'even'

def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

现在开始下一个测试用例:如果我通过奇数,则应返回“奇数”

失败的测试用例如下:

 
#test_evenodd.py
import pytest

def evenOdd(value):
    return 'even'

def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

def test_check_odd():
    retval = evenOdd(1)
    assert retval== 'odd'

现在我们需要编写代码以使测试通过。

 
#test_evenodd.py
import pytest

def evenOdd(value):
    if value%2==0:
        return 'even'
    else:
        return 'odd'

def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

def test_check_odd():
    retval = evenOdd(1)
    assert retval== 'odd'
 

在这里,我看不到任何可重构的东西。现在让我们转到最后一个测试用例:如果我传递的不是整数,则应该引发异常。

失败的测试用例如下:

 
#test_evenodd.py
import pytest

def evenOdd(value):
    if value%2==0:
        return 'even'
    else:
        return 'odd'

def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

def test_check_odd():
    retval = evenOdd(1)
    assert retval== 'odd'

def test_check_int():
    with pytest.raises(TypeError):
        evenOdd(1.5)
 

现在,我将在函数中引发TypeError,如下所示:

#test_evenodd.py
import pytest

def evenOdd(value):
    if type(value)==int:
        if value%2==0:
            return 'even'
        else:
            return 'odd'
    else:
        raise TypeError


def test_check_even():
    retval = evenOdd(2)
    assert retval=='even'

def test_check_odd():
    retval = evenOdd(1)
    assert retval== 'odd'

def test_check_int():
    with pytest.raises(TypeError):
        evenOdd(1.5)

并且我们所有的测试都通过了:

这样,我们已经实现了最终功能。撰写本文的主要目的是带您完成TDD方法的整个旅程。现在的问题来了,为什么我们要遵循TDD方法?TDD的好处在下面列出。

TDD方法的好处:

  • 为您提供正在开发的内容的即时反馈。

  • 有了即时反馈,您可以自信地更改功能或对当前代码进行增强

  • 这有助于项目或代码的可维护性和可扩展性

  • 最重要的是,它记录了代码,这有助于开发人员了解实际代码的行为方式


在这里还是要推荐下我自己建的Python学习群:721195303,群里都是学Python的,如果你想学或者正在学习Python ,欢迎你加入,大家都是软件开发党,不定期分享干货(只有Python软件开发相关的),包括我自己整理的一份2021最新的Python进阶资料和零基础教学,欢迎进阶中和对Python感兴趣的小伙伴加入!

猜你喜欢

转载自blog.csdn.net/aaahtml/article/details/114277809