Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中正确地进行单元测试_Python_Python 3.x_Python Unittest - Fatal编程技术网

如何在Python中正确地进行单元测试

如何在Python中正确地进行单元测试,python,python-3.x,python-unittest,Python,Python 3.x,Python Unittest,我有一个方法可以做到以下几点。问题是我如何对这个方法进行单元测试。我对这个Python单元测试模块相当陌生 问题和解决办法如下: Given a string containing of ‘0’, ‘1’ and ‘?’ wildcard characters, generate all binary strings that can be formed by replacing each wildcard character by ‘0’ or ‘1’. Example : Input str

我有一个方法可以做到以下几点。问题是我如何对这个方法进行单元测试。我对这个Python单元测试模块相当陌生

问题和解决办法如下:

Given a string containing of ‘0’, ‘1’ and ‘?’ wildcard characters, generate all binary strings that can be formed by replacing each wildcard character by ‘0’ or ‘1’.
Example :
Input str = "1??0?101"
Output: 
        10000101
        10001101
        10100101
        10101101
        11000101
        11001101
        11100101
        11101101
解决方案:

def _print(string, index):
    if index == len(string):
        print(''.join(string))
        return

    if string[index] == "?":

        # replace '?' by '0' and recurse
        string[index] = '0'
        _print(string, index + 1)

        # replace '?' by '1' and recurse
        string[index] = '1'
        _print(string, index + 1)

        # NOTE: Need to backtrack as string
        # is passed by reference to the
        # function
        string[index] = '?'
    else:
        _print(string, index + 1)

# Driver code
if __name__ == "__main__":

    string = "1??0?101"
    string = list(string) #don’t forget to convert to string
    _print(string, 0)

输出:

        10000101
        10001101
        10100101
        10101101
        11000101
        11001101
        11100101
        11101101
问题:

1。还有,有没有办法将列表作为输出返回,而不是打印出来?

2。在这种情况下,哪些断言测试用例是合适的?

3。在这种情况下,最好的端到端测试用例是什么?

4。在时间和空间复杂性方面,有什么更好的方法可以解决这个问题?

我尝试过这个似乎不起作用的方法:

import unittest
from wildcard import _print
class TestWildCard(unittest.TestCase):

    def test_0_print(self):
        print("Start wildCard _print test: \n")
        result = 111
        self.assertEquals(_print("1?1",0),result,"Results match")
答复:

1:当然,不要打印某些内容,而是将结果附加到列表
result.append('some value')
,不要忘记在代码
result=[]
的开头初始化列表,并在函数完成后返回它
返回结果
-并且可能不调用函数
\u print
,但是类似于
位字符串

ad 1:由于函数是递归的,因此在递归调用函数时,现在还需要捕获返回值并将其添加到结果中,因此
result+=\u print(string,index+1)

2:您通常应该考虑边缘情况并单独测试它们,或者将那些真正测试功能的单个方面的情况组合在一起。没有一种方法可以说明测试应该是什么样子的——如果有的话,测试框架只会为您生成它

3:答案与2相同

您的代码变成:

def bit_strings(s, index):
    result = []

    if index == len(s):
        result.append(''.join(s))
        return result

    if s[index] == "?":
        # replace '?' by '0' and recurse
        s[index] = '0'
        result += bit_strings(s, index + 1)

        # replace '?' by '1' and recurse
        s[index] = '1'
        result += bit_strings(s, index + 1)

        # NOTE: Need to backtrack as string
        # is passed by reference to the
        # function
        s[index] = '?'
    else:
        result += bit_strings(s, index + 1)

    return result


# Driver code
if __name__ == "__main__":
    x = "1??0?101"
    xl = list(x)  #don’t forget to convert to string
    print(bit_strings(xl, 0))
有更有效的方法可以做到这一点,但我只是根据问题和答案修改了您的代码

我已将
string
重命名为
s
,因为
string
有点混乱,会提醒其他人该类型或隐藏(内置)模块

至于单元测试:

import unittest
from wildcard import bit_strings


class TestWildCard(unittest.TestCase):
    def test_0_print(self):
        print("Start wildCard _print test: \n")
        # you only had one case here and it's a list now
        result = ['101', '111']
        # user assertEqual, not Equals
        # you were passing in a string, but your code assumed a list, so list() added
        self.assertEqual(bit_strings(list("1?1"), 0), result, "Results match")      
当使用PyCharm这样的环境时,它有助于调用文件
test.py
(即名称中包含
test
),从而帮助您更轻松地运行单元测试

注释中要求的两个备选解决方案(一个仍然是递归的,只是要简洁得多,另一个不是递归的,但在结果列表中可能有点浪费-只有两个快捷方式):

此解决方案不会在列表和字符串之间移动,因为不需要也不会操纵输入值。正如你所知道的,递归的有点慢,但我更喜欢它的可读性。输出:

['00010001', '00010011', '00110001', '00110011', '01010001', '01010011', '01110001', '01110011']
['00010001', '01010001', '00110001', '01110001', '00010011', '01010011', '00110011', '01110011']
13.073874
3.9742709000000005

请注意,您自己的解决方案使用相同的设置运行了大约8秒钟,因此我建议的“改进版”更简单,但不是更快,因此您可能更喜欢后一种解决方案。

顺便说一下,您将函数称为方法,但方法是在类上定义的函数。函数就是函数,我理解你的意思。你能不能建议一些更好的方法,一种更节省时间和空间的方法@格里斯马补充了一些建议。
['00010001', '00010011', '00110001', '00110011', '01010001', '01010011', '01110001', '01110011']
['00010001', '01010001', '00110001', '01110001', '00010011', '01010011', '00110011', '01110011']
13.073874
3.9742709000000005