【发布时间】:2013-07-12 00:34:00
【问题描述】:
注意:我习惯于在 C# 代码中使用依赖注入, 但据我了解,像 Ruby 和 Python 这样的动态语言是 喜欢play-doh not LEGOs,因此不需要遵循使用 IoC 容器,尽管关于 IoC 模式是否仍然有用存在一些争论。在下面的代码中,我使用了 fudge 的
.patch功能,它提供了模拟/存根代码所需的接缝。然而,代码的组件因此是耦合的。我不确定我喜欢这个。 This SO answer 还解释了动态语言中的耦合比静态语言更松散,但确实引用了该问题中的另一个答案,即不需要 IoC 工具,但不需要模式。所以一个附带的问题是,“我应该为此使用 DI 吗?”
我正在使用以下 python 框架:
这是生成的生产代码:
def to_fasta(seq_records, file_name):
file_object = open(file_name, "w")
Bio.SeqIO.write(seq_records, file_object, "fasta")
file_object.close()
现在我对这段代码进行了 TDD,但我通过以下测试进行了测试(这并不彻底):
@istest
@fudge.patch('__builtin__.open', 'Bio.SeqIO.write')
def to_fasta_writes_file(fake_open, fake_SeqIO):
fake_open.is_a_stub()
fake_SeqIO.expects_call()
seq_records = build_expected_output_sequneces()
file_path = "doesn't matter"
to_fasta(seq_records, file_path)
这是更新后的测试以及明确的 cmets,以确保我遵循 Four-Phase Test 模式:
@istest
@fudge.patch('__builtin__.open', 'Bio.SeqIO')
def to_fasta_writes_file(fake_open, fake_SeqIO):
# Setup
seq_records = build_expected_output_sequneces()
file_path = "doesn't matter"
file_type = 'fasta'
file_object = fudge.Fake('file').expects('close')
(fake_open
.expects_call()
.with_args(file_path, 'w')
.returns(file_object))
(fake_SeqIO
.is_callable()
.expects("write")
.with_args(seq_records, file_object, file_type))
# Exercise
to_fasta(seq_records, file_path)
# Verify (not needed due to '.patch')
# Teardown
虽然第二个例子更彻底,但这个测试是不是有点矫枉过正? TDD python代码有更好的方法吗?基本上,我正在寻找有关我如何使用 TDD 执行此操作的反馈,并且欢迎任何替代方法来编写测试代码或生产代码。
【问题讨论】:
-
我没有看到测试该特定功能的优势。我认为测试一切只是浪费时间。像这样的简单功能不一定需要完整的测试;通常一个简单的doctest就足够了。顺便说一句:如果您的目标不是python with 可以避免测试对
close的调用,因为它们肯定会发生。 -
@Bakuriu,我已经更新了顶部的注释,而且,我是 python 新手,这就是我问这些问题的原因(我读到过关于
doctest在我写完这篇文章之后,但这是我第一次听说with。关于不测试“一切”如何使用 TDD 来实现 100% 的代码覆盖率?
标签: python mocking tdd stubbing