Python中测试驱动开发的澄清

2024-09-29 21:33:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我想知道我是否可以得到一些关于TDD的澄清,只是一般的测试。我使用python来编写我的程序,并且pytest作为我的测试框架

到目前为止,我一直在这样做,先写这些测试,已经开始让我的大脑对某些任务采取务实的态度

  1. 除了3个类变量之外的所有内容都是在编写测试之前编写的,这是否意味着我在技术上没有遵循TDD
  2. 为了清楚起见,我是否应该先为一个未实现的方法编写整个测试,然后创建方法和功能,以便测试通过
  3. 在TDD之后,我的主要目标是让每一个测试都通过吗,不管我在测试数据中做了什么改变?(它确实如此)(因此消除了潜在的bug?)
  4. 一个类的测试是否应该非常多(取决于类的大小)
  5. 根据下面的代码,你能告诉我我的路径是否正确吗

代码供您参考

import pytest
import os
import sys

path = os.path.dirname(os.path.abspath(__file__))
path = path.replace("\\pytest", "")
sys.path.append(path)
path += "\\pyffi"
sys.path.append(path)

from NifExplorer import NifExplorer
from NifExplorer import NifFormat

@pytest.fixture(autouse=True, scope='session')
def setup_nifExplorer():
    Explorers = []

    explorer = NifExplorer()
    explorer.SetBlockType(NifFormat.NiNode)
    explorer.SetResultPath("\\pytest\\results")
    explorer.SetSearchPath("\\pytest\\nif\\base")

    explorer2 = NifExplorer()
    explorer2.SetBlockType(NifFormat.ATextureRenderData)
    explorer2.SetResultPath("\\pytest\\results")
    explorer2.SetSearchPath("\\pytest\\nif\\base")

    explorer3 = NifExplorer()
    explorer3.SetBlockType("NiNode")
    explorer3.SetResultPath("\\pytest\\testResults")
    explorer3.SetSearchPath("\\pytest\\nif\\base")

    Explorers.append(explorer)
    Explorers.append(explorer2)
    Explorers.append(explorer3)


    return Explorers   

@pytest.mark.usefixtures("setup_nifExplorer")
class TestNifExplorer:
    def NifExlorer_BlockType_Is_Not_None(self, setup_nifExplorer):
        assert setup_nifExplorer.BlockType != None

    def NifExplorer_SearchPath_Is_Not_None(self, setup_nifExplorer):
        assert setup_nifExplorer.SearchPath != None

    def NifExplorer_ResultPath_Is_Not_None(self, setup_nifExlorer):
        assert setup_nifExlorer.ResultPath != None
        
    @pytest.mark.parametrize('funcs', (NifExplorer_SearchPath_Is_Not_None, NifExplorer_ResultPath_Is_Not_None, NifExlorer_BlockType_Is_Not_None))
    def test_NifExplorer_Variables_Equal_Not_None(self, setup_nifExplorer, funcs):
        for obj in setup_nifExplorer:
            funcs(self,obj)
        
    def NifExplorer_ResultPath_Directory_Exists(self, setup_nifExplorer):
        assert os.path.exists(setup_nifExplorer.ResultPath) == True

    def NifExplorer_SearchPath_Directory_Exists(self, setup_nifExplorer):
        assert os.path.exists(setup_nifExplorer.SearchPath) == True

    def NifExplorer_SearchPath_Directory_Contains_No_Forward_Slashes(self, setup_nifExplorer):
        assert setup_nifExplorer.SearchPath.count('/') < 1

    def NifExplorer_ResultPath_Directory_Contains_No_Forward_Slashes(self, setup_nifExplorer):
        assert setup_nifExplorer.ResultPath.count('/') < 1

    @pytest.mark.parametrize('funcs', [NifExplorer_ResultPath_Directory_Exists, NifExplorer_SearchPath_Directory_Exists, NifExplorer_SearchPath_Directory_Contains_No_Forward_Slashes, NifExplorer_ResultPath_Directory_Contains_No_Forward_Slashes])
    def test_NifExplorer_Directories_Exist_And_Paths_Contain_No_Forward_Slashes(self, setup_nifExplorer, funcs):
        for obj in setup_nifExplorer:
            funcs(self,obj)

    def NifExplorer_SearchPath_Contains_Nif_Files_Recursively(self, setup_nifExplorer):
        assert setup_nifExplorer.DirectoryContainsNifRecursively(setup_nifExplorer.SearchPath) == True

    @pytest.mark.parametrize('funcs', [NifExplorer_SearchPath_Contains_Nif_Files_Recursively])
    def test_NifExplorer_SearchPath_Contains_Nif_Files(self, setup_nifExplorer, funcs):
        for obj in setup_nifExplorer:
            funcs(self,obj)
if __name__ == "__main__":
    pytest.main()

Tags: pathselfnonepytestdefsetupnotassert
1条回答
网友
1楼 · 发布于 2024-09-29 21:33:54

Everything apart from 3 class variables were written before the tests were written, does that mean I'm technically not following TDD?

如果您在进行需要的测试之前编写了任何“真实”代码,那么您就没有遵循TDD。这是可以的-TDD不一定是在所有情况下使用的最佳工具。但是当您处于TDD有意义的情况下,那么首先编写测试

am I supposed to write the entire test for an unimplemented method first, then create the method and functionality so the tests pass?

这取决于你遵循谁的指导。Robert Martin建议您编写足够的测试以使其失败,然后通过那么多测试,然后编写更多测试,然后通过,依此类推,直到测试完成。他称之为纳米循环。马丁认为这是一种重现与肯特·贝克共事经历的技巧

然而,当Kent Beck自己描述TDD时,他谈到编写一个完整的测试,然后一次解决其中的一个问题

我自己发现贝克的风格更适合我,尤其是在一个可以自动填充一些缺失代码的编码环境中。因此,我将专注于测试的设计,直到我对它感到满意为止,然后让IDE创建通过测试所需的框架代码,并最终填充细节

Is my main objective following TDD to have every single test pass

测试实际上是“错误检测器”;目标是创建无错误地交付价值的代码

TDD的一个好处是,这个仪式大大减少了你在任何时候必须处理的“错误”的数量。是的,这意味着我们几乎总是处于两种状态中的一种,要么(a)我们写的所有测试都通过了,要么(b)除了我们写的一个测试之外,所有测试都通过了

Are tests for a class supposed to number greatly(depending on the size of the class)?

不一定是大小;复杂性可能是一个更好的衡量标准——有多少种不同的输入类?通常,您至少需要从每个样本中抽取一个样本,以确保您需要的所有行为都存在

这里有一个常见的例子:假设一个函数以公历年作为输入,如果该年是闰年,则返回true。我们关心的输入类

  • 不能被4整除的年份
  • 年份可以被4整除,但不能被100整除
  • 年份可以被100整除,但不能被400整除
  • 可被400整除的年份

那么四次“测试”

can you tell me if I am on the correct path

很难说。然而,有几个想法很突出

大多数实际工作包括“复杂的代码”和“难以测试的代码”。一个有用的技巧是设计代码,使复杂的代码易于测试,而难以测试的代码非常简单,显然没有缺陷

“难以测试”包括依赖于共享可变状态(如文件系统)的行为。因此,我们通常会选择文件系统代码过于简单而无法破坏的设计,将所有分支放在其他地方,然后彻底测试分支代码

此外,测试设计是一件事。特别是,我们通常希望对测试进行优先排序,使其易于一目了然。这反过来通常意味着您将把一个测试的所有代码放在一起,而不是将一堆“设置”代码放在一个地方,而将断言放在其他地方

相关问题 更多 >

    热门问题