用Python处理夹具数据的正确方法

时间:2019-04-30 08:27:50

标签: python fixtures

我的程序正在生成自然语言句子。 我想通过将随机种子设置为固定值,然后进行正确的测试:

  • 产生预期结果;
  • 将生成的句子与预期结果进行比较;
  • 如果它们不同,则询问用户生成的句子是否实际上是预期的结果,在这种情况下,更新预期的结果。

我已经在JS中遇到了这样的系统,所以很惊讶没有在Python中找到它。您如何处理这种情况?

2 个答案:

答案 0 :(得分:1)

Python中有许多测试框架,其中最受欢迎的两个是PyTestNose。 PyTest倾向于涵盖所有基础,但是Nose也有很多不错的功能。

fixtures用鼻子掩盖了文档的早期内容。他们给的例子看起来像

def setup_func():
    "set up test fixtures"

def teardown_func():
    "tear down test fixtures"

@with_setup(setup_func, teardown_func)
def test():
    "test ..."

在您的情况下,通过手动检查,您可能需要将该逻辑直接构建到测试本身中。

使用更具体的示例进行编辑

以鼻子的例子为基础,解决这个问题的一种方法是编写测试

from nose.tools import eq_

def setup_func():
    "set your random seed"

def teardown_func():
    "whatever teardown you need"

@with_setup(setup_func, teardown_func)
def test():
    expected = "the correct answer"
    actual = "make a prediction ..."
    _eq(expected, actual, "prediction did not match!")

在运行测试时,如果模型未产生正确的输出,则测试将失败,并显示“预测不匹配!”。在这种情况下,您应该转到测试文件并使用期望值更新expected。此过程不像在运行时键入过程那样动态,但是它具有易于版本控制的优点。

答案 1 :(得分:0)

One drawback of asking the user to replace the expected answer is that the automated test can not be run automatically. Therefore, test frameworks do not allow reading from input.

I really wanted this feature, so my implementation如下:

def compare_results(expected, results):
    if not os.path.isfile(expected):
        logging.warning("The expected file does not exist.")
    elif filecmp.cmp(expected, results):
        logging.debug("%s is accepted." % expected)
        return 
    content = Path(results).read_text()
    print("The test %s failed." % expected)
    print("Should I accept the results?")
    print(content)
    while True:
        try:
            keep = input("[y/n]")
        except OSError:
            assert False, "The test failed. Run directly this file to accept the result"
        if keep.lower() in ["y", "yes"]:
            Path(expected).write_text(content)
            break
        elif keep.lower() in ["n", "no"]:
            assert False, "The test failed and you did not accept the answer."
            break
        else:
            print("Please answer by yes or no.")


def test_example_iot_root(setup):
    ...
    compare_results(EXPECTED_DIR / "iot_root.test", tmp.name)


if __name__ == "__main__":
    from inspect import getmembers, isfunction
    def istest(o):
        return isfunction(o[1]) and  o[0].startswith("test")

    [random.seed(1) and o[1](setup) for o in getmembers(sys.modules[__name__]) \
            if istest(o)]

当我直接运行此文件时,它询问我是否应该替换预期的结果。当我从pytest运行时,input创建了一个OSError,可以退出循环。绝对不完美。